Processes the closing section of a class declaration.

@param File $phpcsFile The file being scanned.
@param int  $stackPtr  The position of the current token
in the stack passed in $tokens.

@return void
198948
public function processClose(File $phpcsFile, $stackPtr)
    {
        $tokens = $phpcsFile->getTokens();

        // Just in case.
        if (isset($tokens[$stackPtr]['scope_closer']) === false) {
            return;
        }

        $closeBrace = $tokens[$stackPtr]['scope_closer'];
        if ($tokens[($closeBrace - 1)]['code'] === T_WHITESPACE) {
            $prevContent = $tokens[($closeBrace - 1)]['content'];
            if ($prevContent !== $phpcsFile->eolChar) {
                $blankSpace = substr($prevContent, strpos($prevContent, $phpcsFile->eolChar));
                $spaces     = strlen($blankSpace);
                if ($spaces !== 0) {
                    if ($tokens[($closeBrace - 1)]['line'] !== $tokens[$closeBrace]['line']) {
                        $error = 'Expected 0 spaces before closing brace; newline found';
                        $fix   = $phpcsFile->addFixableError($error, $closeBrace, 'NewLineBeforeCloseBrace');
                    } else {
                        $error = 'Expected 0 spaces before closing brace; %s found';
                        $data  = array($spaces);
                        $fix   = $phpcsFile->addFixableError($error, $closeBrace, 'SpaceBeforeCloseBrace', $data);
                    }//end if

                    if ($fix === true) {
                        $phpcsFile->fixer->beginChangeset();
                        $phpcsFile->fixer->replaceToken(($closeBrace - 1), '');
                        $phpcsFile->fixer->endChangeset();
                    }
                }//end if
            }//end if
        }//end if

        // Check that the closing brace has one blank line after it.
        $nextContent = $phpcsFile->findNext(array(T_WHITESPACE), ($closeBrace + 1), null, true);
        if ($nextContent !== false) {
            $difference = ($tokens[$nextContent]['line'] - $tokens[$closeBrace]['line'] - 1);
            if ($difference < 0) {
                $difference = 0;
            }

            if ($difference !== 1) {
                $error = 'Closing brace of a %s must be followed by a single blank line; found %s';
                $data  = array(
                          $tokens[$stackPtr]['content'],
                          $difference,
                         );
                $fix   = $phpcsFile->addFixableError($error, $closeBrace, 'NewlinesAfterCloseBrace', $data);
                if ($fix === true) {
                    $phpcsFile->fixer->beginChangeset();

                    if ($difference > 1) {
                        for ($i = ($closeBrace + 1); $i < $nextContent; $i++) {
                            if ($tokens[$i]['line'] === $tokens[$nextContent]['line']) {
                                // Keep existing indentation.
                                break;
                            }

                            $phpcsFile->fixer->replaceToken($i, '');
                        }
                    }

                    $phpcsFile->fixer->addNewline($closeBrace);
                    $phpcsFile->fixer->endChangeset();
                }
            }//end if
        }//end if
    }
792263
public function process(File $phpcsFile, $stackPtr)
    {
        if ($this->supportsBelow('5.4') === false) {
            return;
        }

        $tokens         = $phpcsFile->getTokens();
        $tokenContentLC = strtolower($tokens[$stackPtr]['content']);

        if ($tokenContentLC !== $tokens[$stackPtr]['content']) {
            $phpcsFile->addError(
                'The keyword \'%s\' was treated in a case-sensitive fashion in certain cases in PHP 5.4 or earlier. Use the lowercase version for consistent support.',
                $stackPtr,
                'NonLowercaseFound',
                array($tokenContentLC)
            );
        }
    }
150545
public function process(File $phpcsFile, $stackPtr)
    {
        if ($this->supportsBelow('7.0') === false) {
            return;
        }

        $tokens = $phpcsFile->getTokens();
        $token  = $tokens[$stackPtr];

        // Bow out during live coding.
        if (isset($token['parenthesis_opener'], $token['parenthesis_closer']) === false) {
            return;
        }

        $hasBitwiseOr = $phpcsFile->findNext(\T_BITWISE_OR, $token['parenthesis_opener'], $token['parenthesis_closer']);

        if ($hasBitwiseOr === false) {
            return;
        }

        $phpcsFile->addError(
            'Catching multiple exceptions within one statement is not supported in PHP 7.0 or earlier.',
            $hasBitwiseOr,
            'Found'
        );
    }
640418
public function process(File $phpcsFile, $stackPtr)
    {
        $tokens = $phpcsFile->getTokens();

        $end = null;
        if (isset($tokens[$stackPtr]['scope_closer'])) {
            $end = $tokens[$stackPtr]['scope_closer'];
        }

        $scope = $phpcsFile->findNext(
            T_FUNCTION,
            $stackPtr,
            $end
        );

        $wantedTokens = array(
            T_PUBLIC,
            T_PROTECTED,
            T_PRIVATE
        );

        while ($scope) {
            $scope = $phpcsFile->findNext(
                $wantedTokens,
                $scope + 1,
                $end
            );

            if ($scope && $tokens[$scope + 2]['code'] === T_VARIABLE) {
                $phpcsFile->addError(
                    'Declare class properties before methods',
                    $scope,
                    'Invalid'
                );
            }
        }
    }
148848
public function process(File $phpcsFile, $stackPtr)
    {
        $this->requiredSpacesAfterOpen   = (int) $this->requiredSpacesAfterOpen;
        $this->requiredSpacesBeforeClose = (int) $this->requiredSpacesBeforeClose;
        $tokens = $phpcsFile->getTokens();

        $this->checkBracketSpacing($phpcsFile, $stackPtr);

        if (isset($tokens[$stackPtr]['scope_closer']) === false) {
            return;
        }

        $this->checkContentInside($phpcsFile, $stackPtr);
        $this->checkLeadingContent($phpcsFile, $stackPtr);
        $this->checkTrailingContent($phpcsFile, $stackPtr);
    }
656867
public function process(File $phpcsFile, $stackPtr)
    {
        if ($this->supportsBelow('7.0') === false) {
            return;
        }

        if ($this->isShortList($phpcsFile, $stackPtr) === false) {
            return;
        }

        $tokens = $phpcsFile->getTokens();
        $closer = $tokens[$stackPtr]['bracket_closer'];

        $hasVariable = $phpcsFile->findNext(\T_VARIABLE, ($stackPtr + 1), $closer);
        if ($hasVariable === false) {
            // List syntax is only valid if there are variables in it.
            return;
        }

        $phpcsFile->addError(
            'The shorthand list syntax "[]" to destructure arrays is not available in PHP 7.0 or earlier.',
            $stackPtr,
            'Found'
        );

        return ($closer + 1);
    }
321806
public function process(File $phpcsFile, $stackPtr)
    {
        $tokens     = $phpcsFile->getTokens();
        $functionLc = strtolower($tokens[$stackPtr]['content']);
        if (isset($this->targetFunctions[$functionLc]) === false) {
            return;
        }

        // Next non-empty token should be the open parenthesis.
        $nextNonEmpty = $phpcsFile->findNext(Tokens::$emptyTokens, ($stackPtr + 1), null, true, null, true);
        if ($nextNonEmpty === false || $tokens[$nextNonEmpty]['code'] !== \T_OPEN_PARENTHESIS) {
            return;
        }

        $ignore = array(
            \T_DOUBLE_COLON    => true,
            \T_OBJECT_OPERATOR => true,
            \T_FUNCTION        => true,
            \T_NEW             => true,
        );

        $prevNonEmpty = $phpcsFile->findPrevious(Tokens::$emptyTokens, ($stackPtr - 1), null, true);
        if (isset($ignore[$tokens[$prevNonEmpty]['code']]) === true) {
            // Not a call to a PHP function.
            return;
        } elseif ($tokens[$prevNonEmpty]['code'] === \T_NS_SEPARATOR && $tokens[$prevNonEmpty - 1]['code'] === \T_STRING) {
            // Namespaced function.
            return;
        }

        $data = $tokens[$stackPtr]['content'];

        /*
         * Check for usage of the functions in the global scope.
         *
         * As PHPCS can not determine whether a file is included from within a function in
         * another file, so always throw a warning/error.
         */
        if ($phpcsFile->hasCondition($stackPtr, array(\T_FUNCTION, \T_CLOSURE)) === false) {
            $isError = false;
            $message = 'Use of %s() outside of a user-defined function is only supported if the file is included from within a user-defined function in another file prior to PHP 5.3.';

            if ($this->supportsAbove('5.3') === true) {
                $isError  = true;
                $message .= ' As of PHP 5.3, it is no longer supported at all.';
            }

            $this->addMessage($phpcsFile, $message, $stackPtr, $isError, 'OutsideFunctionScope', $data);
        }

        /*
         * Check for usage of the functions as a parameter in a function call.
         */
        if ($this->supportsBelow('5.2') === false) {
            return;
        }

        if (isset($tokens[$stackPtr]['nested_parenthesis']) === false) {
            return;
        }

        $throwError = false;

        $closer = end($tokens[$stackPtr]['nested_parenthesis']);
        if (isset($tokens[$closer]['parenthesis_owner'])
            && $tokens[$tokens[$closer]['parenthesis_owner']]['type'] === 'T_CLOSURE'
        ) {
            $throwError = true;
        } else {
            $opener       = key($tokens[$stackPtr]['nested_parenthesis']);
            $prevNonEmpty = $phpcsFile->findPrevious(Tokens::$emptyTokens, ($opener - 1), null, true);
            if ($tokens[$prevNonEmpty]['code'] !== \T_STRING) {
                return;
            }

            $prevPrevNonEmpty = $phpcsFile->findPrevious(Tokens::$emptyTokens, ($prevNonEmpty - 1), null, true);
            if ($tokens[$prevPrevNonEmpty]['code'] === \T_FUNCTION) {
                return;
            }

            $throwError = true;
        }

        if ($throwError === false) {
            return;
        }

        $phpcsFile->addError(
            '%s() could not be used in parameter lists prior to PHP 5.3.',
            $stackPtr,
            'InParameterList',
            $data
        );
    }
1302999
public function process(File $phpcsFile, $stackPtr)
    {
        if ($this->supportsBelow('5.3') === false) {
            return;
        }

        $tokens = $phpcsFile->getTokens();

        // Next non-empty token should be the open parenthesis.
        $openParenthesis = $phpcsFile->findNext(Tokens::$emptyTokens, ($stackPtr + 1), null, true, null, true);
        if ($openParenthesis === false || $tokens[$openParenthesis]['code'] !== \T_OPEN_PARENTHESIS) {
            return;
        }

        // Don't throw errors during live coding.
        if (isset($tokens[$openParenthesis]['parenthesis_closer']) === false) {
            return;
        }

        // Is this T_STRING really a function or method call ?
        $prevToken = $phpcsFile->findPrevious(Tokens::$emptyTokens, ($stackPtr - 1), null, true);
        if ($prevToken !== false && \in_array($tokens[$prevToken]['code'], array(\T_DOUBLE_COLON, \T_OBJECT_OPERATOR), true) === false) {
            $ignore = array(
                \T_FUNCTION  => true,
                \T_CONST     => true,
                \T_USE       => true,
                \T_NEW       => true,
                \T_CLASS     => true,
                \T_INTERFACE => true,
            );

            if (isset($ignore[$tokens[$prevToken]['code']]) === true) {
                // Not a call to a PHP function or method.
                return;
            }
        }

        $closeParenthesis = $tokens[$openParenthesis]['parenthesis_closer'];
        $nextNonEmpty     = $phpcsFile->findNext(Tokens::$emptyTokens, ($closeParenthesis + 1), null, true, null, true);
        if ($nextNonEmpty !== false && $tokens[$nextNonEmpty]['type'] === 'T_OPEN_SQUARE_BRACKET') {
            $phpcsFile->addError(
                'Function array dereferencing is not present in PHP version 5.3 or earlier',
                $nextNonEmpty,
                'Found'
            );
        }
    }
834171
public function process(File $phpcsFile, $stackPtr)
    {
        $tokens = $phpcsFile->getTokens();

        if ($tokens[($stackPtr - 1)]['code'] === T_WHITESPACE
            && $tokens[($stackPtr - 2)]['line'] === $tokens[$stackPtr]['line']
        ) {
            $error = 'Space found before object operator';
            $fix   = $phpcsFile->addFixableError($error, $stackPtr, 'Before');
            if ($fix === true) {
                $phpcsFile->fixer->replaceToken(($stackPtr - 1), '');
            }
        }

        if ($tokens[($stackPtr + 1)]['code'] === T_WHITESPACE
            && $tokens[($stackPtr + 2)]['line'] === $tokens[$stackPtr]['line']
        ) {
            $error = 'Space found after object operator';
            $fix   = $phpcsFile->addFixableError($error, $stackPtr, 'After');
            if ($fix === true) {
                $phpcsFile->fixer->replaceToken(($stackPtr + 1), '');
            }
        }
    }
666059
public function process(File $phpcsFile, $stackPtr)
    {
        if ($this->supportsBelow('5.4') === false) {
            return;
        }

        $tokens = $phpcsFile->getTokens();

        if (isset($tokens[$stackPtr]['parenthesis_opener'], $tokens[$stackPtr]['parenthesis_closer']) === false) {
            return;
        }

        $opener = $tokens[$stackPtr]['parenthesis_opener'];
        $closer = $tokens[$stackPtr]['parenthesis_closer'];

        $asToken = $phpcsFile->findNext(\T_AS, ($opener + 1), $closer);
        if ($asToken === false) {
            return;
        }

        $hasList = $phpcsFile->findNext(array(\T_LIST, \T_OPEN_SHORT_ARRAY), ($asToken + 1), $closer);
        if ($hasList === false) {
            return;
        }

        $phpcsFile->addError(
            'Unpacking nested arrays with list() in a foreach is not supported in PHP 5.4 or earlier.',
            $hasList,
            'Found'
        );
    }
724912
public function process(File $phpcsFile, $stackPtr)
    {
        $algo = $this->getHashAlgorithmParameter($phpcsFile, $stackPtr);
        if (empty($algo) || \is_string($algo) === false) {
            return;
        }

        // Bow out if not one of the algorithms we're targetting.
        if (isset($this->newAlgorithms[$algo]) === false) {
            return;
        }

        // Check if the algorithm used is new.
        $itemInfo = array(
            'name'   => $algo,
        );
        $this->handleFeature($phpcsFile, $stackPtr, $itemInfo);
    }
138727
public function process(File $phpcsFile, $stackPtr)
    {
        if ($this->bowOutEarly() === true) {
            return;
        }

        $tokens = $phpcsFile->getTokens();

        if ($tokens[$stackPtr]['code'] === \T_OPEN_SHORT_ARRAY
            && $this->isShortList($phpcsFile, $stackPtr) === false
        ) {
            // Short array, not short list.
            return;
        }

        if ($tokens[$stackPtr]['code'] === \T_LIST) {
            $nextNonEmpty = $phpcsFile->findNext(Tokens::$emptyTokens, ($stackPtr + 1), null, true);
            if ($nextNonEmpty === false
                || $tokens[$nextNonEmpty]['code'] !== \T_OPEN_PARENTHESIS
                || isset($tokens[$nextNonEmpty]['parenthesis_closer']) === false
            ) {
                // Parse error or live coding.
                return;
            }

            $opener = $nextNonEmpty;
            $closer = $tokens[$nextNonEmpty]['parenthesis_closer'];
        } else {
            // Short list syntax.
            $opener = $stackPtr;

            if (isset($tokens[$stackPtr]['bracket_closer'])) {
                $closer = $tokens[$stackPtr]['bracket_closer'];
            }
        }

        if (isset($opener, $closer) === false) {
            return;
        }

        $this->examineList($phpcsFile, $opener, $closer);
    }
562782
public function process(File $phpcsFile, $stackPtr)
    {
        $tokens = $phpcsFile->getTokens();

        // In case we have more than one class/interface/trait
        // per file, we want to reset at the start of each.
        if ($tokens[$stackPtr]['code'] !== T_FUNCTION) {
            $this->lastMethodName = null;
            return;
        }

        // We only care about class methods, so ignore global functions (level 0).
        if ($tokens[$stackPtr]['level'] === 1) {
            $methodName = $phpcsFile->getDeclarationName($stackPtr);
            if ($this->lastMethodName !== null && $methodName <= $this->lastMethodName) {
                $phpcsFile->addError('Method "%s" is not in alphabetical order.', $stackPtr, 'OutOfOrder', [$methodName]);
            }

            $this->lastMethodName = $methodName;
        }

    }
14156
public function process(File $phpcsFile, $stackPtr)
    {
        $tokens = $phpcsFile->getTokens();

        if ($tokens[$stackPtr]['code'] === T_COMMENT) {
            $this->processComment($phpcsFile, $stackPtr);
        } elseif ($tokens[$stackPtr]['code'] === T_DOC_COMMENT_OPEN_TAG) {
            $this->processDocBlock($phpcsFile, $stackPtr);
        }
    }
89643
public function process(File $phpcsFile, $stackPtr)
    {
        $tokens    = $phpcsFile->getTokens();
        $tokenType = $tokens[$stackPtr]['type'];

        $itemInfo = array(
            'name'        => $tokenType,
            'description' => $this->deprecatedTypeCasts[$tokenType]['description'],
        );
        $this->handleFeature($phpcsFile, $stackPtr, $itemInfo);
    }
17486
public function process(File $phpcsFile, $stackPtr)
    {
        if ($this->supportsAbove('5.3') === false) {
            return;
        }

        $tokens  = $phpcsFile->getTokens();
        $varName = substr($tokens[$stackPtr]['content'], 1);

        if (isset($this->removedGlobalVariables[$varName]) === false) {
            return;
        }

        if ($this->isClassProperty($phpcsFile, $stackPtr) === true) {
            // Ok, so this was a class property declaration, not our concern.
            return;
        }

        // Check for static usage of class properties shadowing the removed global variables.
        if ($this->inClassScope($phpcsFile, $stackPtr, false) === true) {
            $prevToken = $phpcsFile->findPrevious(Tokens::$emptyTokens, ($stackPtr - 1), null, true, null, true);
            if ($prevToken !== false && $tokens[$prevToken]['code'] === \T_DOUBLE_COLON) {
                return;
            }
        }

        // Do some additional checks for the $php_errormsg variable.
        if ($varName === 'php_errormsg'
            && $this->isTargetPHPErrormsgVar($phpcsFile, $stackPtr, $tokens) === false
        ) {
            return;
        }

        // Still here, so throw an error/warning.
        $itemInfo = array(
            'name' => $varName,
        );
        $this->handleFeature($phpcsFile, $stackPtr, $itemInfo);
    }
123203
public function process(File $phpcsFile, $stackPtr)
    {
        if ($this->supportsAbove('7.0') === false) {
            return;
        }

        $tokens = $phpcsFile->getTokens();
        $token  = $tokens[$stackPtr];
        // Skip function without body.
        if (isset($token['scope_opener']) === false) {
            return;
        }

        // Get all parameters from method signature.
        $parameters = PHPCSHelper::getMethodParameters($phpcsFile, $stackPtr);
        if (empty($parameters) || \is_array($parameters) === false) {
            return;
        }

        $paramNames = array();
        foreach ($parameters as $param) {
            $paramNames[] = strtolower($param['name']);
        }

        if (\count($paramNames) !== \count(array_unique($paramNames))) {
            $phpcsFile->addError(
                'Functions can not have multiple parameters with the same name since PHP 7.0',
                $stackPtr,
                'Found'
            );
        }
    }