@param \PHP_CodeSniffer\Files\File $phpCsFile
@param int $stackPointer

@return bool
787
protected function hasMethodAnnotation(File $phpCsFile, int $stackPointer): bool
    {
        $position = $phpCsFile->findPrevious(T_DOC_COMMENT_CLOSE_TAG, $stackPointer);
        $tokens = $phpCsFile->getTokens();

        while ($position !== false) {
            $position = $phpCsFile->findPrevious(T_DOC_COMMENT_TAG, $position);

            if ($position !== false) {
                if (strpos($tokens[$position + 2]['content'], $this->getMethodName() . '()') !== false) {
                    return true;
                }

                $position--;
            }
        }

        return false;
    }
851011
protected function hasTrailingComparison(File $phpcsFile, int $stackPtr): bool
    {
        $next = $phpcsFile->findNext(T_WHITESPACE, ($stackPtr + 1), null, true);

        return $this->isComparison($phpcsFile, $next);
    }
613991
protected function assertNewLineAtTheBeginning(File $phpCsFile, int $stackPointer): void
    {
        $tokens = $phpCsFile->getTokens();

        $line = $tokens[$stackPointer]['line'];
        $firstTokenInLineIndex = $stackPointer;
        while ($tokens[$firstTokenInLineIndex - 1]['line'] === $line) {
            $firstTokenInLineIndex--;
        }

        $prevContentIndex = $phpCsFile->findPrevious(T_WHITESPACE, $firstTokenInLineIndex - 1, null, true);
        if ($tokens[$prevContentIndex]['type'] === 'T_DOC_COMMENT_CLOSE_TAG') {
            $firstTokenInLineIndex = $tokens[$prevContentIndex]['comment_opener'];
            while ($tokens[$firstTokenInLineIndex - 1]['line'] === $line) {
                $firstTokenInLineIndex--;
            }
        }

        $prevContentIndex = $phpCsFile->findPrevious(T_WHITESPACE, $firstTokenInLineIndex - 1, null, true);

        // Do not mess with the start of the class
        if ($tokens[$prevContentIndex]['type'] === 'T_OPEN_CURLY_BRACKET') {
            return;
        }

        if ($tokens[$prevContentIndex]['line'] < $tokens[$firstTokenInLineIndex]['line'] - 1) {
            return;
        }

        $fix = $phpCsFile->addFixableError('Every function/method needs a newline before', $firstTokenInLineIndex, 'Concrete');
        if ($fix) {
            $phpCsFile->fixer->addNewline($prevContentIndex);
        }
    }
1330367
protected function hasWrongContent(File $phpCsFile, int $stackPointer): bool
    {
        $fileDockBlockTokens = $this->getFileDocBlockTokens($phpCsFile, $stackPointer);

        $firstLineComment = $fileDockBlockTokens[static::FIRST_COMMENT_LINE_POSITION]['content'];
        $secondLineComment = $fileDockBlockTokens[static::SECOND_COMMENT_LINE_POSITION]['content'];

        if ($firstLineComment !== sprintf(static::EXPECTED_COMMENT_FIRST_LINE_STRING, static::YEAR)
            || $secondLineComment !== static::EXPECTED_COMMENT_SECOND_LINE_STRING) {
            return true;
        }

        return false;
    }
684335
protected function checkCustomFileDocBlock(File $phpCsFile, int $stackPointer): void
    {
        $path = str_replace(getcwd(), '', $phpCsFile->getFilename());
        if (strpos($path, DIRECTORY_SEPARATOR . 'vendor' . DIRECTORY_SEPARATOR) === 0) {
            $pathArray = explode(DIRECTORY_SEPARATOR, substr($path, 8));

            $path = getcwd() . DIRECTORY_SEPARATOR . 'vendor' . DIRECTORY_SEPARATOR
                . array_shift($pathArray) . DIRECTORY_SEPARATOR . array_shift($pathArray) . DIRECTORY_SEPARATOR;
        } else {
            $path = getcwd() . DIRECTORY_SEPARATOR;
        }

        $license = $this->getLicense($path);
        if (!$license) {
            return;
        }

        if (!$this->existsFileDocBlock($phpCsFile, $stackPointer)) {
            $fix = $phpCsFile->addFixableError('No file doc block', $stackPointer, 'CustomFileDocBlockMissing');
            if ($fix) {
                $this->addFileDocBlock($phpCsFile, 0);
            }
            return;
        }

        $this->assertNewlineBefore($phpCsFile, $stackPointer);

        if ($this->isCustomFileDocBlock($phpCsFile, $stackPointer, $license)) {
            return;
        }

        $fix = $phpCsFile->addFixableError('Wrong file doc block', $stackPointer, 'CustomFileDocBlockWrong');
        if ($fix) {
            $this->addCustomFileDocBlock($phpCsFile, 0, $license);
        }
    }
466634
protected function addFixableMissingDocBlock(File $phpCsFile, int $stackPointer): void
    {
        $fix = $phpCsFile->addFixableError('No file doc block', $stackPointer, 'FileDocBlockMissing');
        if ($fix) {
            $this->addFileDocBlock($phpCsFile, 0);
        }
    }
233242
public function process(File $phpcsFile, $stackPtr)
    {
        $tokens = $phpcsFile->getTokens();

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

        $scopeOpener = $tokens[$stackPtr]['scope_opener'];
        $scopeCloser = $tokens[$stackPtr]['scope_closer'];

        $trailingContent = $phpcsFile->findNext(
            array( T_WHITESPACE, T_COMMENT ),
            ($scopeCloser + 1),
            null,
            true
        );

        // Ignore if the next token is ELSE or ELSEIF, which means this is a IF/ELSEIF/ELSE block
        // Also, if it's a another closing bracket, this is OK, as we are closing a nesting of blocks
        if (in_array($tokens[$trailingContent]['code'], array(T_ELSE, T_ELSEIF, T_CLOSE_CURLY_BRACKET))) {
            return;
        }

        if ($tokens[$trailingContent]['line'] === ($tokens[$scopeCloser]['line'] + 1)) {
            $error = 'No blank line found after control structure';
            $phpcsFile->addError($error, $scopeCloser, 'NeedBlankLineAfterControlStruct');
        }
    }
903361
public function process(File $phpcsFile, $stackPointer)
    {
        $tokens       = $phpcsFile->getTokens();
        $currentToken = $tokens[$stackPointer];

        $closingParenthesisCandidate = $currentToken['parenthesis_closer'];
        $whitespaceCandidate         = $tokens[$closingParenthesisCandidate - 1];
        $linebreakCandidate          = $tokens[$closingParenthesisCandidate - 2];
        $commaCandidate              = $tokens[$closingParenthesisCandidate - 3];

        $hasClosingParenthesis = ($tokens[$closingParenthesisCandidate]['type'] === 'T_CLOSE_PARENTHESIS'
            && $whitespaceCandidate['type'] === 'T_WHITESPACE');

        $hasLinebreakBeforeClosingParenthesis = ($linebreakCandidate['type'] === 'T_WHITESPACE'
            && $linebreakCandidate['content'] === chr(10));

        $hasCommaAfterLastElement = $commaCandidate['type'] === 'T_COMMA';

        if ($hasClosingParenthesis && $hasLinebreakBeforeClosingParenthesis && !$hasCommaAfterLastElement)
        {
            $type  = 'Production.LastArrayElementComma.ArrayElementWithoutComma';
            $data  = $commaCandidate['content'];
            $error = 'Array element without comma: ' . $commaCandidate['line'];
            $phpcsFile->addWarning($error, $closingParenthesisCandidate - 3, $type, $data);
        }
    }
252063
protected function findApiAnnotationIndex(File $phpCsFile, int $stackPointer): ?int
    {
        $docCommentOpenerPosition = $phpCsFile->findPrevious(T_DOC_COMMENT_OPEN_TAG, $stackPointer);
        if (!$docCommentOpenerPosition) {
            return null;
        }

        $docCommentClosingPosition = $phpCsFile->findNext(T_DOC_COMMENT_CLOSE_TAG, $docCommentOpenerPosition);

        $tokens = $phpCsFile->getTokens();

        for ($i = $docCommentOpenerPosition + 1; $i < $docCommentClosingPosition; $i++) {
            $docCommentToken = $tokens[$i];
            if ($docCommentToken['type'] === 'T_DOC_COMMENT_TAG' && $docCommentToken['content'] === '@api') {
                return $i;
            }
        }

        return null;
    }
1183802
public function process(File $phpcsFile, $stackPtr)
    {
        if ($this->supportsAbove('5.4') === false) {
            return;
        }

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

        foreach ($parameters as $param) {
            if (isset($this->superglobals[$param['name']]) === true) {
                $error     = 'Parameter shadowing super global (%s) causes fatal error since PHP 5.4';
                $errorCode = $this->stringToErrorCode(substr($param['name'], 1)) . 'Found';
                $data      = array($param['name']);

                $phpcsFile->addError($error, $param['token'], $errorCode, $data);
            }
        }
    }
507774
protected function isStaticMethod(File $phpCsFile, int $stackPointer): bool
    {
        $tokens = $phpCsFile->getTokens();

        if (!in_array($tokens[$stackPointer]['code'], [T_FUNCTION])) {
            return false;
        }

        $methodProperties = $phpCsFile->getMethodProperties($stackPointer);

        return $methodProperties['is_static'];
    }
861820
protected function checkAnnotations(File $phpCsFile, int $stackPointer): void
    {
        $tokens = $phpCsFile->getTokens();

        $docBlockEndIndex = $this->findRelatedDocBlock($phpCsFile, $stackPointer);
        if (!$docBlockEndIndex) {
            return;
        }
        $docBlockStartIndex = $tokens[$docBlockEndIndex]['comment_opener'];
        if (!$docBlockStartIndex) {
            return;
        }

        $methodAnnotations = $this->getFixableMethodAnnotations($phpCsFile, $docBlockStartIndex, $docBlockEndIndex);
        if (!$methodAnnotations) {
            return;
        }

        foreach ($methodAnnotations as $methodAnnotation) {
            $fixable = $phpCsFile->addFixableError(
                sprintf('Interface must be used for %s annotation of %s', $methodAnnotation['method'], $methodAnnotation['class']),
                $methodAnnotation['index'],
                'Annotation.Interface.Invalid'
            );
            if (!$fixable) {
                continue;
            }

            $content = $methodAnnotation['interface'] . ' ' . $methodAnnotation['method'];

            $phpCsFile->fixer->beginChangeset();
            $phpCsFile->fixer->replaceToken($methodAnnotation['index'] + 2, $content);
            $phpCsFile->fixer->endChangeset();
        }
    }
1199781
public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr)
    {
        $tokens = $phpcsFile->getTokens();

        if (isset($tokens[$stackPtr]['scope_opener']) === false && $tokens[$stackPtr]['code'] !== T_RETURN)
        {
            return;
        }

        $prev = $phpcsFile->findPrevious([T_SEMICOLON, T_CLOSE_CURLY_BRACKET], ($stackPtr - 1), null, false);

        if ($tokens[$stackPtr]['line'] - 1 === $tokens[$prev]['line'])
        {
            $error = 'Please consider an empty line before the %s statement;';
            $data  = [$tokens[$stackPtr]['content']];
            $fix   = $phpcsFile->addFixableError($error, $stackPtr, 'SpaceBefore', $data);

            if ($fix === true)
            {
                $phpcsFile->fixer->addNewlineBefore($stackPtr);
            }
        }
    }
412945
public function process(File $phpcsFile, $stackPointer)
    {
        $tokens  = $phpcsFile->getTokens();
        $content = $tokens[$stackPointer]['content'];
        if (preg_match('/@ *inject/i', $content) !== 0)
        {
            $injectContent     = $tokens[$stackPointer]['content']
                . $tokens[$stackPointer + 1]['content']
                . $tokens[$stackPointer + 2]['content'];
            $injectMatches     = [];
            $injectPattern     = '@Inject(\(\{"[a-zA-Z]+((\.|\\\\|_)[a-zA-Z]+)*"(, "[a-zA-Z]+((\.|\\\\|_)[a-zA-Z]+)*")*\}\))?';
            $injectablePattern = '@Injectable\([a-zA-Z]+="[a-zA-Z]+"(, ([a-zA-Z]+="[a-zA-Z]+"|[a-zA-Z]+=(true|false)))*\)';
            $completePattern   = '/(' . $injectPattern . ')|(' . $injectablePattern . ')/';
            preg_match($completePattern, $injectContent, $injectMatches);
            if (empty($injectMatches))
            {
                $type  = 'Production.Inject.InjectionFound';
                $data  = [$injectContent];
                $error = 'Inject[able] annotation has wrong format.';
                $phpcsFile->addWarning($error, $stackPointer, $type, $data);
            }
        }
    }
1312372
protected function assertNoApiTag(File $phpCsFile, int $stackPointer): void
    {
        $apiIndex = $this->findApiAnnotationIndex($phpCsFile, $stackPointer);
        if (!$apiIndex) {
            return;
        }

        $fix = $phpCsFile->addFixableError('@api annotation is invalid.', $stackPointer, 'ApiAnnotationInvalid');

        if (!$fix) {
            return;
        }

        $tokens = $phpCsFile->getTokens();
        $line = $tokens[$apiIndex]['line'];

        $phpCsFile->fixer->beginChangeset();
        $phpCsFile->fixer->replaceToken($apiIndex, '');

        $index = $apiIndex;
        while ($tokens[$index - 1]['line'] === $line) {
            $index--;
            $phpCsFile->fixer->replaceToken($index, '');
        }
        $index = $apiIndex;
        while ($tokens[$index + 1]['line'] === $line) {
            $index++;
            $phpCsFile->fixer->replaceToken($index, '');
        }

        $phpCsFile->fixer->endChangeset();
    }
394576
protected function getClassOrInterfaceName(File $phpCsFile, int $stackPointer): string
    {
        $classOrInterfacePosition = $phpCsFile->findPrevious([T_CLASS, T_INTERFACE], $stackPointer);
        $classOrInterfaceNamePosition = $phpCsFile->findNext(T_STRING, $classOrInterfacePosition);

        return $phpCsFile->getTokens()[$classOrInterfaceNamePosition]['content'];
    }
640922
public function process(File $phpcsFile, $stackPtr)
    {
        if ($this->supportsAbove('7.0') === false) {
            return;
        }

        if ($this->determineNamespace($phpcsFile, $stackPtr) !== '') {
            /*
             * Namespaced methods with the same name as the class are treated as
             * regular methods, so we can bow out if we're in a namespace.
             *
             * Note: the exception to this is PHP 5.3.0-5.3.2. This is currently
             * not dealt with.
             */
            return;
        }

        $tokens = $phpcsFile->getTokens();

        $class = $tokens[$stackPtr];

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

        $nextNonEmpty = $phpcsFile->findNext(Tokens::$emptyTokens, ($stackPtr + 1), null, true);
        if ($nextNonEmpty === false || $tokens[$nextNonEmpty]['code'] !== \T_STRING) {
            // Anonymous class in combination with PHPCS 2.3.x.
            return;
        }

        $scopeCloser = $class['scope_closer'];
        $className   = $tokens[$nextNonEmpty]['content'];

        if (empty($className) || \is_string($className) === false) {
            return;
        }

        $nextFunc            = $stackPtr;
        $classNameLc         = strtolower($className);
        $newConstructorFound = false;
        $oldConstructorFound = false;
        $oldConstructorPos   = -1;
        while (($nextFunc = $phpcsFile->findNext(\T_FUNCTION, ($nextFunc + 1), $scopeCloser)) !== false) {
            $functionScopeCloser = $nextFunc;
            if (isset($tokens[$nextFunc]['scope_closer'])) {
                // Normal (non-interface, non-abstract) method.
                $functionScopeCloser = $tokens[$nextFunc]['scope_closer'];
            }

            $funcName = $phpcsFile->getDeclarationName($nextFunc);
            if (empty($funcName) || \is_string($funcName) === false) {
                $nextFunc = $functionScopeCloser;
                continue;
            }

            $funcNameLc = strtolower($funcName);

            if ($funcNameLc === '__construct') {
                $newConstructorFound = true;
            }

            if ($funcNameLc === $classNameLc) {
                $oldConstructorFound = true;
                $oldConstructorPos   = $nextFunc;
            }

            // If both have been found, no need to continue looping through the functions.
            if ($newConstructorFound === true && $oldConstructorFound === true) {
                break;
            }

            $nextFunc = $functionScopeCloser;
        }

        if ($newConstructorFound === false && $oldConstructorFound === true) {
            $phpcsFile->addWarning(
                'Use of deprecated PHP4 style class constructor is not supported since PHP 7.',
                $oldConstructorPos,
                'Found'
            );
        }
    }