Esempio n. 1
0
 /**
  * Processes the tokens that this sniff is interested in.
  *
  * @param PHP_CodeSniffer_File $phpcsFile The file where the token was found.
  * @param int                  $stackPtr  The position in the stack where
  *                                        the token was found.
  *
  * @return void
  * @throws PHP_CodeSniffer_Exception If jslint.js could not be run
  */
 public function process(File $phpcsFile, $stackPtr)
 {
     $rhinoPath = Config::getExecutablePath('jslint');
     $jslintPath = Config::getExecutablePath('jslint');
     if ($rhinoPath === null || $jslintPath === null) {
         return;
     }
     $fileName = $phpcsFile->getFilename();
     $cmd = "{$rhinoPath} \"{$jslintPath}\" \"{$fileName}\"";
     $msg = exec($cmd, $output, $retval);
     if (is_array($output) === true) {
         foreach ($output as $finding) {
             $matches = array();
             $numMatches = preg_match('/Lint at line ([0-9]+).*:(.*)$/', $finding, $matches);
             if ($numMatches === 0) {
                 continue;
             }
             $line = (int) $matches[1];
             $message = 'jslint says: ' . trim($matches[2]);
             $phpcsFile->addWarningOnLine($message, $line, 'ExternalTool');
         }
     }
     // Ignore the rest of the file.
     return $phpcsFile->numTokens + 1;
 }
Esempio n. 2
0
 /**
  * Processes this test, when one of its tokens is encountered.
  *
  * @param PHP_CodeSniffer_File $phpcsFile The file being scanned.
  * @param int                  $stackPtr  The position of the current token in
  *                                        the stack passed in $tokens.
  *
  * @return void
  */
 public function process(File $phpcsFile, $stackPtr)
 {
     if ($this->phpPath === null) {
         $this->phpPath = Config::getExecutablePath('php');
         if ($this->phpPath === null) {
             // PHP_BINARY is available in PHP 5.4+.
             if (defined('PHP_BINARY') === true) {
                 $this->phpPath = PHP_BINARY;
             } else {
                 return;
             }
         }
     }
     $fileName = $phpcsFile->getFilename();
     $cmd = $this->phpPath . " -l \"{$fileName}\" 2>&1";
     $output = shell_exec($cmd);
     $matches = array();
     if (preg_match('/^.*error:(.*) in .* on line ([0-9]+)/', trim($output), $matches) === 1) {
         $error = trim($matches[1]);
         $line = (int) $matches[2];
         $phpcsFile->addErrorOnLine("PHP syntax error: {$error}", $line, 'PHPSyntax');
     }
     // Ignore the rest of the file.
     return $phpcsFile->numTokens + 1;
 }
Esempio n. 3
0
 /**
  * Processes this sniff, when one of its tokens is encountered.
  *
  * @param PHP_CodeSniffer_File $phpcsFile The file being scanned.
  * @param int                  $stackPtr  The position of the current token in
  *                                        the stack passed in $tokens.
  *
  * @return void
  */
 public function process(File $phpcsFile, $stackPtr)
 {
     $fileName = $phpcsFile->getFilename();
     $matches = array();
     if (preg_match('|/systems/(.*)/([^/]+)?actions.inc$|i', $fileName, $matches) === 0) {
         // Not an actions file.
         return;
     }
     $ownClass = $matches[2];
     $tokens = $phpcsFile->getTokens();
     $typeName = $phpcsFile->findNext(T_CONSTANT_ENCAPSED_STRING, $stackPtr + 2, null, false, true);
     $typeName = trim($tokens[$typeName]['content'], " '");
     switch (strtolower($tokens[$stackPtr + 1]['content'])) {
         case 'includesystem':
             $included = strtolower($typeName);
             break;
         case 'includeasset':
             $included = strtolower($typeName) . 'assettype';
             break;
         case 'includewidget':
             $included = strtolower($typeName) . 'widgettype';
             break;
         default:
             return;
     }
     if ($included === strtolower($ownClass)) {
         $error = "You do not need to include \"%s\" from within the system's own actions file";
         $data = array($ownClass);
         $phpcsFile->addError($error, $stackPtr, 'NotRequired', $data);
     }
 }
Esempio n. 4
0
 /**
  * Processes the tokens that this sniff is interested in.
  *
  * @param PHP_CodeSniffer_File $phpcsFile The file where the token was found.
  * @param int                  $stackPtr  The position in the stack where
  *                                        the token was found.
  *
  * @return void
  */
 public function process(File $phpcsFile, $stackPtr)
 {
     $jslPath = Config::getExecutablePath('jsl');
     if (is_null($jslPath) === true) {
         return;
     }
     $fileName = $phpcsFile->getFilename();
     $cmd = '"' . $jslPath . '" -nologo -nofilelisting -nocontext -nosummary -output-format __LINE__:__ERROR__ -process "' . $fileName . '"';
     $msg = exec($cmd, $output, $retval);
     // Variable $exitCode is the last line of $output if no error occurs, on
     // error it is numeric. Try to handle various error conditions and
     // provide useful error reporting.
     if ($retval === 2 || $retval === 4) {
         if (is_array($output) === true) {
             $msg = join('\\n', $output);
         }
         throw new RuntimeException("Failed invoking JavaScript Lint, retval was [{$retval}], output was [{$msg}]");
     }
     if (is_array($output) === true) {
         foreach ($output as $finding) {
             $split = strpos($finding, ':');
             $line = substr($finding, 0, $split);
             $message = substr($finding, $split + 1);
             $phpcsFile->addWarningOnLine(trim($message), $line, 'ExternalTool');
         }
     }
     // Ignore the rest of the file.
     return $phpcsFile->numTokens + 1;
 }
Esempio n. 5
0
 /**
  * Processes the tokens that this sniff is interested in.
  *
  * @param PHP_CodeSniffer_File $phpcsFile The file where the token was found.
  * @param int                  $stackPtr  The position in the stack where
  *                                        the token was found.
  *
  * @return void
  */
 public function process(File $phpcsFile, $stackPtr)
 {
     $csslintPath = Config::getExecutablePath('csslint');
     if ($csslintPath === null) {
         return;
     }
     $fileName = $phpcsFile->getFilename();
     $cmd = $csslintPath . ' ' . escapeshellarg($fileName);
     exec($cmd, $output, $retval);
     if (is_array($output) === false) {
         return;
     }
     $count = count($output);
     for ($i = 0; $i < $count; $i++) {
         $matches = array();
         $numMatches = preg_match('/(error|warning) at line (\\d+)/', $output[$i], $matches);
         if ($numMatches === 0) {
             continue;
         }
         $line = (int) $matches[2];
         $message = 'csslint says: ' . $output[$i + 1];
         // First line is message with error line and error code.
         // Second is error message.
         // Third is wrong line in file.
         // Fourth is empty line.
         $i += 4;
         $phpcsFile->addWarningOnLine($message, $line, 'ExternalTool');
     }
     //end for
     // Ignore the rest of the file.
     return $phpcsFile->numTokens + 1;
 }
Esempio n. 6
0
 /**
  * Processes this test, when one of its tokens is encountered.
  *
  * @param PHP_CodeSniffer_File $phpcsFile The file being scanned.
  * @param int                  $stackPtr  The position of the current token in
  *                                        the stack passed in $tokens.
  *
  * @return void
  */
 public function process(File $phpcsFile, $stackPtr)
 {
     $fullPath = basename($phpcsFile->getFilename());
     $fileName = substr($fullPath, 0, strrpos($fullPath, '.'));
     if ($fileName === '') {
         // No filename probably means STDIN, so we can't do this check.
         return;
     }
     $tokens = $phpcsFile->getTokens();
     $decName = $phpcsFile->findNext(T_STRING, $stackPtr);
     if ($tokens[$decName]['content'] !== $fileName) {
         $error = '%s name doesn\'t match filename; expected "%s %s"';
         $data = array(ucfirst($tokens[$stackPtr]['content']), $tokens[$stackPtr]['content'], $fileName);
         $phpcsFile->addError($error, $stackPtr, 'NoMatch', $data);
     }
 }
Esempio n. 7
0
 /**
  * Generates a text diff of the original file and the new content.
  *
  * @param string  $filePath Optional file path to diff the file against.
  *                          If not specified, the original version of the
  *                          file will be used.
  * @param boolean $colors   Print colored output or not.
  *
  * @return string
  */
 public function generateDiff($filePath = null, $colors = true)
 {
     if ($filePath === null) {
         $filePath = $this->currentFile->getFilename();
     }
     $cwd = getcwd() . DIRECTORY_SEPARATOR;
     $filename = str_replace($cwd, '', $filePath);
     $contents = $this->getContents();
     $tempName = tempnam(sys_get_temp_dir(), 'phpcs-fixer');
     $fixedFile = fopen($tempName, 'w');
     fwrite($fixedFile, $contents);
     // We must use something like shell_exec() because whitespace at the end
     // of lines is critical to diff files.
     $cmd = "diff -u -L\"{$filename}\" -LPHP_CodeSniffer \"{$filename}\" \"{$tempName}\"";
     $diff = shell_exec($cmd);
     fclose($fixedFile);
     if (is_file($tempName) === true) {
         unlink($tempName);
     }
     if ($colors === false) {
         return $diff;
     }
     $diffLines = explode(PHP_EOL, $diff);
     if (count($diffLines) === 1) {
         // Seems to be required for cygwin.
         $diffLines = explode("\n", $diff);
     }
     $diff = array();
     foreach ($diffLines as $line) {
         if (isset($line[0]) === true) {
             switch ($line[0]) {
                 case '-':
                     $diff[] = "{$line}";
                     break;
                 case '+':
                     $diff[] = "{$line}";
                     break;
                 default:
                     $diff[] = $line;
             }
         }
     }
     $diff = implode(PHP_EOL, $diff);
     return $diff;
 }
 /**
  * Processes the tokens that this sniff is interested in.
  *
  * @param PHP_CodeSniffer_File $phpcsFile The file where the token was found.
  * @param int                  $stackPtr  The position in the stack where
  *                                        the token was found.
  *
  * @return void
  */
 public function process(File $phpcsFile, $stackPtr)
 {
     // Ignore files with browser-specific suffixes.
     $filename = $phpcsFile->getFilename();
     $breakChar = strrpos($filename, '_');
     if ($breakChar !== false && substr($filename, -4) === '.css') {
         $specific = substr($filename, $breakChar + 1, -4);
         if (isset($this->specificStylesheets[$specific]) === true) {
             return;
         }
     }
     $tokens = $phpcsFile->getTokens();
     $content = $tokens[$stackPtr]['content'];
     if ($content[0] === '-') {
         $error = 'Browser-specific styles are not allowed';
         $phpcsFile->addError($error, $stackPtr, 'ForbiddenStyle');
     }
 }
Esempio n. 9
0
 /**
  * Processes this sniff, when one of its tokens is encountered.
  *
  * @param PHP_CodeSniffer_File $phpcsFile The file being scanned.
  * @param int                  $stackPtr  The position of the current token in
  *                                        the stack passed in $tokens.
  *
  * @return int
  */
 public function process(File $phpcsFile, $stackPtr)
 {
     $filename = $phpcsFile->getFilename();
     if ($filename === 'STDIN') {
         return;
     }
     $filename = basename($filename);
     $lowercaseFilename = strtolower($filename);
     if ($filename !== $lowercaseFilename) {
         $data = array($filename, $lowercaseFilename);
         $error = 'Filename "%s" doesn\'t match the expected filename "%s"';
         $phpcsFile->addError($error, $stackPtr, 'NotFound', $data);
         $phpcsFile->recordMetric($stackPtr, 'Lowercase filename', 'no');
     } else {
         $phpcsFile->recordMetric($stackPtr, 'Lowercase filename', 'yes');
     }
     // Ignore the rest of the file.
     return $phpcsFile->numTokens + 1;
 }
Esempio n. 10
0
 /**
  * Processes the tokens that this sniff is interested in.
  *
  * @param PHP_CodeSniffer_File $phpcsFile The file where the token was found.
  * @param int                  $stackPtr  The position in the stack where
  *                                        the token was found.
  *
  * @return int
  */
 public function process(File $phpcsFile, $stackPtr)
 {
     $analyzerPath = Config::getExecutablePath('zend_ca');
     if (is_null($analyzerPath) === true) {
         return;
     }
     $fileName = $phpcsFile->getFilename();
     // In the command, 2>&1 is important because the code analyzer sends its
     // findings to stderr. $output normally contains only stdout, so using 2>&1
     // will pipe even stderr to stdout.
     $cmd = $analyzerPath . ' ' . $fileName . ' 2>&1';
     // There is the possibility to pass "--ide" as an option to the analyzer.
     // This would result in an output format which would be easier to parse.
     // The problem here is that no cleartext error messages are returnwd; only
     // error-code-labels. So for a start we go for cleartext output.
     $exitCode = exec($cmd, $output, $retval);
     // Variable $exitCode is the last line of $output if no error occures, on
     // error it is numeric. Try to handle various error conditions and
     // provide useful error reporting.
     if (is_numeric($exitCode) === true && $exitCode > 0) {
         if (is_array($output) === true) {
             $msg = join('\\n', $output);
         }
         throw new RuntimeException("Failed invoking ZendCodeAnalyzer, exitcode was [{$exitCode}], retval was [{$retval}], output was [{$msg}]");
     }
     if (is_array($output) === true) {
         foreach ($output as $finding) {
             // The first two lines of analyzer output contain
             // something like this:
             // > Zend Code Analyzer 1.2.2
             // > Analyzing <filename>...
             // So skip these...
             $res = preg_match("/^.+\\(line ([0-9]+)\\):(.+)\$/", $finding, $regs);
             if (empty($regs) === true || $res === false) {
                 continue;
             }
             $phpcsFile->addWarningOnLine(trim($regs[2]), $regs[1], 'ExternalTool');
         }
     }
     // Ignore the rest of the file.
     return $phpcsFile->numTokens + 1;
 }
Esempio n. 11
0
 /**
  * Processes this test, when one of its tokens is encountered.
  *
  * @param PHP_CodeSniffer_File $phpcsFile The file being scanned.
  * @param int                  $stackPtr  The position of the current token
  *                                        in the stack passed in $tokens.
  *
  * @return void
  */
 public function process(File $phpcsFile, $stackPtr)
 {
     $tokens = $phpcsFile->getTokens();
     $namespace = '';
     $findTokens = array(T_CLASS, T_INTERFACE, T_NAMESPACE, T_CLOSE_TAG);
     $stackPtr = $phpcsFile->findNext($findTokens, $stackPtr + 1);
     while ($stackPtr !== false) {
         if ($tokens[$stackPtr]['code'] === T_CLOSE_TAG) {
             // We can stop here. The sniff will continue from the next open
             // tag when PHPCS reaches that token, if there is one.
             return;
         }
         // Keep track of what namespace we are in.
         if ($tokens[$stackPtr]['code'] === T_NAMESPACE) {
             $nsEnd = $phpcsFile->findNext(array(T_NS_SEPARATOR, T_STRING, T_WHITESPACE), $stackPtr + 1, null, true);
             $namespace = trim($phpcsFile->getTokensAsString($stackPtr + 1, $nsEnd - $stackPtr - 1));
             $stackPtr = $nsEnd;
         } else {
             $nameToken = $phpcsFile->findNext(T_STRING, $stackPtr);
             $name = $tokens[$nameToken]['content'];
             if ($namespace !== '') {
                 $name = $namespace . '\\' . $name;
             }
             $compareName = strtolower($name);
             if (isset($this->foundClasses[$compareName]) === true) {
                 $type = strtolower($tokens[$stackPtr]['content']);
                 $file = $this->foundClasses[$compareName]['file'];
                 $line = $this->foundClasses[$compareName]['line'];
                 $error = 'Duplicate %s name "%s" found; first defined in %s on line %s';
                 $data = array($type, $name, $file, $line);
                 $phpcsFile->addWarning($error, $stackPtr, 'Found', $data);
             } else {
                 $this->foundClasses[$compareName] = array('file' => $phpcsFile->getFilename(), 'line' => $tokens[$stackPtr]['line']);
             }
         }
         //end if
         $stackPtr = $phpcsFile->findNext($findTokens, $stackPtr + 1);
     }
     //end while
 }
Esempio n. 12
0
 /**
  * Processes the tokens that this sniff is interested in.
  *
  * @param PHP_CodeSniffer_File $phpcsFile The file where the token was found.
  * @param int                  $stackPtr  The position in the stack where
  *                                        the token was found.
  *
  * @return void
  * @throws PHP_CodeSniffer_Exception If jslint.js could not be run
  */
 public function process(File $phpcsFile, $stackPtr)
 {
     $lintPath = Config::getExecutablePath('gjslint');
     if ($lintPath === null) {
         return;
     }
     $fileName = $phpcsFile->getFilename();
     $cmd = "{$lintPath} --nosummary --notime --unix_mode \"{$fileName}\"";
     $msg = exec($cmd, $output, $retval);
     if (is_array($output) === false) {
         return;
     }
     foreach ($output as $finding) {
         $matches = array();
         $numMatches = preg_match('/^(.*):([0-9]+):\\(.*?([0-9]+)\\)(.*)$/', $finding, $matches);
         if ($numMatches === 0) {
             continue;
         }
         // Skip error codes we are ignoring.
         $code = $matches[3];
         if (in_array($code, $this->ignoreCodes) === true) {
             continue;
         }
         $line = (int) $matches[2];
         $error = trim($matches[4]);
         $message = 'gjslint says: (%s) %s';
         $data = array($code, $error);
         if (in_array($code, $this->errorCodes) === true) {
             $phpcsFile->addErrorOnLine($message, $line, 'ExternalToolError', $data);
         } else {
             $phpcsFile->addWarningOnLine($message, $line, 'ExternalTool', $data);
         }
     }
     //end foreach
     // Ignore the rest of the file.
     return $phpcsFile->numTokens + 1;
 }
Esempio n. 13
0
 /**
  * Processes a token within the scope that this test is listening to.
  *
  * @param PHP_CodeSniffer_File $phpcsFile The file where the token was found.
  * @param int                  $stackPtr  The position in the stack where
  *                                        this token was found.
  *
  * @return void
  */
 protected function processTokenOutsideScope(File $phpcsFile, $stackPtr)
 {
     $tokens = $phpcsFile->getTokens();
     if ($tokens[$stackPtr]['code'] === T_EXTENDS) {
         // Find the class name.
         $classNameToken = $phpcsFile->findNext(T_STRING, $stackPtr + 1);
         $className = $tokens[$classNameToken]['content'];
     } else {
         // Determine the name of the class that the static function
         // is being called on. But don't process class names represented by
         // variables as this can be an inexact science.
         $classNameToken = $phpcsFile->findPrevious(T_WHITESPACE, $stackPtr - 1, null, true);
         if ($tokens[$classNameToken]['code'] === T_VARIABLE) {
             return;
         }
         $className = $tokens[$classNameToken]['content'];
     }
     // Some systems are always available.
     if (isset($this->ignore[strtolower($className)]) === true) {
         return;
     }
     $includedClasses = array();
     $fileName = strtolower($phpcsFile->getFilename());
     $matches = array();
     if (preg_match('|/systems/([^/]+)/([^/]+)?actions.inc$|', $fileName, $matches) !== 0) {
         // This is an actions file, which means we don't
         // have to include the system in which it exists
         // We know the system from the path.
         $includedClasses[$matches[1]] = true;
     }
     // Go searching for includeSystem, includeAsset or require/include
     // calls outside our scope.
     for ($i = 0; $i < $stackPtr; $i++) {
         // Skip classes and functions as will we never get
         // into their scopes when including this file, although
         // we have a chance of getting into IF's, WHILE's etc.
         if (($tokens[$i]['code'] === T_CLASS || $tokens[$i]['code'] === T_INTERFACE || $tokens[$i]['code'] === T_FUNCTION) && isset($tokens[$i]['scope_closer']) === true) {
             $i = $tokens[$i]['scope_closer'];
             continue;
         }
         $name = $this->getIncludedClassFromToken($phpcsFile, $tokens, $i);
         if ($name !== false) {
             $includedClasses[$name] = true;
             // Special case for Widgets cause they are, well, special.
         } else {
             if (strtolower($tokens[$i]['content']) === 'includewidget') {
                 $typeName = $phpcsFile->findNext(T_CONSTANT_ENCAPSED_STRING, $i + 1);
                 $typeName = trim($tokens[$typeName]['content'], " '");
                 $includedClasses[strtolower($typeName) . 'widgettype'] = true;
             }
         }
     }
     //end for
     if (isset($includedClasses[strtolower($className)]) === false) {
         if ($tokens[$stackPtr]['code'] === T_EXTENDS) {
             $error = 'Class extends non-included class or system "%s"; include system with Channels::includeSystem() or include class with require_once';
             $data = array($className);
             $phpcsFile->addError($error, $stackPtr, 'NotIncludedExtends', $data);
         } else {
             $error = 'Static method called on non-included class or system "%s"; include system with Channels::includeSystem() or include class with require_once';
             $data = array($className);
             $phpcsFile->addError($error, $stackPtr, 'NotIncludedCall', $data);
         }
     }
 }
Esempio n. 14
0
 /**
  * Generate summary information to be used during report generation.
  *
  * @param \PHP_CodeSniffer\Files\File $phpcsFile The file that has been processed.
  *
  * @return array
  */
 public function prepareFileReport(File $phpcsFile)
 {
     $report = array('filename' => Common::stripBasepath($phpcsFile->getFilename(), $this->config->basepath), 'errors' => $phpcsFile->getErrorCount(), 'warnings' => $phpcsFile->getWarningCount(), 'fixable' => $phpcsFile->getFixableCount(), 'messages' => array());
     if ($report['errors'] === 0 && $report['warnings'] === 0) {
         // Prefect score!
         return $report;
     }
     if ($this->config->recordErrors === false) {
         $message = 'Errors are not being recorded but this report requires error messages. ';
         $message .= 'This report will not show the correct information.';
         $report['messages'][1][1] = array(array('message' => $message, 'source' => 'Internal.RecordErrors', 'severity' => 5, 'fixable' => false, 'type' => 'ERROR'));
         return $report;
     }
     $errors = array();
     // Merge errors and warnings.
     foreach ($phpcsFile->getErrors() as $line => $lineErrors) {
         foreach ($lineErrors as $column => $colErrors) {
             $newErrors = array();
             foreach ($colErrors as $data) {
                 $newErrors[] = array('message' => $data['message'], 'source' => $data['source'], 'severity' => $data['severity'], 'fixable' => $data['fixable'], 'type' => 'ERROR');
             }
             $errors[$line][$column] = $newErrors;
         }
         ksort($errors[$line]);
     }
     //end foreach
     foreach ($phpcsFile->getWarnings() as $line => $lineWarnings) {
         foreach ($lineWarnings as $column => $colWarnings) {
             $newWarnings = array();
             foreach ($colWarnings as $data) {
                 $newWarnings[] = array('message' => $data['message'], 'source' => $data['source'], 'severity' => $data['severity'], 'fixable' => $data['fixable'], 'type' => 'WARNING');
             }
             if (isset($errors[$line]) === false) {
                 $errors[$line] = array();
             }
             if (isset($errors[$line][$column]) === true) {
                 $errors[$line][$column] = array_merge($newWarnings, $errors[$line][$column]);
             } else {
                 $errors[$line][$column] = $newWarnings;
             }
         }
         //end foreach
         ksort($errors[$line]);
     }
     //end foreach
     ksort($errors);
     $report['messages'] = $errors;
     return $report;
 }
Esempio n. 15
0
 /**
  * Processes the test.
  *
  * @param PHP_CodeSniffer_File $phpcsFile The PHP_CodeSniffer file where the
  *                                        token occurred.
  * @param int                  $stackPtr  The position in the tokens stack
  *                                        where the listening token type was
  *                                        found.
  *
  * @return void
  * @see    register()
  */
 public final function process(File $phpcsFile, $stackPtr)
 {
     $file = $phpcsFile->getFilename();
     if ($this->currFile !== $file) {
         // We have changed files, so clean up.
         $this->errorPos = array();
         $this->currFile = $file;
     }
     $tokens = $phpcsFile->getTokens();
     if (in_array($tokens[$stackPtr]['code'], $this->supplementaryTokens) === true) {
         $this->processSupplementary($phpcsFile, $stackPtr);
     }
     $type = $tokens[$stackPtr]['code'];
     // If the type is not set, then it must have been a token registered
     // with registerSupplementary().
     if (isset($this->parsedPatterns[$type]) === false) {
         return;
     }
     $allErrors = array();
     // Loop over each pattern that is listening to the current token type
     // that we are processing.
     foreach ($this->parsedPatterns[$type] as $patternInfo) {
         // If processPattern returns false, then the pattern that we are
         // checking the code with must not be designed to check that code.
         $errors = $this->processPattern($patternInfo, $phpcsFile, $stackPtr);
         if ($errors === false) {
             // The pattern didn't match.
             continue;
         } else {
             if (empty($errors) === true) {
                 // The pattern matched, but there were no errors.
                 break;
             }
         }
         foreach ($errors as $stackPtr => $error) {
             if (isset($this->errorPos[$stackPtr]) === false) {
                 $this->errorPos[$stackPtr] = true;
                 $allErrors[$stackPtr] = $error;
             }
         }
     }
     foreach ($allErrors as $stackPtr => $error) {
         $phpcsFile->addError($error, $stackPtr, 'Found');
     }
 }