Skip to main content
Drupal API
User account menu
  • Log in

Breadcrumb

  1. Drupal Core 11.1.x
  2. File.php

function File::process

Starts the stack traversal and tells listeners when tokens are found.

Return value

void

2 calls to File::process()
LocalFile::process in vendor/squizlabs/php_codesniffer/src/Files/LocalFile.php
Processes the file.
LocalFile::process in vendor/squizlabs/php_codesniffer/src/Files/LocalFile.php
Processes the file.
1 method overrides File::process()
LocalFile::process in vendor/squizlabs/php_codesniffer/src/Files/LocalFile.php
Processes the file.

File

vendor/squizlabs/php_codesniffer/src/Files/File.php, line 320

Class

File

Namespace

PHP_CodeSniffer\Files

Code

public function process() {
    if ($this->ignored === true) {
        return;
    }
    $this->errors = [];
    $this->warnings = [];
    $this->errorCount = 0;
    $this->warningCount = 0;
    $this->fixableCount = 0;
    $this->parse();
    // Check if tokenizer errors cause this file to be ignored.
    if ($this->ignored === true) {
        return;
    }
    $this->fixer
        ->startFile($this);
    if (PHP_CODESNIFFER_VERBOSITY > 2) {
        echo "\t*** START TOKEN PROCESSING ***" . PHP_EOL;
    }
    $foundCode = false;
    $listenerIgnoreTo = [];
    $inTests = defined('PHP_CODESNIFFER_IN_TESTS');
    $checkAnnotations = $this->config->annotations;
    $annotationErrors = [];
    // Foreach of the listeners that have registered to listen for this
    // token, get them to process it.
    foreach ($this->tokens as $stackPtr => $token) {
        // Check for ignored lines.
        if ($checkAnnotations === true && ($token['code'] === T_COMMENT || $token['code'] === T_PHPCS_IGNORE_FILE || $token['code'] === T_PHPCS_SET || $token['code'] === T_DOC_COMMENT_STRING || $token['code'] === T_DOC_COMMENT_TAG || $inTests === true && $token['code'] === T_INLINE_HTML)) {
            $commentText = ltrim($this->tokens[$stackPtr]['content'], " \t/*#");
            $commentTextLower = strtolower($commentText);
            if (strpos($commentText, '@codingStandards') !== false) {
                if (strpos($commentText, '@codingStandardsIgnoreFile') !== false) {
                    // Ignoring the whole file, just a little late.
                    $this->errors = [];
                    $this->warnings = [];
                    $this->errorCount = 0;
                    $this->warningCount = 0;
                    $this->fixableCount = 0;
                    return;
                }
                else {
                    if (strpos($commentText, '@codingStandardsChangeSetting') !== false) {
                        $start = strpos($commentText, '@codingStandardsChangeSetting');
                        $comment = substr($commentText, $start + 30);
                        $parts = explode(' ', $comment);
                        if (count($parts) >= 2) {
                            $sniffParts = explode('.', $parts[0]);
                            if (count($sniffParts) >= 3) {
                                // If the sniff code is not known to us, it has not been registered in this run.
                                // But don't throw an error as it could be there for a different standard to use.
                                if (isset($this->ruleset->sniffCodes[$parts[0]]) === true) {
                                    $listenerCode = array_shift($parts);
                                    $propertyCode = array_shift($parts);
                                    $settings = [
                                        'value' => rtrim(implode(' ', $parts), " */\r\n"),
                                        'scope' => 'sniff',
                                    ];
                                    $listenerClass = $this->ruleset->sniffCodes[$listenerCode];
                                    $this->ruleset
                                        ->setSniffProperty($listenerClass, $propertyCode, $settings);
                                }
                            }
                        }
                    }
                }
                
                //end if
            }
            else {
                if (substr($commentTextLower, 0, 16) === 'phpcs:ignorefile' || substr($commentTextLower, 0, 17) === '@phpcs:ignorefile') {
                    // Ignoring the whole file, just a little late.
                    $this->errors = [];
                    $this->warnings = [];
                    $this->errorCount = 0;
                    $this->warningCount = 0;
                    $this->fixableCount = 0;
                    return;
                }
                else {
                    if (substr($commentTextLower, 0, 9) === 'phpcs:set' || substr($commentTextLower, 0, 10) === '@phpcs:set') {
                        if (isset($token['sniffCode']) === true) {
                            $listenerCode = $token['sniffCode'];
                            if (isset($this->ruleset->sniffCodes[$listenerCode]) === true) {
                                $propertyCode = $token['sniffProperty'];
                                $settings = [
                                    'value' => $token['sniffPropertyValue'],
                                    'scope' => 'sniff',
                                ];
                                $listenerClass = $this->ruleset->sniffCodes[$listenerCode];
                                try {
                                    $this->ruleset
                                        ->setSniffProperty($listenerClass, $propertyCode, $settings);
                                } catch (RuntimeException $e) {
                                    // Non-existant property being set via an inline annotation.
                                    // This is typically a PHPCS test case file, but we can't throw an error on the annotation
                                    // line as it would get ignored. We also don't want this error to block
                                    // the scan of the current file, so collect these and throw later.
                                    $annotationErrors[] = 'Line ' . $token['line'] . ': ' . str_replace('Ruleset invalid. ', '', $e->getMessage());
                                }
                            }
                        }
                    }
                }
            }
            
            //end if
        }
        
        //end if
        if (PHP_CODESNIFFER_VERBOSITY > 2) {
            $type = $token['type'];
            $content = Common::prepareForOutput($token['content']);
            echo "\t\tProcess token {$stackPtr}: {$type} => {$content}" . PHP_EOL;
        }
        if ($token['code'] !== T_INLINE_HTML) {
            $foundCode = true;
        }
        if (isset($this->ruleset->tokenListeners[$token['code']]) === false) {
            continue;
        }
        foreach ($this->ruleset->tokenListeners[$token['code']] as $listenerData) {
            if (isset($this->ignoredListeners[$listenerData['class']]) === true || isset($listenerIgnoreTo[$listenerData['class']]) === true && $listenerIgnoreTo[$listenerData['class']] > $stackPtr) {
                // This sniff is ignoring past this token, or the whole file.
                continue;
            }
            // Make sure this sniff supports the tokenizer
            // we are currently using.
            $class = $listenerData['class'];
            if (isset($listenerData['tokenizers'][$this->tokenizerType]) === false) {
                continue;
            }
            if (trim($this->path, '\'"') !== 'STDIN') {
                // If the file path matches one of our ignore patterns, skip it.
                // While there is support for a type of each pattern
                // (absolute or relative) we don't actually support it here.
                foreach ($listenerData['ignore'] as $pattern) {
                    // We assume a / directory separator, as do the exclude rules
                    // most developers write, so we need a special case for any system
                    // that is different.
                    if (DIRECTORY_SEPARATOR === '\\') {
                        $pattern = str_replace('/', '\\\\', $pattern);
                    }
                    $pattern = '`' . $pattern . '`i';
                    if (preg_match($pattern, $this->path) === 1) {
                        $this->ignoredListeners[$class] = true;
                        continue 2;
                    }
                }
                // If the file path does not match one of our include patterns, skip it.
                // While there is support for a type of each pattern
                // (absolute or relative) we don't actually support it here.
                if (empty($listenerData['include']) === false) {
                    $included = false;
                    foreach ($listenerData['include'] as $pattern) {
                        // We assume a / directory separator, as do the exclude rules
                        // most developers write, so we need a special case for any system
                        // that is different.
                        if (DIRECTORY_SEPARATOR === '\\') {
                            $pattern = str_replace('/', '\\\\', $pattern);
                        }
                        $pattern = '`' . $pattern . '`i';
                        if (preg_match($pattern, $this->path) === 1) {
                            $included = true;
                            break;
                        }
                    }
                    if ($included === false) {
                        $this->ignoredListeners[$class] = true;
                        continue;
                    }
                }
                
                //end if
            }
            
            //end if
            $this->activeListener = $class;
            if ($this->configCache['trackTime'] === true) {
                $startTime = microtime(true);
            }
            if (PHP_CODESNIFFER_VERBOSITY > 2) {
                echo "\t\t\tProcessing " . $this->activeListener . '... ';
            }
            $ignoreTo = $this->ruleset->sniffs[$class]
                ->process($this, $stackPtr);
            if ($ignoreTo !== null) {
                $listenerIgnoreTo[$this->activeListener] = $ignoreTo;
            }
            if ($this->configCache['trackTime'] === true) {
                $timeTaken = microtime(true) - $startTime;
                if (isset($this->listenerTimes[$this->activeListener]) === false) {
                    $this->listenerTimes[$this->activeListener] = 0;
                }
                $this->listenerTimes[$this->activeListener] += $timeTaken;
            }
            if (PHP_CODESNIFFER_VERBOSITY > 2) {
                $timeTaken = round($timeTaken, 4);
                echo "DONE in {$timeTaken} seconds" . PHP_EOL;
            }
            $this->activeListener = '';
        }
        
        //end foreach
    }
    
    //end foreach
    // If short open tags are off but the file being checked uses
    // short open tags, the whole content will be inline HTML
    // and nothing will be checked. So try and handle this case.
    // We don't show this error for STDIN because we can't be sure the content
    // actually came directly from the user. It could be something like
    // refs from a Git pre-push hook.
    if ($foundCode === false && $this->tokenizerType === 'PHP' && $this->path !== 'STDIN') {
        $shortTags = (bool) ini_get('short_open_tag');
        if ($shortTags === false) {
            $error = 'No PHP code was found in this file and short open tags are not allowed by this install of PHP. This file may be using short open tags but PHP does not allow them.';
            $this->addWarning($error, null, 'Internal.NoCodeFound');
        }
    }
    if ($annotationErrors !== []) {
        $error = 'Encountered invalid inline phpcs:set annotations. Found:' . PHP_EOL;
        $error .= implode(PHP_EOL, $annotationErrors);
        $this->addWarning($error, null, 'Internal.PropertyDoesNotExist');
    }
    if (PHP_CODESNIFFER_VERBOSITY > 2) {
        echo "\t*** END TOKEN PROCESSING ***" . PHP_EOL;
        echo "\t*** START SNIFF PROCESSING REPORT ***" . PHP_EOL;
        arsort($this->listenerTimes, SORT_NUMERIC);
        foreach ($this->listenerTimes as $listener => $timeTaken) {
            echo "\t{$listener}: " . round($timeTaken, 4) . ' secs' . PHP_EOL;
        }
        echo "\t*** END SNIFF PROCESSING REPORT ***" . PHP_EOL;
    }
    $this->fixedCount += $this->fixer
        ->getFixCount();
}

API Navigation

  • Drupal Core 11.1.x
  • Topics
  • Classes
  • Functions
  • Constants
  • Globals
  • Files
  • Namespaces
  • Deprecated
  • Services
RSS feed
Powered by Drupal