/**
  * Processes the tokens within the scope.
  *
  * @param PHP_CodeSniffer_File $phpcsFile The file being processed.
  * @param int                  $stackPtr  The position where this token was
  *                                        found.
  * @param int                  $currScope The position of the current scope.
  *
  * @return void
  */
 protected function processTokenWithinScope(File $phpcsFile, $stackPtr, $currScope)
 {
     $methodName = $phpcsFile->getDeclarationName($stackPtr);
     if ($methodName === null) {
         // Ignore closures.
         return;
     }
     // Ignore magic methods.
     if (preg_match('|^__|', $methodName) !== 0) {
         $magicPart = strtolower(substr($methodName, 2));
         if (isset($this->magicMethods[$magicPart]) === true || isset($this->methodsDoubleUnderscore[$magicPart]) === true) {
             return;
         }
     }
     $testName = ltrim($methodName, '_');
     if ($testName !== '' && Common::isCamelCaps($testName, false, true, false) === false) {
         $error = 'Method name "%s" is not in camel caps format';
         $className = $phpcsFile->getDeclarationName($currScope);
         $errorData = array($className . '::' . $methodName);
         $phpcsFile->addError($error, $stackPtr, 'NotCamelCaps', $errorData);
         $phpcsFile->recordMetric($stackPtr, 'CamelCase method name', 'no');
     } else {
         $phpcsFile->recordMetric($stackPtr, 'CamelCase method name', 'yes');
     }
 }
Example #2
0
 /**
  * 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.
  * @param int                  $currScope The current scope opener token.
  *
  * @return void
  */
 protected function processTokenWithinScope(File $phpcsFile, $stackPtr, $currScope)
 {
     $tokens = $phpcsFile->getTokens();
     $methodName = $phpcsFile->getDeclarationName($stackPtr);
     if ($methodName === null) {
         // Ignore closures.
         return;
     }
     if ($phpcsFile->hasCondition($stackPtr, T_FUNCTION) === true) {
         // Ignore nested functions.
         return;
     }
     $modifier = null;
     for ($i = $stackPtr - 1; $i > 0; $i--) {
         if ($tokens[$i]['line'] < $tokens[$stackPtr]['line']) {
             break;
         } else {
             if (isset(Tokens::$scopeModifiers[$tokens[$i]['code']]) === true) {
                 $modifier = $i;
                 break;
             }
         }
     }
     if ($modifier === null) {
         $error = 'Visibility must be declared on method "%s"';
         $data = array($methodName);
         $phpcsFile->addError($error, $stackPtr, 'Missing', $data);
     }
 }
Example #3
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);
         }
     }
 }
Example #4
0
 /**
  * Processes the tokens outside the scope.
  *
  * @param PHP_CodeSniffer_File $phpcsFile The file being processed.
  * @param int                  $stackPtr  The position where this token was
  *                                        found.
  *
  * @return void
  */
 protected function processTokenOutsideScope(File $phpcsFile, $stackPtr)
 {
     $functionName = $phpcsFile->getDeclarationName($stackPtr);
     if ($functionName === null) {
         return;
     }
     $errorData = array($functionName);
     // Does this function claim to be magical?
     if (preg_match('|^__|', $functionName) !== 0) {
         $error = 'Function name "%s" is invalid; only PHP magic methods should be prefixed with a double underscore';
         $phpcsFile->addError($error, $stackPtr, 'DoubleUnderscore', $errorData);
         return;
     }
     if (Common::isCamelCaps($functionName, false, true, false) === false) {
         $error = 'Function name "%s" is not in camel caps format';
         $phpcsFile->addError($error, $stackPtr, 'NotCamelCaps', $errorData);
     }
 }
Example #5
0
 /**
  * Processes this test when one of its tokens is encountered.
  *
  * @param PHP_CodeSniffer_File $phpcsFile The current file being scanned.
  * @param int                  $stackPtr  The position of the current token
  *                                        in the stack passed in $tokens.
  * @param int                  $currScope A pointer to the start of the scope.
  *
  * @return void
  */
 protected function processTokenWithinScope(File $phpcsFile, $stackPtr, $currScope)
 {
     $className = $phpcsFile->getDeclarationName($currScope);
     if ($className !== $this->currentClass) {
         $this->loadFunctionNamesInScope($phpcsFile, $currScope);
         $this->currentClass = $className;
     }
     $methodName = $phpcsFile->getDeclarationName($stackPtr);
     if (strcasecmp($methodName, $className) === 0) {
         if (in_array('__construct', $this->functionList) === false) {
             $error = 'PHP4 style constructors are not allowed; use "__construct()" instead';
             $phpcsFile->addError($error, $stackPtr, 'OldStyle');
         }
     } else {
         if (strcasecmp($methodName, '__construct') !== 0) {
             // Not a constructor.
             return;
         }
     }
     $tokens = $phpcsFile->getTokens();
     $parentClassName = $phpcsFile->findExtendedClassName($currScope);
     if ($parentClassName === false) {
         return;
     }
     // Stop if the constructor doesn't have a body, like when it is abstract.
     if (isset($tokens[$stackPtr]['scope_closer']) === false) {
         return;
     }
     $endFunctionIndex = $tokens[$stackPtr]['scope_closer'];
     $startIndex = $stackPtr;
     while (($doubleColonIndex = $phpcsFile->findNext(T_DOUBLE_COLON, $startIndex, $endFunctionIndex)) !== false) {
         if ($tokens[$doubleColonIndex + 1]['code'] === T_STRING && $tokens[$doubleColonIndex + 1]['content'] === $parentClassName) {
             $error = 'PHP4 style calls to parent constructors are not allowed; use "parent::__construct()" instead';
             $phpcsFile->addError($error, $doubleColonIndex + 1, 'OldStyleCall');
         }
         $startIndex = $doubleColonIndex + 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();
     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;
     }
 }
Example #7
0
 /**
  * Processes the tokens outside the scope.
  *
  * @param PHP_CodeSniffer_File $phpcsFile The file being processed.
  * @param int                  $stackPtr  The position where this token was
  *                                        found.
  *
  * @return void
  */
 protected function processTokenOutsideScope(File $phpcsFile, $stackPtr)
 {
     $functionName = $phpcsFile->getDeclarationName($stackPtr);
     if ($functionName === null) {
         // Ignore closures.
         return;
     }
     if (ltrim($functionName, '_') === '') {
         // Ignore special functions.
         return;
     }
     $errorData = array($functionName);
     // Is this a magic function. i.e., it is prefixed with "__".
     if (preg_match('|^__|', $functionName) !== 0) {
         $magicPart = strtolower(substr($functionName, 2));
         if (isset($this->magicFunctions[$magicPart]) === false) {
             $error = 'Function name "%s" is invalid; only PHP magic methods should be prefixed with a double underscore';
             $phpcsFile->addError($error, $stackPtr, 'FunctionDoubleUnderscore', $errorData);
         }
         return;
     }
     // Function names can be in two parts; the package name and
     // the function name.
     $packagePart = '';
     $camelCapsPart = '';
     $underscorePos = strrpos($functionName, '_');
     if ($underscorePos === false) {
         $camelCapsPart = $functionName;
     } else {
         $packagePart = substr($functionName, 0, $underscorePos);
         $camelCapsPart = substr($functionName, $underscorePos + 1);
         // We don't care about _'s on the front.
         $packagePart = ltrim($packagePart, '_');
     }
     // If it has a package part, make sure the first letter is a capital.
     if ($packagePart !== '') {
         if ($functionName[0] === '_') {
             $error = 'Function name "%s" is invalid; only private methods should be prefixed with an underscore';
             $phpcsFile->addError($error, $stackPtr, 'FunctionUnderscore', $errorData);
             return;
         }
         if ($functionName[0] !== strtoupper($functionName[0])) {
             $error = 'Function name "%s" is prefixed with a package name but does not begin with a capital letter';
             $phpcsFile->addError($error, $stackPtr, 'FunctionNoCapital', $errorData);
             return;
         }
     }
     // If it doesn't have a camel caps part, it's not valid.
     if (trim($camelCapsPart) === '') {
         $error = 'Function name "%s" is not valid; name appears incomplete';
         $phpcsFile->addError($error, $stackPtr, 'FunctionInvalid', $errorData);
         return;
     }
     $validName = true;
     $newPackagePart = $packagePart;
     $newCamelCapsPart = $camelCapsPart;
     // Every function must have a camel caps part, so check that first.
     if (Common::isCamelCaps($camelCapsPart, false, true, false) === false) {
         $validName = false;
         $newCamelCapsPart = strtolower($camelCapsPart[0]) . substr($camelCapsPart, 1);
     }
     if ($packagePart !== '') {
         // Check that each new word starts with a capital.
         $nameBits = explode('_', $packagePart);
         foreach ($nameBits as $bit) {
             if ($bit[0] !== strtoupper($bit[0])) {
                 $newPackagePart = '';
                 foreach ($nameBits as $bit) {
                     $newPackagePart .= strtoupper($bit[0]) . substr($bit, 1) . '_';
                 }
                 $validName = false;
                 break;
             }
         }
     }
     if ($validName === false) {
         $newName = rtrim($newPackagePart, '_') . '_' . $newCamelCapsPart;
         if ($newPackagePart === '') {
             $newName = $newCamelCapsPart;
         } else {
             $newName = rtrim($newPackagePart, '_') . '_' . $newCamelCapsPart;
         }
         $error = 'Function name "%s" is invalid; consider "%s" instead';
         $data = $errorData;
         $data[] = $newName;
         $phpcsFile->addError($error, $stackPtr, 'FunctionNameInvalid', $data);
     }
 }
 /**
  * Processes the tokens outside the scope.
  *
  * @param PHP_CodeSniffer_File $phpcsFile The file being processed.
  * @param int                  $stackPtr  The position where this token was
  *                                        found.
  *
  * @return void
  */
 protected function processTokenOutsideScope(File $phpcsFile, $stackPtr)
 {
     $functionName = $phpcsFile->getDeclarationName($stackPtr);
     if ($functionName === null) {
         // Ignore closures.
         return;
     }
     $errorData = array($functionName);
     // Is this a magic function. i.e., it is prefixed with "__".
     if (preg_match('|^__|', $functionName) !== 0) {
         $magicPart = strtolower(substr($functionName, 2));
         if (isset($this->magicFunctions[$magicPart]) === false) {
             $error = 'Function name "%s" is invalid; only PHP magic methods should be prefixed with a double underscore';
             $phpcsFile->addError($error, $stackPtr, 'FunctionDoubleUnderscore', $errorData);
         }
         return;
     }
     // Ignore first underscore in functions prefixed with "_".
     $functionName = ltrim($functionName, '_');
     if (Common::isCamelCaps($functionName, false, true, $this->strict) === false) {
         $error = 'Function name "%s" is not in camel caps format';
         $phpcsFile->addError($error, $stackPtr, 'NotCamelCaps', $errorData);
         $phpcsFile->recordMetric($stackPtr, 'CamelCase function name', 'no');
     } else {
         $phpcsFile->recordMetric($stackPtr, 'CamelCase method name', 'yes');
     }
 }
Example #9
0
 /**
  * Process the return comment of this function comment.
  *
  * @param PHP_CodeSniffer_File $phpcsFile    The file being scanned.
  * @param int                  $stackPtr     The position of the current token
  *                                           in the stack passed in $tokens.
  * @param int                  $commentStart The position in the stack where the comment started.
  *
  * @return void
  */
 protected function processReturn(File $phpcsFile, $stackPtr, $commentStart)
 {
     $tokens = $phpcsFile->getTokens();
     // Skip constructor and destructor.
     $methodName = $phpcsFile->getDeclarationName($stackPtr);
     $isSpecialMethod = $methodName === '__construct' || $methodName === '__destruct';
     $return = null;
     foreach ($tokens[$commentStart]['comment_tags'] as $tag) {
         if ($tokens[$tag]['content'] === '@return') {
             if ($return !== null) {
                 $error = 'Only 1 @return tag is allowed in a function comment';
                 $phpcsFile->addError($error, $tag, 'DuplicateReturn');
                 return;
             }
             $return = $tag;
         }
     }
     if ($isSpecialMethod === true) {
         return;
     }
     if ($return !== null) {
         $content = $tokens[$return + 2]['content'];
         if (empty($content) === true || $tokens[$return + 2]['code'] !== T_DOC_COMMENT_STRING) {
             $error = 'Return type missing for @return tag in function comment';
             $phpcsFile->addError($error, $return, 'MissingReturnType');
         }
     } else {
         $error = 'Missing @return tag in function comment';
         $phpcsFile->addError($error, $tokens[$commentStart]['comment_closer'], 'MissingReturn');
     }
     //end if
 }
Example #10
0
 /**
  * Process the return comment of this function comment.
  *
  * @param PHP_CodeSniffer_File $phpcsFile    The file being scanned.
  * @param int                  $stackPtr     The position of the current token
  *                                           in the stack passed in $tokens.
  * @param int                  $commentStart The position in the stack where the comment started.
  *
  * @return void
  */
 protected function processReturn(File $phpcsFile, $stackPtr, $commentStart)
 {
     $tokens = $phpcsFile->getTokens();
     // Skip constructor and destructor.
     $methodName = $phpcsFile->getDeclarationName($stackPtr);
     $isSpecialMethod = $methodName === '__construct' || $methodName === '__destruct';
     $return = null;
     foreach ($tokens[$commentStart]['comment_tags'] as $tag) {
         if ($tokens[$tag]['content'] === '@return') {
             if ($return !== null) {
                 $error = 'Only 1 @return tag is allowed in a function comment';
                 $phpcsFile->addError($error, $tag, 'DuplicateReturn');
                 return;
             }
             $return = $tag;
         }
     }
     if ($isSpecialMethod === true) {
         return;
     }
     if ($return !== null) {
         $content = $tokens[$return + 2]['content'];
         if (empty($content) === true || $tokens[$return + 2]['code'] !== T_DOC_COMMENT_STRING) {
             $error = 'Return type missing for @return tag in function comment';
             $phpcsFile->addError($error, $return, 'MissingReturnType');
         } else {
             // Check return type (can be multiple, separated by '|').
             $typeNames = explode('|', $content);
             $suggestedNames = array();
             foreach ($typeNames as $i => $typeName) {
                 $suggestedName = Common::suggestType($typeName);
                 if (in_array($suggestedName, $suggestedNames) === false) {
                     $suggestedNames[] = $suggestedName;
                 }
             }
             $suggestedType = implode('|', $suggestedNames);
             if ($content !== $suggestedType) {
                 $error = 'Expected "%s" but found "%s" for function return type';
                 $data = array($suggestedType, $content);
                 $fix = $phpcsFile->addFixableError($error, $return, 'InvalidReturn', $data);
                 if ($fix === true) {
                     $phpcsFile->fixer->replaceToken($return + 2, $suggestedType);
                 }
             }
             // Support both a return type and a description. The return type
             // is anything up to the first space.
             $returnParts = explode(' ', $content, 2);
             $returnType = $returnParts[0];
             // If the return type is void, make sure there is
             // no return statement in the function.
             if ($returnType === 'void') {
                 if (isset($tokens[$stackPtr]['scope_closer']) === true) {
                     $endToken = $tokens[$stackPtr]['scope_closer'];
                     for ($returnToken = $stackPtr; $returnToken < $endToken; $returnToken++) {
                         if ($tokens[$returnToken]['code'] === T_CLOSURE) {
                             $returnToken = $tokens[$returnToken]['scope_closer'];
                             continue;
                         }
                         if ($tokens[$returnToken]['code'] === T_RETURN || $tokens[$returnToken]['code'] === T_YIELD) {
                             break;
                         }
                     }
                     if ($returnToken !== $endToken) {
                         // If the function is not returning anything, just
                         // exiting, then there is no problem.
                         $semicolon = $phpcsFile->findNext(T_WHITESPACE, $returnToken + 1, null, true);
                         if ($tokens[$semicolon]['code'] !== T_SEMICOLON) {
                             $error = 'Function return type is void, but function contains return statement';
                             $phpcsFile->addError($error, $return, 'InvalidReturnVoid');
                         }
                     }
                 }
                 //end if
             } else {
                 if ($returnType !== 'mixed') {
                     // If return type is not void, there needs to be a return statement
                     // somewhere in the function that returns something.
                     if (isset($tokens[$stackPtr]['scope_closer']) === true) {
                         $endToken = $tokens[$stackPtr]['scope_closer'];
                         $returnToken = $phpcsFile->findNext(array(T_RETURN, T_YIELD), $stackPtr, $endToken);
                         if ($returnToken === false) {
                             $error = 'Function return type is not void, but function has no return statement';
                             $phpcsFile->addError($error, $return, 'InvalidNoReturn');
                         } else {
                             $semicolon = $phpcsFile->findNext(T_WHITESPACE, $returnToken + 1, null, true);
                             if ($tokens[$semicolon]['code'] === T_SEMICOLON) {
                                 $error = 'Function return type is not void, but function is returning void here';
                                 $phpcsFile->addError($error, $returnToken, 'InvalidReturnNotVoid');
                             }
                         }
                     }
                 }
             }
             //end if
         }
         //end if
     } else {
         $error = 'Missing @return tag in function comment';
         $phpcsFile->addError($error, $tokens[$commentStart]['comment_closer'], 'MissingReturn');
     }
     //end if
 }
Example #11
0
 /**
  * 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.
  * @param int                  $currScope The current scope opener token.
  *
  * @return void
  */
 protected function processTokenWithinScope(File $phpcsFile, $stackPtr, $currScope)
 {
     $tokens = $phpcsFile->getTokens();
     $methodName = $phpcsFile->getDeclarationName($stackPtr);
     if ($methodName === null) {
         // Ignore closures.
         return;
     }
     if ($methodName[0] === '_' && isset($methodName[1]) === true && $methodName[1] !== '_') {
         $error = 'Method name "%s" should not be prefixed with an underscore to indicate visibility';
         $data = array($methodName);
         $phpcsFile->addWarning($error, $stackPtr, 'Underscore', $data);
     }
     $visibility = 0;
     $static = 0;
     $abstract = 0;
     $final = 0;
     $find = Tokens::$methodPrefixes;
     $find[] = T_WHITESPACE;
     $prev = $phpcsFile->findPrevious($find, $stackPtr - 1, null, true);
     $prefix = $stackPtr;
     while (($prefix = $phpcsFile->findPrevious(Tokens::$methodPrefixes, $prefix - 1, $prev)) !== false) {
         switch ($tokens[$prefix]['code']) {
             case T_STATIC:
                 $static = $prefix;
                 break;
             case T_ABSTRACT:
                 $abstract = $prefix;
                 break;
             case T_FINAL:
                 $final = $prefix;
                 break;
             default:
                 $visibility = $prefix;
                 break;
         }
     }
     $fixes = array();
     if ($visibility !== 0 && $final > $visibility) {
         $error = 'The final declaration must precede the visibility declaration';
         $fix = $phpcsFile->addFixableError($error, $final, 'FinalAfterVisibility');
         if ($fix === true) {
             $fixes[$final] = '';
             $fixes[$final + 1] = '';
             if (isset($fixes[$visibility]) === true) {
                 $fixes[$visibility] = 'final ' . $fixes[$visibility];
             } else {
                 $fixes[$visibility] = 'final ' . $tokens[$visibility]['content'];
             }
         }
     }
     if ($visibility !== 0 && $abstract > $visibility) {
         $error = 'The abstract declaration must precede the visibility declaration';
         $fix = $phpcsFile->addFixableError($error, $abstract, 'AbstractAfterVisibility');
         if ($fix === true) {
             $fixes[$abstract] = '';
             $fixes[$abstract + 1] = '';
             if (isset($fixes[$visibility]) === true) {
                 $fixes[$visibility] = 'abstract ' . $fixes[$visibility];
             } else {
                 $fixes[$visibility] = 'abstract ' . $tokens[$visibility]['content'];
             }
         }
     }
     if ($static !== 0 && $static < $visibility) {
         $error = 'The static declaration must come after the visibility declaration';
         $fix = $phpcsFile->addFixableError($error, $static, 'StaticBeforeVisibility');
         if ($fix === true) {
             $fixes[$static] = '';
             $fixes[$static + 1] = '';
             if (isset($fixes[$visibility]) === true) {
                 $fixes[$visibility] = $fixes[$visibility] . ' static';
             } else {
                 $fixes[$visibility] = $tokens[$visibility]['content'] . ' static';
             }
         }
     }
     // Batch all the fixes together to reduce the possibility of conflicts.
     if (empty($fixes) === false) {
         $phpcsFile->fixer->beginChangeset();
         foreach ($fixes as $stackPtr => $content) {
             $phpcsFile->fixer->replaceToken($stackPtr, $content);
         }
         $phpcsFile->fixer->endChangeset();
     }
 }
 /**
  * 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 function without body.
     if (isset($token['scope_opener']) === false) {
         return;
     }
     // Get function name.
     $methodName = $phpcsFile->getDeclarationName($stackPtr);
     // Get all parameters from method signature.
     $signature = array();
     foreach ($phpcsFile->getMethodParameters($stackPtr) as $param) {
         $signature[] = $param['name'];
     }
     $next = ++$token['scope_opener'];
     $end = --$token['scope_closer'];
     for (; $next <= $end; ++$next) {
         $code = $tokens[$next]['code'];
         if (isset(Tokens::$emptyTokens[$code]) === true) {
             continue;
         } else {
             if ($code === T_RETURN) {
                 continue;
             }
         }
         break;
     }
     // Any token except 'parent' indicates correct code.
     if ($tokens[$next]['code'] !== T_PARENT) {
         return;
     }
     // Find next non empty token index, should be double colon.
     $next = $phpcsFile->findNext(Tokens::$emptyTokens, $next + 1, null, true);
     // Skip for invalid code.
     if ($next === false || $tokens[$next]['code'] !== T_DOUBLE_COLON) {
         return;
     }
     // Find next non empty token index, should be the function name.
     $next = $phpcsFile->findNext(Tokens::$emptyTokens, $next + 1, null, true);
     // Skip for invalid code or other method.
     if ($next === false || $tokens[$next]['content'] !== $methodName) {
         return;
     }
     // Find next non empty token index, should be the open parenthesis.
     $next = $phpcsFile->findNext(Tokens::$emptyTokens, $next + 1, null, true);
     // Skip for invalid code.
     if ($next === false || $tokens[$next]['code'] !== T_OPEN_PARENTHESIS) {
         return;
     }
     $validParameterTypes = array(T_VARIABLE, T_LNUMBER, T_CONSTANT_ENCAPSED_STRING);
     $parameters = array('');
     $parenthesisCount = 1;
     $count = count($tokens);
     for (++$next; $next < $count; ++$next) {
         $code = $tokens[$next]['code'];
         if ($code === T_OPEN_PARENTHESIS) {
             ++$parenthesisCount;
         } else {
             if ($code === T_CLOSE_PARENTHESIS) {
                 --$parenthesisCount;
             } else {
                 if ($parenthesisCount === 1 && $code === T_COMMA) {
                     $parameters[] = '';
                 } else {
                     if (isset(Tokens::$emptyTokens[$code]) === false) {
                         $parameters[count($parameters) - 1] .= $tokens[$next]['content'];
                     }
                 }
             }
         }
         if ($parenthesisCount === 0) {
             break;
         }
     }
     //end for
     $next = $phpcsFile->findNext(Tokens::$emptyTokens, $next + 1, null, true);
     if ($next === false || $tokens[$next]['code'] !== T_SEMICOLON) {
         return;
     }
     // Check rest of the scope.
     for (++$next; $next <= $end; ++$next) {
         $code = $tokens[$next]['code'];
         // Skip for any other content.
         if (isset(Tokens::$emptyTokens[$code]) === false) {
             return;
         }
     }
     $parameters = array_map('trim', $parameters);
     $parameters = array_filter($parameters);
     if (count($parameters) === count($signature) && $parameters === $signature) {
         $phpcsFile->addWarning('Possible useless method overriding detected', $stackPtr, 'Found');
     }
 }