/**
  * 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();
     $token = $tokens[$stackPtr];
     // Skip for-loop without body.
     if (isset($token['parenthesis_opener']) === false) {
         return;
     }
     $next = ++$token['parenthesis_opener'];
     $end = --$token['parenthesis_closer'];
     $goodCondition = false;
     for (; $next <= $end; ++$next) {
         $code = $tokens[$next]['code'];
         if (isset(Tokens::$emptyTokens[$code]) === true) {
             continue;
         } else {
             if ($code !== T_TRUE && $code !== T_FALSE) {
                 $goodCondition = true;
             }
         }
     }
     if ($goodCondition === false) {
         $error = 'Avoid IF statements that are always true or false';
         $phpcsFile->addWarning($error, $stackPtr, 'Found');
     }
 }
Exemple #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)
 {
     $tokens = $phpcsFile->getTokens();
     // Ignore abstract methods.
     if (isset($tokens[$stackPtr]['scope_opener']) === false) {
         return;
     }
     // Detect start and end of this function definition.
     $start = $tokens[$stackPtr]['scope_opener'];
     $end = $tokens[$stackPtr]['scope_closer'];
     $nestingLevel = 0;
     // Find the maximum nesting level of any token in the function.
     for ($i = $start + 1; $i < $end; $i++) {
         $level = $tokens[$i]['level'];
         if ($nestingLevel < $level) {
             $nestingLevel = $level;
         }
     }
     // We subtract the nesting level of the function itself.
     $nestingLevel = $nestingLevel - $tokens[$stackPtr]['level'] - 1;
     if ($nestingLevel > $this->absoluteNestingLevel) {
         $error = 'Function\'s nesting level (%s) exceeds allowed maximum of %s';
         $data = array($nestingLevel, $this->absoluteNestingLevel);
         $phpcsFile->addError($error, $stackPtr, 'MaxExceeded', $data);
     } else {
         if ($nestingLevel > $this->nestingLevel) {
             $warning = 'Function\'s nesting level (%s) exceeds %s; consider refactoring the function';
             $data = array($nestingLevel, $this->nestingLevel);
             $phpcsFile->addWarning($warning, $stackPtr, 'TooHigh', $data);
         }
     }
 }
 /**
  * Processes the function tokens within the class.
  *
  * @param PHP_CodeSniffer_File $phpcsFile The file where this token was found.
  * @param int                  $stackPtr  The position where the token was found.
  *
  * @return void
  */
 protected function processMemberVar(File $phpcsFile, $stackPtr)
 {
     $tokens = $phpcsFile->getTokens();
     if ($tokens[$stackPtr]['content'][1] === '_') {
         $error = 'Property name "%s" should not be prefixed with an underscore to indicate visibility';
         $data = array($tokens[$stackPtr]['content']);
         $phpcsFile->addWarning($error, $stackPtr, 'Underscore', $data);
     }
     // Detect multiple properties defined at the same time. Throw an error
     // for this, but also only process the first property in the list so we don't
     // repeat errors.
     $find = Tokens::$scopeModifiers;
     $find = array_merge($find, array(T_VARIABLE, T_VAR, T_SEMICOLON));
     $prev = $phpcsFile->findPrevious($find, $stackPtr - 1);
     if ($tokens[$prev]['code'] === T_VARIABLE) {
         return;
     }
     if ($tokens[$prev]['code'] === T_VAR) {
         $error = 'The var keyword must not be used to declare a property';
         $phpcsFile->addError($error, $stackPtr, 'VarUsed');
     }
     $next = $phpcsFile->findNext(array(T_VARIABLE, T_SEMICOLON), $stackPtr + 1);
     if ($tokens[$next]['code'] === T_VARIABLE) {
         $error = 'There must not be more than one property declared per statement';
         $phpcsFile->addError($error, $stackPtr, 'Multiple');
     }
     $modifier = $phpcsFile->findPrevious(Tokens::$scopeModifiers, $stackPtr);
     if ($modifier === false || $tokens[$modifier]['line'] !== $tokens[$stackPtr]['line']) {
         $error = 'Visibility must be declared on property "%s"';
         $data = array($tokens[$stackPtr]['content']);
         $phpcsFile->addError($error, $stackPtr, 'ScopeMissing', $data);
     }
 }
Exemple #4
0
 /**
  * Processes this test, when one of its tokens is encountered.
  *
  * @param PHP_CodeSniffer_File $phpcsFile The current file being processed.
  * @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();
     if (isset($tokens[$stackPtr]['scope_opener']) === false) {
         $error = 'Possible parse error: %s missing opening or closing brace';
         $data = array($tokens[$stackPtr]['content']);
         $phpcsFile->addWarning($error, $stackPtr, 'MissingBrace', $data);
         return;
     }
     // Determine the name of the class or interface. Note that we cannot
     // simply look for the first T_STRING because a class name
     // starting with the number will be multiple tokens.
     $opener = $tokens[$stackPtr]['scope_opener'];
     $nameStart = $phpcsFile->findNext(T_WHITESPACE, $stackPtr + 1, $opener, true);
     $nameEnd = $phpcsFile->findNext(T_WHITESPACE, $nameStart, $opener);
     if ($nameEnd === false) {
         $name = $tokens[$nameStart]['content'];
     } else {
         $name = trim($phpcsFile->getTokensAsString($nameStart, $nameEnd - $nameStart));
     }
     // Check for camel caps format.
     $valid = Common::isCamelCaps($name, true, true, false);
     if ($valid === false) {
         $type = ucfirst($tokens[$stackPtr]['content']);
         $error = '%s name "%s" is not in camel caps format';
         $data = array($type, $name);
         $phpcsFile->addError($error, $stackPtr, 'NotCamelCaps', $data);
         $phpcsFile->recordMetric($stackPtr, 'CamelCase class name', 'no');
     } else {
         $phpcsFile->recordMetric($stackPtr, 'CamelCase class name', 'yes');
     }
 }
 /**
  * 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)
 {
     $this->currentFile = $phpcsFile;
     $tokens = $phpcsFile->getTokens();
     // Ignore abstract methods.
     if (isset($tokens[$stackPtr]['scope_opener']) === false) {
         return;
     }
     // Detect start and end of this function definition.
     $start = $tokens[$stackPtr]['scope_opener'];
     $end = $tokens[$stackPtr]['scope_closer'];
     // Predicate nodes for PHP.
     $find = array(T_CASE => true, T_DEFAULT => true, T_CATCH => true, T_IF => true, T_FOR => true, T_FOREACH => true, T_WHILE => true, T_DO => true, T_ELSEIF => true);
     $complexity = 1;
     // Iterate from start to end and count predicate nodes.
     for ($i = $start + 1; $i < $end; $i++) {
         if (isset($find[$tokens[$i]['code']]) === true) {
             $complexity++;
         }
     }
     if ($complexity > $this->absoluteComplexity) {
         $error = 'Function\'s cyclomatic complexity (%s) exceeds allowed maximum of %s';
         $data = array($complexity, $this->absoluteComplexity);
         $phpcsFile->addError($error, $stackPtr, 'MaxExceeded', $data);
     } else {
         if ($complexity > $this->complexity) {
             $warning = 'Function\'s cyclomatic complexity (%s) exceeds %s; consider refactoring the function';
             $data = array($complexity, $this->complexity);
             $phpcsFile->addWarning($warning, $stackPtr, 'TooHigh', $data);
         }
     }
 }
 /**
  * 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();
     $token = $tokens[$stackPtr];
     // Skip invalid statement.
     if (isset($token['parenthesis_opener']) === false) {
         return;
     }
     $next = ++$token['parenthesis_opener'];
     $end = --$token['parenthesis_closer'];
     $parts = array(0, 0, 0);
     $index = 0;
     for (; $next <= $end; ++$next) {
         $code = $tokens[$next]['code'];
         if ($code === T_SEMICOLON) {
             ++$index;
         } else {
             if (isset(Tokens::$emptyTokens[$code]) === false) {
                 ++$parts[$index];
             }
         }
     }
     if ($parts[0] === 0 && $parts[2] === 0 && $parts[1] > 0) {
         $error = 'This FOR loop can be simplified to a WHILE loop';
         $phpcsFile->addWarning($error, $stackPtr, 'CanSimplify');
     }
 }
Exemple #7
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();
     $find = Tokens::$methodPrefixes;
     $find[] = T_WHITESPACE;
     $commentEnd = $phpcsFile->findPrevious($find, $stackPtr - 1, null, true);
     if ($tokens[$commentEnd]['code'] !== T_DOC_COMMENT_CLOSE_TAG && $tokens[$commentEnd]['code'] !== T_COMMENT) {
         $phpcsFile->addError('Missing class doc comment', $stackPtr, 'Missing');
         $phpcsFile->recordMetric($stackPtr, 'Class has doc comment', 'no');
         return;
     }
     $phpcsFile->recordMetric($stackPtr, 'Class has doc comment', 'yes');
     if ($tokens[$commentEnd]['code'] === T_COMMENT) {
         $phpcsFile->addError('You must use "/**" style comments for a class comment', $stackPtr, 'WrongStyle');
         return;
     }
     if ($tokens[$commentEnd]['line'] !== $tokens[$stackPtr]['line'] - 1) {
         $error = 'There must be no blank lines after the class comment';
         $phpcsFile->addError($error, $commentEnd, 'SpacingAfter');
     }
     $commentStart = $tokens[$commentEnd]['comment_opener'];
     foreach ($tokens[$commentStart]['comment_tags'] as $tag) {
         $error = '%s tag is not allowed in class comment';
         $data = array($tokens[$tag]['content']);
         $phpcsFile->addWarning($error, $tag, 'TagNotAllowed', $data);
     }
 }
 /**
  * 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();
     $token = $tokens[$stackPtr];
     // Skip for-loop without body.
     if (isset($token['scope_opener']) === false) {
         return;
     }
     // Find incrementors for outer loop.
     $outer = $this->findIncrementers($tokens, $token);
     // Skip if empty.
     if (count($outer) === 0) {
         return;
     }
     // Find nested for loops.
     $start = ++$token['scope_opener'];
     $end = --$token['scope_closer'];
     for (; $start <= $end; ++$start) {
         if ($tokens[$start]['code'] !== T_FOR) {
             continue;
         }
         $inner = $this->findIncrementers($tokens, $tokens[$start]);
         $diff = array_intersect($outer, $inner);
         if (count($diff) !== 0) {
             $error = 'Loop incrementor (%s) jumbling with inner loop';
             $data = array(join(', ', $diff));
             $phpcsFile->addWarning($error, $stackPtr, 'Found', $data);
         }
     }
 }
 /**
  * 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)
 {
     $error = 'Silencing errors is forbidden';
     if ($this->error === true) {
         $error = 'Silencing errors is forbidden';
         $phpcsFile->addError($error, $stackPtr, 'Forbidden');
     } else {
         $error = 'Silencing errors is discouraged';
         $phpcsFile->addWarning($error, $stackPtr, 'Discouraged');
     }
 }
Exemple #10
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();
     if (empty($tokens[$stackPtr]['conditions']) === true) {
         $functionName = $phpcsFile->getDeclarationName($stackPtr);
         if ($functionName === null) {
             return;
         }
         // Special exception for __autoload as it needs to be global.
         if ($functionName !== '__autoload') {
             $error = 'Consider putting global function "%s" in a static class';
             $data = array($functionName);
             $phpcsFile->addWarning($error, $stackPtr, 'Found', $data);
         }
     }
 }
 /**
  * Processes the token in the specified PHP_CodeSniffer_File.
  *
  * @param PHP_CodeSniffer_File $phpcsFile The PHP_CodeSniffer file where this
  *                                        token was found.
  * @param int                  $stackPtr  The position where the token was found.
  * @param array                $currScope The current scope opener token.
  *
  * @return void
  */
 protected final function processTokenWithinScope(File $phpcsFile, $stackPtr, $currScope)
 {
     if ($this->currentFile !== $phpcsFile) {
         $this->currentFile = $phpcsFile;
         $this->functionOpen = false;
         $this->endFunction = -1;
     }
     $tokens = $phpcsFile->getTokens();
     if ($stackPtr > $this->endFunction) {
         $this->functionOpen = false;
     }
     if ($tokens[$stackPtr]['code'] === T_FUNCTION && $this->functionOpen === false) {
         $this->functionOpen = true;
         $methodProps = $phpcsFile->getMethodProperties($stackPtr);
         // If the function is abstract, or is in an interface,
         // then set the end of the function to it's closing semicolon.
         if ($methodProps['is_abstract'] === true || $tokens[$currScope]['code'] === T_INTERFACE) {
             $this->endFunction = $phpcsFile->findNext(array(T_SEMICOLON), $stackPtr);
         } else {
             if (isset($tokens[$stackPtr]['scope_closer']) === false) {
                 $error = 'Possible parse error: non-abstract method defined as abstract';
                 $phpcsFile->addWarning($error, $stackPtr, 'Internal.ParseError.NonAbstractDefinedAbstract');
                 return;
             }
             $this->endFunction = $tokens[$stackPtr]['scope_closer'];
         }
     }
     //end if
     if ($tokens[$stackPtr]['code'] === T_DOUBLE_QUOTED_STRING || $tokens[$stackPtr]['code'] === T_HEREDOC) {
         // Check to see if this string has a variable in it.
         $pattern = '|(?<!\\\\)(?:\\\\{2})*\\${?[a-zA-Z0-9_]+}?|';
         if (preg_match($pattern, $tokens[$stackPtr]['content']) !== 0) {
             $this->processVariableInString($phpcsFile, $stackPtr);
         }
         return;
     }
     if ($this->functionOpen === true) {
         if ($tokens[$stackPtr]['code'] === T_VARIABLE) {
             $this->processVariable($phpcsFile, $stackPtr);
         }
     } else {
         // What if we assign a member variable to another?
         // ie. private $_count = $this->_otherCount + 1;.
         $this->processMemberVar($phpcsFile, $stackPtr);
     }
 }
 /**
  * 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)
 {
     $tokens = $phpcsFile->getTokens();
     $functionName = $phpcsFile->findNext(T_STRING, $stackPtr + 1, null, false, null, true);
     while ($functionName !== false) {
         // Check if this is really a function.
         $bracket = $phpcsFile->findNext(T_WHITESPACE, $functionName + 1, null, true);
         if ($tokens[$bracket]['code'] !== T_OPEN_PARENTHESIS) {
             // Not a function call.
             $functionName = $phpcsFile->findNext(T_STRING, $functionName + 1, null, false, null, true);
             continue;
         }
         $error = 'The result of a function call should be assigned to a variable before being returned';
         $phpcsFile->addWarning($error, $stackPtr, 'NotAssigned');
         break;
     }
 }
 /**
  * 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)
 {
     $tokens = $phpcsFile->getTokens();
     // Make sure it is an API function. We know this by the doc comment.
     $commentEnd = $phpcsFile->findPrevious(T_DOC_COMMENT_CLOSE_TAG, $stackPtr);
     $commentStart = $phpcsFile->findPrevious(T_DOC_COMMENT_OPEN_TAG, $commentEnd - 1);
     $comment = $phpcsFile->getTokensAsString($commentStart, $commentEnd - $commentStart);
     if (strpos($comment, '* @api') === false) {
         return;
     }
     // Find all the vars passed in as we are only interested in comparisons
     // to NULL for these specific variables.
     $foundVars = array();
     $open = $tokens[$stackPtr]['parenthesis_opener'];
     $close = $tokens[$stackPtr]['parenthesis_closer'];
     for ($i = $open + 1; $i < $close; $i++) {
         if ($tokens[$i]['code'] === T_VARIABLE) {
             $foundVars[$tokens[$i]['content']] = true;
         }
     }
     if (empty($foundVars) === true) {
         return;
     }
     $start = $tokens[$stackPtr]['scope_opener'];
     $end = $tokens[$stackPtr]['scope_closer'];
     for ($i = $start + 1; $i < $end; $i++) {
         if ($tokens[$i]['code'] !== T_VARIABLE || isset($foundVars[$tokens[$i]['content']]) === false) {
             continue;
         }
         $operator = $phpcsFile->findNext(T_WHITESPACE, $i + 1, null, true);
         if ($tokens[$operator]['code'] !== T_IS_IDENTICAL && $tokens[$operator]['code'] !== T_IS_NOT_IDENTICAL) {
             continue;
         }
         $nullValue = $phpcsFile->findNext(T_WHITESPACE, $operator + 1, null, true);
         if ($tokens[$nullValue]['code'] !== T_NULL) {
             continue;
         }
         $error = 'Values submitted via Ajax requests should not be compared directly to NULL; use empty() instead';
         $phpcsFile->addWarning($error, $nullValue, 'Found');
     }
     //end for
 }
Exemple #14
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)
 {
     $tokens = $phpcsFile->getTokens();
     $content = $tokens[$stackPtr]['content'];
     $matches = array();
     preg_match('/(?:\\A|[^\\p{L}]+)todo([^\\p{L}]+(.*)|\\Z)/ui', $content, $matches);
     if (empty($matches) === false) {
         // Clear whitespace and some common characters not required at
         // the end of a to-do message to make the warning more informative.
         $type = 'CommentFound';
         $todoMessage = trim($matches[1]);
         $todoMessage = trim($todoMessage, '-:[](). ');
         $error = 'Comment refers to a TODO task';
         $data = array($todoMessage);
         if ($todoMessage !== '') {
             $type = 'TaskFound';
             $error .= ' "%s"';
         }
         $phpcsFile->addWarning($error, $stackPtr, $type, $data);
     }
 }
 /**
  * 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
 }
 /**
  * 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();
     $token = $tokens[$stackPtr];
     // Skip invalid statement.
     if (isset($token['parenthesis_opener']) === false) {
         return;
     }
     $next = ++$token['parenthesis_opener'];
     $end = --$token['parenthesis_closer'];
     $position = 0;
     for (; $next <= $end; ++$next) {
         $code = $tokens[$next]['code'];
         if ($code === T_SEMICOLON) {
             ++$position;
         }
         if ($position < 1) {
             continue;
         } else {
             if ($position > 1) {
                 break;
             } else {
                 if ($code !== T_VARIABLE && $code !== T_STRING) {
                     continue;
                 }
             }
         }
         // Find next non empty token, if it is a open curly brace we have a
         // function call.
         $index = $phpcsFile->findNext(Tokens::$emptyTokens, $next + 1, null, true);
         if ($tokens[$index]['code'] === T_OPEN_PARENTHESIS) {
             $error = 'Avoid function calls in a FOR loop test part';
             $phpcsFile->addWarning($error, $stackPtr, 'NotAllowed');
             break;
         }
     }
     //end for
 }
 /**
  * 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();
     $token = $tokens[$stackPtr];
     // Skip for-statements without body.
     if (isset($token['scope_opener']) === false) {
         return;
     }
     // Fetch previous token.
     $prev = $phpcsFile->findPrevious(Tokens::$emptyTokens, $stackPtr - 1, null, true);
     // Skip for non final class.
     if ($prev === false || $tokens[$prev]['code'] !== T_FINAL) {
         return;
     }
     $next = ++$token['scope_opener'];
     $end = --$token['scope_closer'];
     for (; $next <= $end; ++$next) {
         if ($tokens[$next]['code'] === T_FINAL) {
             $error = 'Unnecessary FINAL modifier in FINAL class';
             $phpcsFile->addWarning($error, $next, 'Found');
         }
     }
 }
 /**
  * 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)
 {
     $this->requiredSpacesAfterOpen = (int) $this->requiredSpacesAfterOpen;
     $this->requiredSpacesBeforeClose = (int) $this->requiredSpacesBeforeClose;
     $tokens = $phpcsFile->getTokens();
     $openingBracket = $phpcsFile->findNext(T_OPEN_PARENTHESIS, $stackPtr);
     if ($openingBracket === false) {
         $error = 'Possible parse error: FOREACH has no opening parenthesis';
         $phpcsFile->addWarning($error, $stackPtr, 'MissingOpenParenthesis');
         return;
     }
     if (isset($tokens[$openingBracket]['parenthesis_closer']) === false) {
         $error = 'Possible parse error: FOREACH has no closing parenthesis';
         $phpcsFile->addWarning($error, $stackPtr, 'MissingCloseParenthesis');
         return;
     }
     $closingBracket = $tokens[$openingBracket]['parenthesis_closer'];
     if ($this->requiredSpacesAfterOpen === 0 && $tokens[$openingBracket + 1]['code'] === T_WHITESPACE) {
         $error = 'Space found after opening bracket of FOREACH loop';
         $fix = $phpcsFile->addFixableError($error, $stackPtr, 'SpaceAfterOpen');
         if ($fix === true) {
             $phpcsFile->fixer->replaceToken($openingBracket + 1, '');
         }
     } else {
         if ($this->requiredSpacesAfterOpen > 0) {
             $spaceAfterOpen = 0;
             if ($tokens[$openingBracket + 1]['code'] === T_WHITESPACE) {
                 $spaceAfterOpen = strlen($tokens[$openingBracket + 1]['content']);
             }
             if ($spaceAfterOpen !== $this->requiredSpacesAfterOpen) {
                 $error = 'Expected %s spaces after opening bracket; %s found';
                 $data = array($this->requiredSpacesAfterOpen, $spaceAfterOpen);
                 $fix = $phpcsFile->addFixableError($error, $stackPtr, 'SpacingAfterOpen', $data);
                 if ($fix === true) {
                     $padding = str_repeat(' ', $this->requiredSpacesAfterOpen);
                     if ($spaceAfterOpen === 0) {
                         $phpcsFile->fixer->addContent($openingBracket, $padding);
                     } else {
                         $phpcsFile->fixer->replaceToken($openingBracket + 1, $padding);
                     }
                 }
             }
         }
     }
     //end if
     if ($this->requiredSpacesBeforeClose === 0 && $tokens[$closingBracket - 1]['code'] === T_WHITESPACE) {
         $error = 'Space found before closing bracket of FOREACH loop';
         $fix = $phpcsFile->addFixableError($error, $stackPtr, 'SpaceBeforeClose');
         if ($fix === true) {
             $phpcsFile->fixer->replaceToken($closingBracket - 1, '');
         }
     } else {
         if ($this->requiredSpacesBeforeClose > 0) {
             $spaceBeforeClose = 0;
             if ($tokens[$closingBracket - 1]['code'] === T_WHITESPACE) {
                 $spaceBeforeClose = strlen($tokens[$closingBracket - 1]['content']);
             }
             if ($spaceBeforeClose !== $this->requiredSpacesBeforeClose) {
                 $error = 'Expected %s spaces before closing bracket; %s found';
                 $data = array($this->requiredSpacesBeforeClose, $spaceBeforeClose);
                 $fix = $phpcsFile->addFixableError($error, $stackPtr, 'SpaceBeforeClose', $data);
                 if ($fix === true) {
                     $padding = str_repeat(' ', $this->requiredSpacesBeforeClose);
                     if ($spaceBeforeClose === 0) {
                         $phpcsFile->fixer->addContentBefore($closingBracket, $padding);
                     } else {
                         $phpcsFile->fixer->replaceToken($closingBracket - 1, $padding);
                     }
                 }
             }
         }
     }
     //end if
     $asToken = $phpcsFile->findNext(T_AS, $openingBracket);
     if ($asToken === false) {
         $error = 'Possible parse error: FOREACH has no AS statement';
         $phpcsFile->addWarning($error, $stackPtr, 'MissingAs');
         return;
     }
     $content = $tokens[$asToken]['content'];
     if ($content !== strtolower($content)) {
         $expected = strtolower($content);
         $error = 'AS keyword must be lowercase; expected "%s" but found "%s"';
         $data = array($expected, $content);
         $fix = $phpcsFile->addFixableError($error, $asToken, 'AsNotLower', $data);
         if ($fix === true) {
             $phpcsFile->fixer->replaceToken($asToken, $expected);
         }
     }
     $doubleArrow = $phpcsFile->findNext(T_DOUBLE_ARROW, $asToken, $closingBracket);
     if ($doubleArrow !== false) {
         if ($tokens[$doubleArrow - 1]['code'] !== T_WHITESPACE) {
             $error = 'Expected 1 space before "=>"; 0 found';
             $fix = $phpcsFile->addFixableError($error, $stackPtr, 'NoSpaceBeforeArrow');
             if ($fix === true) {
                 $phpcsFile->fixer->addContentBefore($doubleArrow, ' ');
             }
         } else {
             if (strlen($tokens[$doubleArrow - 1]['content']) !== 1) {
                 $spaces = strlen($tokens[$doubleArrow - 1]['content']);
                 $error = 'Expected 1 space before "=>"; %s found';
                 $data = array($spaces);
                 $fix = $phpcsFile->addFixableError($error, $stackPtr, 'SpacingBeforeArrow', $data);
                 if ($fix === true) {
                     $phpcsFile->fixer->replaceToken($doubleArrow - 1, ' ');
                 }
             }
         }
         if ($tokens[$doubleArrow + 1]['code'] !== T_WHITESPACE) {
             $error = 'Expected 1 space after "=>"; 0 found';
             $fix = $phpcsFile->addFixableError($error, $stackPtr, 'NoSpaceAfterArrow');
             if ($fix === true) {
                 $phpcsFile->fixer->addContent($doubleArrow, ' ');
             }
         } else {
             if (strlen($tokens[$doubleArrow + 1]['content']) !== 1) {
                 $spaces = strlen($tokens[$doubleArrow + 1]['content']);
                 $error = 'Expected 1 space after "=>"; %s found';
                 $data = array($spaces);
                 $fix = $phpcsFile->addFixableError($error, $stackPtr, 'SpacingAfterArrow', $data);
                 if ($fix === true) {
                     $phpcsFile->fixer->replaceToken($doubleArrow + 1, ' ');
                 }
             }
         }
     }
     //end if
     if ($tokens[$asToken - 1]['code'] !== T_WHITESPACE) {
         $error = 'Expected 1 space before "as"; 0 found';
         $fix = $phpcsFile->addFixableError($error, $stackPtr, 'NoSpaceBeforeAs');
         if ($fix === true) {
             $phpcsFile->fixer->addContentBefore($asToken, ' ');
         }
     } else {
         if (strlen($tokens[$asToken - 1]['content']) !== 1) {
             $spaces = strlen($tokens[$asToken - 1]['content']);
             $error = 'Expected 1 space before "as"; %s found';
             $data = array($spaces);
             $fix = $phpcsFile->addFixableError($error, $stackPtr, 'SpacingBeforeAs', $data);
             if ($fix === true) {
                 $phpcsFile->fixer->replaceToken($asToken - 1, ' ');
             }
         }
     }
     if ($tokens[$asToken + 1]['code'] !== T_WHITESPACE) {
         $error = 'Expected 1 space after "as"; 0 found';
         $fix = $phpcsFile->addFixableError($error, $stackPtr, 'NoSpaceAfterAs');
         if ($fix === true) {
             $phpcsFile->fixer->addContent($asToken, ' ');
         }
     } else {
         if (strlen($tokens[$asToken + 1]['content']) !== 1) {
             $spaces = strlen($tokens[$asToken + 1]['content']);
             $error = 'Expected 1 space after "as"; %s found';
             $data = array($spaces);
             $fix = $phpcsFile->addFixableError($error, $stackPtr, 'SpacingAfterAs', $data);
             if ($fix === true) {
                 $phpcsFile->fixer->replaceToken($asToken + 1, ' ');
             }
         }
     }
 }
 /**
  * Processes the variable found within a double quoted string.
  *
  * @param PHP_CodeSniffer_File $phpcsFile The file being scanned.
  * @param int                  $stackPtr  The position of the double quoted
  *                                        string.
  *
  * @return void
  */
 protected function processVariableInString(File $phpcsFile, $stackPtr)
 {
     $tokens = $phpcsFile->getTokens();
     $phpReservedVars = array('_SERVER', '_GET', '_POST', '_REQUEST', '_SESSION', '_ENV', '_COOKIE', '_FILES', 'GLOBALS', 'http_response_header', 'HTTP_RAW_POST_DATA', 'php_errormsg');
     if (preg_match_all('|[^\\\\]\\$([a-zA-Z_\\x7f-\\xff][a-zA-Z0-9_\\x7f-\\xff]*)|', $tokens[$stackPtr]['content'], $matches) !== 0) {
         foreach ($matches[1] as $varName) {
             // If it's a php reserved var, then its ok.
             if (in_array($varName, $phpReservedVars) === true) {
                 continue;
             }
             if (Common::isCamelCaps($varName, false, true, false) === false) {
                 $error = 'Variable "%s" is not in valid camel caps format';
                 $data = array($varName);
                 $phpcsFile->addError($error, $stackPtr, 'StringVarNotCamelCaps', $data);
             } else {
                 if (preg_match('|\\d|', $varName) === 1) {
                     $warning = 'Variable "%s" contains numbers but this is discouraged';
                     $data = array($varName);
                     $phpcsFile->addWarning($warning, $stackPtr, 'StringVarContainsNumbers', $data);
                 }
             }
         }
         //end foreach
     }
     //end if
 }
 /**
  * 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();
     $scope_identifier = $phpcsFile->findNext(T_STRING, $stackPtr + 1);
     $errorData = array(strtolower($tokens[$stackPtr]['content']) . ' ' . $tokens[$scope_identifier]['content']);
     if (isset($tokens[$stackPtr]['scope_opener']) === false) {
         $error = 'Possible parse error: %s missing opening or closing brace';
         $phpcsFile->addWarning($error, $stackPtr, 'MissingBrace', $errorData);
         return;
     }
     $openingBrace = $tokens[$stackPtr]['scope_opener'];
     // Is the brace on the same line as the class/interface/trait declaration ?
     $lastClassLineToken = $phpcsFile->findPrevious(T_STRING, $openingBrace - 1, $stackPtr);
     $lastClassLine = $tokens[$lastClassLineToken]['line'];
     $braceLine = $tokens[$openingBrace]['line'];
     $lineDifference = $braceLine - $lastClassLine;
     if ($lineDifference > 0) {
         $phpcsFile->recordMetric($stackPtr, 'Class opening brace placement', 'new line');
         $error = 'Opening brace should be on the same line as the declaration for %s';
         $fix = $phpcsFile->addFixableError($error, $openingBrace, 'BraceOnNewLine', $errorData);
         if ($fix === true) {
             $phpcsFile->fixer->beginChangeset();
             $phpcsFile->fixer->addContent($lastClassLineToken, ' {');
             $phpcsFile->fixer->replaceToken($openingBrace, '');
             $phpcsFile->fixer->endChangeset();
         }
     } else {
         $phpcsFile->recordMetric($stackPtr, 'Class opening brace placement', 'same line');
     }
     // Is the opening brace the last thing on the line ?
     $next = $phpcsFile->findNext(T_WHITESPACE, $openingBrace + 1, null, true);
     if ($tokens[$next]['line'] === $tokens[$openingBrace]['line']) {
         if ($next === $tokens[$stackPtr]['scope_closer']) {
             // Ignore empty classes.
             return;
         }
         $error = 'Opening brace must be the last content on the line';
         $fix = $phpcsFile->addFixableError($error, $openingBrace, 'ContentAfterBrace');
         if ($fix === true) {
             $phpcsFile->fixer->addNewline($openingBrace);
         }
     }
     // Only continue checking if the opening brace looks good.
     if ($lineDifference > 0) {
         return;
     }
     // Is there precisely one space before the opening brace ?
     if ($tokens[$openingBrace - 1]['code'] !== T_WHITESPACE) {
         $length = 0;
     } else {
         if ($tokens[$openingBrace - 1]['content'] === "\t") {
             $length = '\\t';
         } else {
             $length = strlen($tokens[$openingBrace - 1]['content']);
         }
     }
     if ($length !== 1) {
         $error = 'Expected 1 space before opening brace; found %s';
         $data = array($length);
         $fix = $phpcsFile->addFixableError($error, $openingBrace, 'SpaceBeforeBrace', $data);
         if ($fix === true) {
             if ($length === 0 || $length === '\\t') {
                 $phpcsFile->fixer->addContentBefore($openingBrace, ' ');
             } else {
                 $phpcsFile->fixer->replaceToken($openingBrace - 1, ' ');
             }
         }
     }
 }
 /**
  * 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();
     // Process whole comment blocks at once, so skip all but the first token.
     if ($stackPtr > 0 && $tokens[$stackPtr]['code'] === $tokens[$stackPtr - 1]['code']) {
         return;
     }
     // Ignore comments at the end of code blocks.
     if (substr($tokens[$stackPtr]['content'], 0, 6) === '//end ') {
         return;
     }
     $content = '';
     if ($phpcsFile->tokenizerType === 'PHP') {
         $content = '<?php ';
     }
     for ($i = $stackPtr; $i < $phpcsFile->numTokens; $i++) {
         if ($tokens[$stackPtr]['code'] !== $tokens[$i]['code']) {
             break;
         }
         /*
             Trim as much off the comment as possible so we don't
             have additional whitespace tokens or comment tokens
         */
         $tokenContent = trim($tokens[$i]['content']);
         if (substr($tokenContent, 0, 2) === '//') {
             $tokenContent = substr($tokenContent, 2);
         }
         if (substr($tokenContent, 0, 1) === '#') {
             $tokenContent = substr($tokenContent, 1);
         }
         if (substr($tokenContent, 0, 3) === '/**') {
             $tokenContent = substr($tokenContent, 3);
         }
         if (substr($tokenContent, 0, 2) === '/*') {
             $tokenContent = substr($tokenContent, 2);
         }
         if (substr($tokenContent, -2) === '*/') {
             $tokenContent = substr($tokenContent, 0, -2);
         }
         if (substr($tokenContent, 0, 1) === '*') {
             $tokenContent = substr($tokenContent, 1);
         }
         $content .= $tokenContent . $phpcsFile->eolChar;
     }
     //end for
     $content = trim($content);
     if ($phpcsFile->tokenizerType === 'PHP') {
         $content .= ' ?>';
     }
     // Quite a few comments use multiple dashes, equals signs etc
     // to frame comments and licence headers.
     $content = preg_replace('/[-=*]+/', '-', $content);
     // Random numbers sitting inside the content can throw parse errors
     // for invalid literals in PHP7+, so strip those.
     $content = preg_replace('/\\d+/', '', $content);
     // Because we are not really parsing code, the tokenizer can throw all sorts
     // of errors that don't mean anything, so ignore them.
     $oldErrors = ini_get('error_reporting');
     ini_set('error_reporting', 0);
     try {
         $tokenizerClass = get_class($phpcsFile->tokenizer);
         $tokenizer = new $tokenizerClass($content, $phpcsFile->config, $phpcsFile->eolChar);
         $stringTokens = $tokenizer->getTokens();
     } catch (TokenizerException $e) {
         // We couldn't check the comment, so ignore it.
         ini_set('error_reporting', $oldErrors);
         return;
     }
     ini_set('error_reporting', $oldErrors);
     $emptyTokens = array(T_WHITESPACE => true, T_STRING => true, T_STRING_CONCAT => true, T_ENCAPSED_AND_WHITESPACE => true, T_NONE => true, T_COMMENT => true);
     $numTokens = count($stringTokens);
     /*
         We know what the first two and last two tokens should be
         (because we put them there) so ignore this comment if those
         tokens were not parsed correctly. It obviously means this is not
         valid code.
     */
     // First token is always the opening PHP tag.
     if ($stringTokens[0]['code'] !== T_OPEN_TAG) {
         return;
     }
     // Last token is always the closing PHP tag, unless something went wrong.
     if (isset($stringTokens[$numTokens - 1]) === false || $stringTokens[$numTokens - 1]['code'] !== T_CLOSE_TAG) {
         return;
     }
     // Second last token is always whitespace or a comment, depending
     // on the code inside the comment.
     if ($phpcsFile->tokenizerType === 'PHP' && isset(Tokens::$emptyTokens[$stringTokens[$numTokens - 2]['code']]) === false) {
         return;
     }
     $numComment = 0;
     $numPossible = 0;
     $numCode = 0;
     for ($i = 0; $i < $numTokens; $i++) {
         if (isset($emptyTokens[$stringTokens[$i]['code']]) === true) {
             // Looks like comment.
             $numComment++;
         } else {
             if (in_array($stringTokens[$i]['code'], Tokens::$comparisonTokens) === true || in_array($stringTokens[$i]['code'], Tokens::$arithmeticTokens) === true || $stringTokens[$i]['code'] === T_GOTO_LABEL) {
                 // Commented out HTML/XML and other docs contain a lot of these
                 // characters, so it is best to not use them directly.
                 $numPossible++;
             } else {
                 // Looks like code.
                 $numCode++;
             }
         }
     }
     // We subtract 3 from the token number so we ignore the start/end tokens
     // and their surrounding whitespace. We take 2 off the number of code
     // tokens so we ignore the start/end tokens.
     if ($numTokens > 3) {
         $numTokens -= 3;
     }
     if ($numCode >= 2) {
         $numCode -= 2;
     }
     $percentCode = ceil($numCode / $numTokens * 100);
     if ($percentCode > $this->maxPercentage) {
         // Just in case.
         $percentCode = min(100, $percentCode);
         $error = 'This comment is %s%% valid code; is this commented out code?';
         $data = array($percentCode);
         $phpcsFile->addWarning($error, $stackPtr, 'Found', $data);
     }
 }
 /**
  * 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)
 {
     $this->requiredSpacesAfterOpen = (int) $this->requiredSpacesAfterOpen;
     $this->requiredSpacesBeforeClose = (int) $this->requiredSpacesBeforeClose;
     $tokens = $phpcsFile->getTokens();
     $openingBracket = $phpcsFile->findNext(T_OPEN_PARENTHESIS, $stackPtr);
     if ($openingBracket === false) {
         $error = 'Possible parse error: no opening parenthesis for FOR keyword';
         $phpcsFile->addWarning($error, $stackPtr, 'NoOpenBracket');
         return;
     }
     $closingBracket = $tokens[$openingBracket]['parenthesis_closer'];
     if ($this->requiredSpacesAfterOpen === 0 && $tokens[$openingBracket + 1]['code'] === T_WHITESPACE) {
         $error = 'Space found after opening bracket of FOR loop';
         $fix = $phpcsFile->addFixableError($error, $stackPtr, 'SpacingAfterOpen');
         if ($fix === true) {
             $phpcsFile->fixer->replaceToken($openingBracket + 1, '');
         }
     } else {
         if ($this->requiredSpacesAfterOpen > 0) {
             $spaceAfterOpen = 0;
             if ($tokens[$openingBracket + 1]['code'] === T_WHITESPACE) {
                 $spaceAfterOpen = strlen($tokens[$openingBracket + 1]['content']);
             }
             if ($spaceAfterOpen !== $this->requiredSpacesAfterOpen) {
                 $error = 'Expected %s spaces after opening bracket; %s found';
                 $data = array($this->requiredSpacesAfterOpen, $spaceAfterOpen);
                 $fix = $phpcsFile->addFixableError($error, $stackPtr, 'SpacingAfterOpen', $data);
                 if ($fix === true) {
                     $padding = str_repeat(' ', $this->requiredSpacesAfterOpen);
                     if ($spaceAfterOpen === 0) {
                         $phpcsFile->fixer->addContent($openingBracket, $padding);
                     } else {
                         $phpcsFile->fixer->replaceToken($openingBracket + 1, $padding);
                     }
                 }
             }
         }
     }
     //end if
     if ($this->requiredSpacesBeforeClose === 0 && $tokens[$closingBracket - 1]['code'] === T_WHITESPACE) {
         $error = 'Space found before closing bracket of FOR loop';
         $fix = $phpcsFile->addFixableError($error, $stackPtr, 'SpacingBeforeClose');
         if ($fix === true) {
             $phpcsFile->fixer->replaceToken($closingBracket - 1, '');
         }
     } else {
         if ($this->requiredSpacesBeforeClose > 0) {
             $spaceBeforeClose = 0;
             if ($tokens[$closingBracket - 1]['code'] === T_WHITESPACE) {
                 $spaceBeforeClose = strlen($tokens[$closingBracket - 1]['content']);
             }
             if ($this->requiredSpacesBeforeClose !== $spaceBeforeClose) {
                 $error = 'Expected %s spaces before closing bracket; %s found';
                 $data = array($this->requiredSpacesBeforeClose, $spaceBeforeClose);
                 $fix = $phpcsFile->addFixableError($error, $stackPtr, 'SpacingBeforeClose', $data);
                 if ($fix === true) {
                     $padding = str_repeat(' ', $this->requiredSpacesBeforeClose);
                     if ($spaceBeforeClose === 0) {
                         $phpcsFile->fixer->addContentBefore($closingBracket, $padding);
                     } else {
                         $phpcsFile->fixer->replaceToken($closingBracket - 1, $padding);
                     }
                 }
             }
         }
     }
     //end if
     $firstSemicolon = $phpcsFile->findNext(T_SEMICOLON, $openingBracket, $closingBracket);
     // Check whitespace around each of the tokens.
     if ($firstSemicolon !== false) {
         if ($tokens[$firstSemicolon - 1]['code'] === T_WHITESPACE) {
             $error = 'Space found before first semicolon of FOR loop';
             $fix = $phpcsFile->addFixableError($error, $stackPtr, 'SpacingBeforeFirst');
             if ($fix === true) {
                 $phpcsFile->fixer->replaceToken($firstSemicolon - 1, '');
             }
         }
         if ($tokens[$firstSemicolon + 1]['code'] !== T_WHITESPACE && $tokens[$firstSemicolon + 1]['code'] !== T_SEMICOLON) {
             $error = 'Expected 1 space after first semicolon of FOR loop; 0 found';
             $fix = $phpcsFile->addFixableError($error, $stackPtr, 'NoSpaceAfterFirst');
             if ($fix === true) {
                 $phpcsFile->fixer->addContent($firstSemicolon, ' ');
             }
         } else {
             if (strlen($tokens[$firstSemicolon + 1]['content']) !== 1) {
                 $spaces = strlen($tokens[$firstSemicolon + 1]['content']);
                 $error = 'Expected 1 space after first semicolon of FOR loop; %s found';
                 $data = array($spaces);
                 $fix = $phpcsFile->addFixableError($error, $stackPtr, 'SpacingAfterFirst', $data);
                 if ($fix === true) {
                     $phpcsFile->fixer->replaceToken($firstSemicolon + 1, ' ');
                 }
             }
         }
         $secondSemicolon = $phpcsFile->findNext(T_SEMICOLON, $firstSemicolon + 1);
         if ($secondSemicolon !== false) {
             if ($tokens[$secondSemicolon - 1]['code'] === T_WHITESPACE && $tokens[$firstSemicolon + 1]['code'] !== T_SEMICOLON) {
                 $error = 'Space found before second semicolon of FOR loop';
                 $fix = $phpcsFile->addFixableError($error, $stackPtr, 'SpacingBeforeSecond');
                 if ($fix === true) {
                     $phpcsFile->fixer->replaceToken($secondSemicolon - 1, '');
                 }
             }
             if ($secondSemicolon + 1 !== $closingBracket && $tokens[$secondSemicolon + 1]['code'] !== T_WHITESPACE) {
                 $error = 'Expected 1 space after second semicolon of FOR loop; 0 found';
                 $fix = $phpcsFile->addFixableError($error, $stackPtr, 'NoSpaceAfterSecond');
                 if ($fix === true) {
                     $phpcsFile->fixer->addContent($secondSemicolon, ' ');
                 }
             } else {
                 if (strlen($tokens[$secondSemicolon + 1]['content']) !== 1) {
                     $spaces = strlen($tokens[$secondSemicolon + 1]['content']);
                     $data = array($spaces);
                     if ($secondSemicolon + 2 === $closingBracket) {
                         $error = 'Expected no space after second semicolon of FOR loop; %s found';
                         $fix = $phpcsFile->addFixableError($error, $stackPtr, 'SpacingAfterSecondNoThird', $data);
                         if ($fix === true) {
                             $phpcsFile->fixer->replaceToken($secondSemicolon + 1, '');
                         }
                     } else {
                         $error = 'Expected 1 space after second semicolon of FOR loop; %s found';
                         $fix = $phpcsFile->addFixableError($error, $stackPtr, 'SpacingAfterSecond', $data);
                         if ($fix === true) {
                             $phpcsFile->fixer->replaceToken($secondSemicolon + 1, ' ');
                         }
                     }
                 }
             }
             //end if
         }
         //end if
     }
     //end if
 }
Exemple #23
0
 /**
  * Called to process class member vars.
  *
  * @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 processMemberVar(File $phpcsFile, $stackPtr)
 {
     $tokens = $phpcsFile->getTokens();
     $ignore = array(T_PUBLIC, T_PRIVATE, T_PROTECTED, T_VAR, T_STATIC, T_WHITESPACE);
     $commentEnd = $phpcsFile->findPrevious($ignore, $stackPtr - 1, null, true);
     if ($commentEnd === false || $tokens[$commentEnd]['code'] !== T_DOC_COMMENT_CLOSE_TAG && $tokens[$commentEnd]['code'] !== T_COMMENT) {
         $phpcsFile->addError('Missing member variable doc comment', $stackPtr, 'Missing');
         return;
     }
     if ($tokens[$commentEnd]['code'] === T_COMMENT) {
         $phpcsFile->addError('You must use "/**" style comments for a member variable comment', $stackPtr, 'WrongStyle');
         return;
     }
     $commentStart = $tokens[$commentEnd]['comment_opener'];
     $foundVar = null;
     foreach ($tokens[$commentStart]['comment_tags'] as $tag) {
         if ($tokens[$tag]['content'] === '@var') {
             if ($foundVar !== null) {
                 $error = 'Only one @var tag is allowed in a member variable comment';
                 $phpcsFile->addError($error, $tag, 'DuplicateVar');
             } else {
                 $foundVar = $tag;
             }
         } else {
             if ($tokens[$tag]['content'] === '@see') {
                 // Make sure the tag isn't empty.
                 $string = $phpcsFile->findNext(T_DOC_COMMENT_STRING, $tag, $commentEnd);
                 if ($string === false || $tokens[$string]['line'] !== $tokens[$tag]['line']) {
                     $error = 'Content missing for @see tag in member variable comment';
                     $phpcsFile->addError($error, $tag, 'EmptySees');
                 }
             } else {
                 $error = '%s tag is not allowed in member variable comment';
                 $data = array($tokens[$tag]['content']);
                 $phpcsFile->addWarning($error, $tag, 'TagNotAllowed', $data);
             }
         }
         //end if
     }
     //end foreach
     // The @var tag is the only one we require.
     if ($foundVar === null) {
         $error = 'Missing @var tag in member variable comment';
         $phpcsFile->addError($error, $commentEnd, 'MissingVar');
         return;
     }
     $firstTag = $tokens[$commentStart]['comment_tags'][0];
     if ($foundVar !== null && $tokens[$firstTag]['content'] !== '@var') {
         $error = 'The @var tag must be the first tag in a member variable comment';
         $phpcsFile->addError($error, $foundVar, 'VarOrder');
     }
     // Make sure the tag isn't empty and has the correct padding.
     $string = $phpcsFile->findNext(T_DOC_COMMENT_STRING, $foundVar, $commentEnd);
     if ($string === false || $tokens[$string]['line'] !== $tokens[$foundVar]['line']) {
         $error = 'Content missing for @var tag in member variable comment';
         $phpcsFile->addError($error, $foundVar, 'EmptyVar');
         return;
     }
     $varType = $tokens[$foundVar + 2]['content'];
     $suggestedType = Common::suggestType($varType);
     if ($varType !== $suggestedType) {
         $error = 'Expected "%s" but found "%s" for @var tag in member variable comment';
         $data = array($suggestedType, $varType);
         $fix = $phpcsFile->addFixableError($error, $foundVar + 2, 'IncorrectVarType', $data);
         if ($fix === true) {
             $phpcsFile->fixer->replaceToken($foundVar + 2, $suggestedType);
         }
     }
 }
 /**
  * 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)
 {
     $tokens = $phpcsFile->getTokens();
     /*
         We need to find all strings that will be in the eval
         to determine if the "new" keyword is being used.
     */
     $openBracket = $phpcsFile->findNext(T_OPEN_PARENTHESIS, $stackPtr + 1);
     $closeBracket = $tokens[$openBracket]['parenthesis_closer'];
     $strings = array();
     $vars = array();
     for ($i = $openBracket + 1; $i < $closeBracket; $i++) {
         if (isset(Tokens::$stringTokens[$tokens[$i]['code']]) === true) {
             $strings[$i] = $tokens[$i]['content'];
         } else {
             if ($tokens[$i]['code'] === T_VARIABLE) {
                 $vars[$i] = $tokens[$i]['content'];
             }
         }
     }
     /*
         We now have some variables that we need to expand into
         the strings that were assigned to them, if any.
     */
     foreach ($vars as $varPtr => $varName) {
         while (($prev = $phpcsFile->findPrevious(T_VARIABLE, $varPtr - 1)) !== false) {
             // Make sure this is an assignment of the variable. That means
             // it will be the first thing on the line.
             $prevContent = $phpcsFile->findPrevious(T_WHITESPACE, $prev - 1, null, true);
             if ($tokens[$prevContent]['line'] === $tokens[$prev]['line']) {
                 $varPtr = $prevContent;
                 continue;
             }
             if ($tokens[$prev]['content'] !== $varName) {
                 // This variable has a different name.
                 $varPtr = $prevContent;
                 continue;
             }
             // We found one.
             break;
         }
         //end while
         if ($prev !== false) {
             // Find all strings on the line.
             $lineEnd = $phpcsFile->findNext(T_SEMICOLON, $prev + 1);
             for ($i = $prev + 1; $i < $lineEnd; $i++) {
                 if (isset(Tokens::$stringTokens[$tokens[$i]['code']]) === true) {
                     $strings[$i] = $tokens[$i]['content'];
                 }
             }
         }
     }
     //end foreach
     foreach ($strings as $string) {
         // If the string has "new" in it, it is not allowed.
         // We don't bother checking if the word "new" is echo'd
         // because that is unlikely to happen. We assume the use
         // of "new" is for object instantiation.
         if (strstr($string, ' new ') !== false) {
             $error = 'Do not use eval() to create objects dynamically; use reflection instead';
             $phpcsFile->addWarning($error, $stackPtr, 'Found');
         }
     }
 }
 /**
  * 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();
     // If this token is preceded with an "or", it only relates to one line
     // and should be ignored. For example: fopen() or die().
     $prev = $phpcsFile->findPrevious(Tokens::$emptyTokens, $stackPtr - 1, null, true);
     if ($tokens[$prev]['code'] === T_LOGICAL_OR || $tokens[$prev]['code'] === T_BOOLEAN_OR) {
         return;
     }
     // Check if this token is actually part of a one-line IF or ELSE statement.
     for ($i = $stackPtr - 1; $i > 0; $i--) {
         if ($tokens[$i]['code'] === T_CLOSE_PARENTHESIS) {
             $i = $tokens[$i]['parenthesis_opener'];
             continue;
         } else {
             if (isset(Tokens::$emptyTokens[$tokens[$i]['code']]) === true) {
                 continue;
             }
         }
         break;
     }
     if ($tokens[$i]['code'] === T_IF || $tokens[$i]['code'] === T_ELSE || $tokens[$i]['code'] === T_ELSEIF) {
         return;
     }
     if ($tokens[$stackPtr]['code'] === T_RETURN) {
         $next = $phpcsFile->findNext(T_WHITESPACE, $stackPtr + 1, null, true);
         if ($tokens[$next]['code'] === T_SEMICOLON) {
             $next = $phpcsFile->findNext(T_WHITESPACE, $next + 1, null, true);
             if ($tokens[$next]['code'] === T_CLOSE_CURLY_BRACKET) {
                 // If this is the closing brace of a function
                 // then this return statement doesn't return anything
                 // and is not required anyway.
                 $owner = $tokens[$next]['scope_condition'];
                 if ($tokens[$owner]['code'] === T_FUNCTION) {
                     $warning = 'Empty return statement not required here';
                     $phpcsFile->addWarning($warning, $stackPtr, 'ReturnNotRequired');
                     return;
                 }
             }
         }
     }
     if (isset($tokens[$stackPtr]['scope_opener']) === true) {
         $owner = $tokens[$stackPtr]['scope_condition'];
         if ($tokens[$owner]['code'] === T_CASE || $tokens[$owner]['code'] === T_DEFAULT) {
             // This token closes the scope of a CASE or DEFAULT statement
             // so any code between this statement and the next CASE, DEFAULT or
             // end of SWITCH token will not be executable.
             $end = $phpcsFile->findEndOfStatement($stackPtr);
             $next = $phpcsFile->findNext(array(T_CASE, T_DEFAULT, T_CLOSE_CURLY_BRACKET), $end + 1);
             if ($next !== false) {
                 $lastLine = $tokens[$end]['line'];
                 for ($i = $stackPtr + 1; $i < $next; $i++) {
                     if (isset(Tokens::$emptyTokens[$tokens[$i]['code']]) === true) {
                         continue;
                     }
                     $line = $tokens[$i]['line'];
                     if ($line > $lastLine) {
                         $type = substr($tokens[$stackPtr]['type'], 2);
                         $warning = 'Code after %s statement cannot be executed';
                         $data = array($type);
                         $phpcsFile->addWarning($warning, $i, 'Unreachable', $data);
                         $lastLine = $line;
                     }
                 }
             }
             //end if
             // That's all we have to check for these types of statements.
             return;
         }
         //end if
     }
     //end if
     // This token may be part of an inline condition.
     // If we find a closing parenthesis that belongs to a condition
     // we should ignore this token.
     $prev = $phpcsFile->findPrevious(Tokens::$emptyTokens, $stackPtr - 1, null, true);
     if (isset($tokens[$prev]['parenthesis_owner']) === true) {
         $owner = $tokens[$prev]['parenthesis_owner'];
         $ignore = array(T_IF => true, T_ELSE => true, T_ELSEIF => true);
         if (isset($ignore[$tokens[$owner]['code']]) === true) {
             return;
         }
     }
     $ourConditions = array_keys($tokens[$stackPtr]['conditions']);
     if (empty($ourConditions) === false) {
         $condition = array_pop($ourConditions);
         if (isset($tokens[$condition]['scope_closer']) === false) {
             return;
         }
         // Special case for BREAK statements sitting directly inside SWITCH
         // statements. If we get to this point, we know the BREAK is not being
         // used to close a CASE statement, so it is most likely non-executable
         // code itself (as is the case when you put return; break; at the end of
         // a case). So we need to ignore this token.
         if ($tokens[$condition]['code'] === T_SWITCH && $tokens[$stackPtr]['code'] === T_BREAK) {
             return;
         }
         $closer = $tokens[$condition]['scope_closer'];
         // If the closer for our condition is shared with other openers,
         // we will need to throw errors from this token to the next
         // shared opener (if there is one), not to the scope closer.
         $nextOpener = null;
         for ($i = $stackPtr + 1; $i < $closer; $i++) {
             if (isset($tokens[$i]['scope_closer']) === true) {
                 if ($tokens[$i]['scope_closer'] === $closer) {
                     // We found an opener that shares the same
                     // closing token as us.
                     $nextOpener = $i;
                     break;
                 }
             }
         }
         //end for
         if ($nextOpener === null) {
             $end = $closer;
         } else {
             $end = $nextOpener - 1;
         }
     } else {
         // This token is in the global scope.
         if ($tokens[$stackPtr]['code'] === T_BREAK) {
             return;
         }
         // Throw an error for all lines until the end of the file.
         $end = $phpcsFile->numTokens - 1;
     }
     //end if
     // Find the semicolon that ends this statement, skipping
     // nested statements like FOR loops and closures.
     for ($start = $stackPtr + 1; $start < $phpcsFile->numTokens; $start++) {
         if ($start === $end) {
             break;
         }
         if ($tokens[$start]['code'] === T_OPEN_PARENTHESIS) {
             $start = $tokens[$start]['parenthesis_closer'];
             continue;
         }
         if ($tokens[$start]['code'] === T_OPEN_CURLY_BRACKET) {
             $start = $tokens[$start]['bracket_closer'];
             continue;
         }
         if ($tokens[$start]['code'] === T_SEMICOLON) {
             break;
         }
     }
     //end for
     $lastLine = $tokens[$start]['line'];
     for ($i = $start + 1; $i < $end; $i++) {
         if (isset(Tokens::$emptyTokens[$tokens[$i]['code']]) === true || isset(Tokens::$bracketTokens[$tokens[$i]['code']]) === true) {
             continue;
         }
         // Skip whole functions and classes/interfaces because they are not
         // technically executed code, but rather declarations that may be used.
         if ($tokens[$i]['code'] === T_FUNCTION || $tokens[$i]['code'] === T_CLASS || $tokens[$i]['code'] === T_INTERFACE) {
             $i = $tokens[$i]['scope_closer'];
             continue;
         }
         $line = $tokens[$i]['line'];
         if ($line > $lastLine) {
             $type = substr($tokens[$stackPtr]['type'], 2);
             $warning = 'Code after %s statement cannot be executed';
             $data = array($type);
             $phpcsFile->addWarning($warning, $i, 'Unreachable', $data);
             $lastLine = $line;
         }
     }
     //end for
 }
 /**
  * Processes this test, when one of its tokens is encountered.
  *
  * @param PHP_CodeSniffer_File $phpcsFile The file being scanned.
  * @param integer              $stackPtr  The position of the current token in the
  *                                        stack passed in $tokens.
  *
  * @return void
  */
 public function process(File $phpcsFile, $stackPtr)
 {
     $tokens = $phpcsFile->getTokens();
     $errorData = array(strtolower($tokens[$stackPtr]['content']));
     if (isset($tokens[$stackPtr]['scope_opener']) === false) {
         $error = 'Possible parse error: %s missing opening or closing brace';
         $phpcsFile->addWarning($error, $stackPtr, 'MissingBrace', $errorData);
         return;
     }
     $curlyBrace = $tokens[$stackPtr]['scope_opener'];
     $lastContent = $phpcsFile->findPrevious(T_WHITESPACE, $curlyBrace - 1, $stackPtr, true);
     $classLine = $tokens[$lastContent]['line'];
     $braceLine = $tokens[$curlyBrace]['line'];
     if ($braceLine === $classLine) {
         $phpcsFile->recordMetric($stackPtr, 'Class opening brace placement', 'same line');
         $error = 'Opening brace of a %s must be on the line after the definition';
         $fix = $phpcsFile->addFixableError($error, $curlyBrace, 'OpenBraceNewLine', $errorData);
         if ($fix === true) {
             $phpcsFile->fixer->beginChangeset();
             if ($tokens[$curlyBrace - 1]['code'] === T_WHITESPACE) {
                 $phpcsFile->fixer->replaceToken($curlyBrace - 1, '');
             }
             $phpcsFile->fixer->addNewlineBefore($curlyBrace);
             $phpcsFile->fixer->endChangeset();
         }
         return;
     } else {
         $phpcsFile->recordMetric($stackPtr, 'Class opening brace placement', 'new line');
         if ($braceLine > $classLine + 1) {
             $error = 'Opening brace of a %s must be on the line following the %s declaration; found %s line(s)';
             $data = array($tokens[$stackPtr]['content'], $tokens[$stackPtr]['content'], $braceLine - $classLine - 1);
             $fix = $phpcsFile->addFixableError($error, $curlyBrace, 'OpenBraceWrongLine', $data);
             if ($fix === true) {
                 $phpcsFile->fixer->beginChangeset();
                 for ($i = $curlyBrace - 1; $i > $lastContent; $i--) {
                     if ($tokens[$i]['line'] === $tokens[$curlyBrace]['line'] + 1) {
                         break;
                     }
                     $phpcsFile->fixer->replaceToken($i, '');
                 }
                 $phpcsFile->fixer->endChangeset();
             }
             return;
         }
         //end if
     }
     //end if
     if ($tokens[$curlyBrace + 1]['content'] !== $phpcsFile->eolChar) {
         $error = 'Opening %s brace must be on a line by itself';
         $fix = $phpcsFile->addFixableError($error, $curlyBrace, 'OpenBraceNotAlone', $errorData);
         if ($fix === true) {
             $phpcsFile->fixer->addNewline($curlyBrace);
         }
     }
     if ($tokens[$curlyBrace - 1]['code'] === T_WHITESPACE) {
         $prevContent = $tokens[$curlyBrace - 1]['content'];
         if ($prevContent === $phpcsFile->eolChar) {
             $spaces = 0;
         } else {
             $blankSpace = substr($prevContent, strpos($prevContent, $phpcsFile->eolChar));
             $spaces = strlen($blankSpace);
         }
         $expected = $tokens[$stackPtr]['level'] * $this->indent;
         if ($spaces !== $expected) {
             $error = 'Expected %s spaces before opening brace; %s found';
             $data = array($expected, $spaces);
             $fix = $phpcsFile->addFixableError($error, $curlyBrace, 'SpaceBeforeBrace', $data);
             if ($fix === true) {
                 $indent = str_repeat(' ', $expected);
                 if ($spaces === 0) {
                     $phpcsFile->fixer->addContentBefore($curlyBrace, $indent);
                 } else {
                     $phpcsFile->fixer->replaceToken($curlyBrace - 1, $indent);
                 }
             }
         }
     }
     //end if
 }
 /**
  * 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();
     // We can't process SWITCH statements unless we know where they start and end.
     if (isset($tokens[$stackPtr]['scope_opener']) === false || isset($tokens[$stackPtr]['scope_closer']) === false) {
         return;
     }
     $switch = $tokens[$stackPtr];
     $nextCase = $stackPtr;
     $caseAlignment = $switch['column'] + $this->indent;
     $caseCount = 0;
     $foundDefault = false;
     while (($nextCase = $phpcsFile->findNext(array(T_CASE, T_DEFAULT, T_SWITCH), $nextCase + 1, $switch['scope_closer'])) !== false) {
         // Skip nested SWITCH statements; they are handled on their own.
         if ($tokens[$nextCase]['code'] === T_SWITCH) {
             $nextCase = $tokens[$nextCase]['scope_closer'];
             continue;
         }
         if ($tokens[$nextCase]['code'] === T_DEFAULT) {
             $type = 'Default';
             $foundDefault = true;
         } else {
             $type = 'Case';
             $caseCount++;
         }
         if ($tokens[$nextCase]['content'] !== strtolower($tokens[$nextCase]['content'])) {
             $expected = strtolower($tokens[$nextCase]['content']);
             $error = strtoupper($type) . ' keyword must be lowercase; expected "%s" but found "%s"';
             $data = array($expected, $tokens[$nextCase]['content']);
             $fix = $phpcsFile->addFixableError($error, $nextCase, $type . 'NotLower', $data);
             if ($fix === true) {
                 $phpcsFile->fixer->replaceToken($nextCase, $expected);
             }
         }
         if ($tokens[$nextCase]['column'] !== $caseAlignment) {
             $error = strtoupper($type) . ' keyword must be indented ' . $this->indent . ' spaces from SWITCH keyword';
             $fix = $phpcsFile->addFixableError($error, $nextCase, $type . 'Indent');
             if ($fix === true) {
                 $padding = str_repeat(' ', $caseAlignment - 1);
                 if ($tokens[$nextCase]['column'] === 1 || $tokens[$nextCase - 1]['code'] !== T_WHITESPACE) {
                     $phpcsFile->fixer->addContentBefore($nextCase, $padding);
                 } else {
                     $phpcsFile->fixer->replaceToken($nextCase - 1, $padding);
                 }
             }
         }
         if ($type === 'Case' && ($tokens[$nextCase + 1]['type'] !== 'T_WHITESPACE' || $tokens[$nextCase + 1]['content'] !== ' ')) {
             $error = 'CASE keyword must be followed by a single space';
             $fix = $phpcsFile->addFixableError($error, $nextCase, 'SpacingAfterCase');
             if ($fix === true) {
                 if ($tokens[$nextCase + 1]['type'] !== 'T_WHITESPACE') {
                     $phpcsFile->fixer->addContent($nextCase, ' ');
                 } else {
                     $phpcsFile->fixer->replaceToken($nextCase + 1, ' ');
                 }
             }
         }
         if (isset($tokens[$nextCase]['scope_opener']) === false) {
             $error = 'Possible parse error: CASE missing opening colon';
             $phpcsFile->addWarning($error, $nextCase, 'MissingColon');
             continue;
         }
         $opener = $tokens[$nextCase]['scope_opener'];
         if ($tokens[$opener - 1]['type'] === 'T_WHITESPACE') {
             $error = 'There must be no space before the colon in a ' . strtoupper($type) . ' statement';
             $fix = $phpcsFile->addFixableError($error, $nextCase, 'SpaceBeforeColon' . $type);
             if ($fix === true) {
                 $phpcsFile->fixer->replaceToken($opener - 1, '');
             }
         }
         $nextBreak = $tokens[$nextCase]['scope_closer'];
         if ($tokens[$nextBreak]['code'] === T_BREAK || $tokens[$nextBreak]['code'] === T_RETURN || $tokens[$nextBreak]['code'] === T_CONTINUE || $tokens[$nextBreak]['code'] === T_THROW || $tokens[$nextBreak]['code'] === T_EXIT) {
             if ($tokens[$nextBreak]['scope_condition'] === $nextCase) {
                 // Only need to check a couple of things once, even if the
                 // break is shared between multiple case statements, or even
                 // the default case.
                 if ($tokens[$nextBreak]['column'] !== $caseAlignment) {
                     $error = 'Case breaking statement must be indented ' . $this->indent . ' spaces from SWITCH keyword';
                     $fix = $phpcsFile->addFixableError($error, $nextBreak, 'BreakIndent');
                     if ($fix === true) {
                         $padding = str_repeat(' ', $caseAlignment - 1);
                         if ($tokens[$nextBreak]['column'] === 1 || $tokens[$nextBreak - 1]['code'] !== T_WHITESPACE) {
                             $phpcsFile->fixer->addContentBefore($nextBreak, $padding);
                         } else {
                             $phpcsFile->fixer->replaceToken($nextBreak - 1, $padding);
                         }
                     }
                 }
                 $prev = $phpcsFile->findPrevious(T_WHITESPACE, $nextBreak - 1, $stackPtr, true);
                 if ($tokens[$prev]['line'] !== $tokens[$nextBreak]['line'] - 1) {
                     $error = 'Blank lines are not allowed before case breaking statements';
                     $phpcsFile->addError($error, $nextBreak, 'SpacingBeforeBreak');
                 }
                 $nextLine = $tokens[$tokens[$stackPtr]['scope_closer']]['line'];
                 $semicolon = $phpcsFile->findEndOfStatement($nextBreak);
                 for ($i = $semicolon + 1; $i < $tokens[$stackPtr]['scope_closer']; $i++) {
                     if ($tokens[$i]['type'] !== 'T_WHITESPACE') {
                         $nextLine = $tokens[$i]['line'];
                         break;
                     }
                 }
                 if ($type === 'Case') {
                     // Ensure the BREAK statement is followed by
                     // a single blank line, or the end switch brace.
                     if ($nextLine !== $tokens[$semicolon]['line'] + 2 && $i !== $tokens[$stackPtr]['scope_closer']) {
                         $error = 'Case breaking statements must be followed by a single blank line';
                         $fix = $phpcsFile->addFixableError($error, $nextBreak, 'SpacingAfterBreak');
                         if ($fix === true) {
                             $phpcsFile->fixer->beginChangeset();
                             for ($i = $semicolon + 1; $i <= $tokens[$stackPtr]['scope_closer']; $i++) {
                                 if ($tokens[$i]['line'] === $nextLine) {
                                     $phpcsFile->fixer->addNewlineBefore($i);
                                     break;
                                 }
                                 if ($tokens[$i]['line'] === $tokens[$semicolon]['line']) {
                                     continue;
                                 }
                                 $phpcsFile->fixer->replaceToken($i, '');
                             }
                             $phpcsFile->fixer->endChangeset();
                         }
                     }
                     //end if
                 } else {
                     // Ensure the BREAK statement is not followed by a blank line.
                     if ($nextLine !== $tokens[$semicolon]['line'] + 1) {
                         $error = 'Blank lines are not allowed after the DEFAULT case\'s breaking statement';
                         $phpcsFile->addError($error, $nextBreak, 'SpacingAfterDefaultBreak');
                     }
                 }
                 //end if
                 $caseLine = $tokens[$nextCase]['line'];
                 $nextLine = $tokens[$nextBreak]['line'];
                 for ($i = $opener + 1; $i < $nextBreak; $i++) {
                     if ($tokens[$i]['type'] !== 'T_WHITESPACE') {
                         $nextLine = $tokens[$i]['line'];
                         break;
                     }
                 }
                 if ($nextLine !== $caseLine + 1) {
                     $error = 'Blank lines are not allowed after ' . strtoupper($type) . ' statements';
                     $phpcsFile->addError($error, $nextCase, 'SpacingAfter' . $type);
                 }
             }
             //end if
             if ($tokens[$nextBreak]['code'] === T_BREAK) {
                 if ($type === 'Case') {
                     // Ensure empty CASE statements are not allowed.
                     // They must have some code content in them. A comment is not enough.
                     // But count RETURN statements as valid content if they also
                     // happen to close the CASE statement.
                     $foundContent = false;
                     for ($i = $tokens[$nextCase]['scope_opener'] + 1; $i < $nextBreak; $i++) {
                         if ($tokens[$i]['code'] === T_CASE) {
                             $i = $tokens[$i]['scope_opener'];
                             continue;
                         }
                         if (isset(Tokens::$emptyTokens[$tokens[$i]['code']]) === false) {
                             $foundContent = true;
                             break;
                         }
                     }
                     if ($foundContent === false) {
                         $error = 'Empty CASE statements are not allowed';
                         $phpcsFile->addError($error, $nextCase, 'EmptyCase');
                     }
                 } else {
                     // Ensure empty DEFAULT statements are not allowed.
                     // They must (at least) have a comment describing why
                     // the default case is being ignored.
                     $foundContent = false;
                     for ($i = $tokens[$nextCase]['scope_opener'] + 1; $i < $nextBreak; $i++) {
                         if ($tokens[$i]['type'] !== 'T_WHITESPACE') {
                             $foundContent = true;
                             break;
                         }
                     }
                     if ($foundContent === false) {
                         $error = 'Comment required for empty DEFAULT case';
                         $phpcsFile->addError($error, $nextCase, 'EmptyDefault');
                     }
                 }
                 //end if
             }
             //end if
         } else {
             if ($type === 'Default') {
                 $error = 'DEFAULT case must have a breaking statement';
                 $phpcsFile->addError($error, $nextCase, 'DefaultNoBreak');
             }
         }
         //end if
     }
     //end while
     if ($foundDefault === false) {
         $error = 'All SWITCH statements must contain a DEFAULT case';
         $phpcsFile->addError($error, $stackPtr, 'MissingDefault');
     }
     if ($tokens[$switch['scope_closer']]['column'] !== $switch['column']) {
         $error = 'Closing brace of SWITCH statement must be aligned with SWITCH keyword';
         $phpcsFile->addError($error, $switch['scope_closer'], 'CloseBraceAlign');
     }
     if ($caseCount === 0) {
         $error = 'SWITCH statements must contain at least one CASE statement';
         $phpcsFile->addError($error, $stackPtr, 'MissingCase');
     }
 }
 /**
  * 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();
     $token = $tokens[$stackPtr];
     // Skip broken function declarations.
     if (isset($token['scope_opener']) === false || isset($token['parenthesis_opener']) === false) {
         return;
     }
     $params = array();
     foreach ($phpcsFile->getMethodParameters($stackPtr) as $param) {
         $params[$param['name']] = $stackPtr;
     }
     $next = ++$token['scope_opener'];
     $end = --$token['scope_closer'];
     $foundContent = false;
     $validTokens = array(T_HEREDOC => T_HEREDOC, T_NOWDOC => T_NOWDOC, T_END_HEREDOC => T_END_HEREDOC, T_END_NOWDOC => T_END_NOWDOC, T_DOUBLE_QUOTED_STRING => T_DOUBLE_QUOTED_STRING);
     $validTokens += Tokens::$emptyTokens;
     for (; $next <= $end; ++$next) {
         $token = $tokens[$next];
         $code = $token['code'];
         // Ignorable tokens.
         if (isset(Tokens::$emptyTokens[$code]) === true) {
             continue;
         }
         if ($foundContent === false) {
             // A throw statement as the first content indicates an interface method.
             if ($code === T_THROW) {
                 return;
             }
             // A return statement as the first content indicates an interface method.
             if ($code === T_RETURN) {
                 $tmp = $phpcsFile->findNext(Tokens::$emptyTokens, $next + 1, null, true);
                 if ($tmp === false) {
                     return;
                 }
                 // There is a return.
                 if ($tokens[$tmp]['code'] === T_SEMICOLON) {
                     return;
                 }
                 $tmp = $phpcsFile->findNext(Tokens::$emptyTokens, $tmp + 1, null, true);
                 if ($tmp !== false && $tokens[$tmp]['code'] === T_SEMICOLON) {
                     // There is a return <token>.
                     return;
                 }
             }
             //end if
         }
         //end if
         $foundContent = true;
         if ($code === T_VARIABLE && isset($params[$token['content']]) === true) {
             unset($params[$token['content']]);
         } else {
             if ($code === T_DOLLAR) {
                 $nextToken = $phpcsFile->findNext(T_WHITESPACE, $next + 1, null, true);
                 if ($tokens[$nextToken]['code'] === T_OPEN_CURLY_BRACKET) {
                     $nextToken = $phpcsFile->findNext(T_WHITESPACE, $nextToken + 1, null, true);
                     if ($tokens[$nextToken]['code'] === T_STRING) {
                         $varContent = '$' . $tokens[$nextToken]['content'];
                         if (isset($params[$varContent]) === true) {
                             unset($params[$varContent]);
                         }
                     }
                 }
             } else {
                 if ($code === T_DOUBLE_QUOTED_STRING || $code === T_START_HEREDOC || $code === T_START_NOWDOC) {
                     // Tokenize strings that can contain variables.
                     // Make sure the string is re-joined if it occurs over multiple lines.
                     $content = $token['content'];
                     for ($i = $next + 1; $i <= $end; $i++) {
                         if (isset($validTokens[$tokens[$i]['code']]) === true) {
                             $content .= $tokens[$i]['content'];
                             $next++;
                         } else {
                             break;
                         }
                     }
                     $stringTokens = token_get_all(sprintf('<?php %s;?>', $content));
                     foreach ($stringTokens as $stringPtr => $stringToken) {
                         if (is_array($stringToken) === false) {
                             continue;
                         }
                         $varContent = '';
                         if ($stringToken[0] === T_DOLLAR_OPEN_CURLY_BRACES) {
                             $varContent = '$' . $stringTokens[$stringPtr + 1][1];
                         } else {
                             if ($stringToken[0] === T_VARIABLE) {
                                 $varContent = $stringToken[1];
                             }
                         }
                         if ($varContent !== '' && isset($params[$varContent]) === true) {
                             unset($params[$varContent]);
                         }
                     }
                 }
             }
         }
         //end if
     }
     //end for
     if ($foundContent === true && count($params) > 0) {
         foreach ($params as $paramName => $position) {
             $error = 'The method parameter %s is never used';
             $data = array($paramName);
             $phpcsFile->addWarning($error, $position, 'Found', $data);
         }
     }
 }
Exemple #29
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)
 {
     $error = 'Use of eval() is discouraged';
     $phpcsFile->addWarning($error, $stackPtr, 'Discouraged');
 }
 /**
  * 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();
     if ($tokens[$stackPtr]['code'] === T_FUNCTION) {
         $methodProps = $phpcsFile->getMethodProperties($stackPtr);
         // Abstract methods do not require a closing comment.
         if ($methodProps['is_abstract'] === true) {
             return;
         }
         // Closures do not require a closing comment.
         if ($methodProps['is_closure'] === true) {
             return;
         }
         // If this function is in an interface then we don't require
         // a closing comment.
         if ($phpcsFile->hasCondition($stackPtr, T_INTERFACE) === true) {
             return;
         }
         if (isset($tokens[$stackPtr]['scope_closer']) === false) {
             $error = 'Possible parse error: non-abstract method defined as abstract';
             $phpcsFile->addWarning($error, $stackPtr, 'Abstract');
             return;
         }
         $decName = $phpcsFile->getDeclarationName($stackPtr);
         $comment = '//end ' . $decName . '()';
     } else {
         if ($tokens[$stackPtr]['code'] === T_CLASS) {
             $comment = '//end class';
         } else {
             $comment = '//end interface';
         }
     }
     //end if
     if (isset($tokens[$stackPtr]['scope_closer']) === false) {
         $error = 'Possible parse error: %s missing opening or closing brace';
         $data = array($tokens[$stackPtr]['content']);
         $phpcsFile->addWarning($error, $stackPtr, 'MissingBrace', $data);
         return;
     }
     $closingBracket = $tokens[$stackPtr]['scope_closer'];
     if ($closingBracket === null) {
         // Possible inline structure. Other tests will handle it.
         return;
     }
     $error = 'Expected ' . $comment;
     if (isset($tokens[$closingBracket + 1]) === false || $tokens[$closingBracket + 1]['code'] !== T_COMMENT) {
         $next = $phpcsFile->findNext(T_WHITESPACE, $closingBracket + 1, null, true);
         if (rtrim($tokens[$next]['content']) === $comment) {
             // The comment isn't really missing; it is just in the wrong place.
             $fix = $phpcsFile->addFixableError($error . ' directly after closing brace', $closingBracket, 'Misplaced');
             if ($fix === true) {
                 $phpcsFile->fixer->beginChangeset();
                 for ($i = $closingBracket + 1; $i < $next; $i++) {
                     $phpcsFile->fixer->replaceToken($i, '');
                 }
                 // Just in case, because indentation fixes can add indents onto
                 // these comments and cause us to be unable to fix them.
                 $phpcsFile->fixer->replaceToken($next, $comment . $phpcsFile->eolChar);
                 $phpcsFile->fixer->endChangeset();
             }
         } else {
             $fix = $phpcsFile->addFixableError($error, $closingBracket, 'Missing');
             if ($fix === true) {
                 $phpcsFile->fixer->replaceToken($closingBracket, '}' . $comment . $phpcsFile->eolChar);
             }
         }
         return;
     }
     //end if
     if (rtrim($tokens[$closingBracket + 1]['content']) !== $comment) {
         $fix = $phpcsFile->addFixableError($error, $closingBracket, 'Incorrect');
         if ($fix === true) {
             $phpcsFile->fixer->replaceToken($closingBracket + 1, $comment . $phpcsFile->eolChar);
         }
         return;
     }
 }