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

@return array
332659
protected function extractExceptionAnnotations(File $phpCsFile, int $docBlockStartIndex): array
    {
        $tokens = $phpCsFile->getTokens();

        $throwTags = [];
        foreach ($tokens[$docBlockStartIndex]['comment_tags'] as $index) {
            if ($tokens[$index]['content'] !== '@throws') {
                continue;
            }

            if ($tokens[($index + 2)]['code'] !== T_DOC_COMMENT_STRING) {
                continue;
            }

            $fullClass = $tokens[($index + 2)]['content'];
            $space = strpos($fullClass, ' ');
            if ($space !== false) {
                $fullClass = substr($fullClass, 0, $space);
            }

            $class = $fullClass;
            $lastSeparator = strrpos($class, '\\');
            if ($lastSeparator !== false) {
                $class = substr($class, $lastSeparator + 1);
            }

            $throwTags[] = [
                'index' => $index,
                'fullClass' => $fullClass,
                'class' => $class,
            ];
        }

        return $throwTags;
    }
391889
protected function hasInheritDoc(File $phpCsFile, $docBlockStartIndex, $docBlockEndIndex) {
		$tokens = $phpCsFile->getTokens();

		for ($i = $docBlockStartIndex + 1; $i < $docBlockEndIndex; ++$i) {
			if (empty($tokens[$i]['content'])) {
				continue;
			}
			$content = strtolower($tokens[$i]['content']);
			if (strpos($content, '@inheritdoc') === false) {
				continue;
			}

			return true;
		}

		return false;
	}
597665
public function process(File $phpcsFile, $openPointer)
    {
        if (DocCommentHelper::isInline($phpcsFile, $openPointer)) {
            return;
        }

        $this->phpcsFile = $phpcsFile;
        $this->tokens = $phpcsFile->getTokens();

        $commentCloser = $this->tokens[$openPointer]['comment_closer'];

        $fcStartPointer = TokenHelper::findNextExcluding(
            $phpcsFile,
            [T_DOC_COMMENT_WHITESPACE, T_DOC_COMMENT_STAR],
            $openPointer + 1,
            $commentCloser
        );

        if ($fcStartPointer === null) {
            return;
        }

        $annotations = $this->getAnnotations($openPointer);
        $annotationsCount = \count($annotations);
        $firstAnnotation = $annotationsCount > 0 ? $annotations[0] : null;
        $fcEndPointer = $this->getFirstContentEndPointer($fcStartPointer, $openPointer);
        $lcEndPointer = $annotationsCount > 0
            ? $annotations[$annotationsCount - 1]->getEndPointer()
            : $fcEndPointer;

        $this->checkLinesBeforeFirstContent($openPointer, $fcStartPointer);
        $this->checkLinesBetweenDescriptionAndFirstAnnotation($fcStartPointer, $fcEndPointer, $firstAnnotation);
        $this->checkLinesBetweenAnnotationsTypes($annotations);
        $this->checkLinesAfterLastContent($commentCloser, $lcEndPointer);
    }
621011
public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr)
    {
        $this->currentFile = $phpcsFile;

        $tokens       = $phpcsFile->getTokens();
        $commentStart = $phpcsFile->findNext(T_WHITESPACE, ($stackPtr + 1), null, true);

        if ($tokens[$commentStart]['code'] === T_COMMENT) {
            $phpcsFile->addError('You must use "/**" style comments for a file comment', $commentStart, 'WrongStyle');
            return ($phpcsFile->numTokens + 1);
        } else if ($commentStart === false || $tokens[$commentStart]['code'] !== T_DOC_COMMENT_OPEN_TAG) {
            $phpcsFile->addError('Missing file doc comment', $stackPtr, 'Missing');
            return ($phpcsFile->numTokens + 1);
        }

        $commentEnd = $tokens[$commentStart]['comment_closer'];

        // No blank line between the open tag and the file comment.
        if ($tokens[$commentStart]['line'] > ($tokens[$stackPtr]['line'] + 1)) {
            $error = 'There must be no blank lines before the file comment';
            $phpcsFile->addError($error, $stackPtr, 'SpacingAfterOpen');
        }

        // Exactly one blank line after the file comment.
        $next = $phpcsFile->findNext(T_WHITESPACE, ($commentEnd + 1), null, true);
        if ($tokens[$next]['line'] !== ($tokens[$commentEnd]['line'] + 2)) {
            $error = 'There must be exactly one blank line after the file comment';
            $phpcsFile->addError($error, $commentEnd, 'SpacingAfterComment');
        }

        // Required tags in correct order.
        $required = array(
                     '@package'    => true,
                     '@subpackage' => true,
                     '@author'     => true,
                     '@copyright'  => true,
                    );

        $foundTags = array();
        foreach ($tokens[$commentStart]['comment_tags'] as $tag) {
            $name       = $tokens[$tag]['content'];
            $isRequired = isset($required[$name]);

            if ($isRequired === true && in_array($name, $foundTags) === true) {
                $error = 'Only one %s tag is allowed in a file comment';
                $data  = array($name);
                $phpcsFile->addError($error, $tag, 'Duplicate'.ucfirst(substr($name, 1)).'Tag', $data);
            }

            $foundTags[] = $name;

            if ($isRequired === false) {
                continue;
            }

            $string = $phpcsFile->findNext(T_DOC_COMMENT_STRING, $tag, $commentEnd);
            if ($string === false || $tokens[$string]['line'] !== $tokens[$tag]['line']) {
                $error = 'Content missing for %s tag in file comment';
                $data  = array($name);
                $phpcsFile->addError($error, $tag, 'Empty'.ucfirst(substr($name, 1)).'Tag', $data);
                continue;
            }

        }//end foreach

        // Check if the tags are in the correct position.
        $pos = 0;
        foreach ($required as $tag => $true) {
            if (in_array($tag, $foundTags) === false) {
                $error = 'Missing %s tag in file comment';
                $data  = array($tag);
                $phpcsFile->addError($error, $commentEnd, 'Missing'.ucfirst(substr($tag, 1)).'Tag', $data);
            }

            if (isset($foundTags[$pos]) === false) {
                break;
            }

            if ($foundTags[$pos] !== $tag) {
                $error = 'The tag in position %s should be the %s tag';
                $data  = array(
                          ($pos + 1),
                          $tag,
                         );
                $phpcsFile->addError($error, $tokens[$commentStart]['comment_tags'][$pos], ucfirst(substr($tag, 1)).'TagOrder', $data);
            }

            $pos++;
        }//end foreach

        // Ignore the rest of the file.
        return ($phpcsFile->numTokens + 1);

    }
19204
protected function processParams(
        File $phpcsFile,
        $stackPtr,
        $commentStart
    ) {
        $tokens = $phpcsFile->getTokens();

        $params = [];
        $maxType = 0;
        $maxVar = 0;

        foreach ($tokens[$commentStart]['comment_tags'] as $pos => $tag) {
            if ($tokens[$tag]['content'] !== '@param') {
                continue;
            }

            $type = '';
            $typeSpace = 0;
            $var = '';
            $varSpace = 0;
            $comment = '';
            if ($tokens[($tag + 2)]['code'] === T_DOC_COMMENT_STRING) {
                $matches = [];
                preg_match(
                    '/([^$&\.]+)(?:((?:\$|&|\.)[^\s]+)(?:(\s+)(.*))?)?/',
                    $tokens[($tag + 2)]['content'],
                    $matches
                );

                $typeLen = strlen($matches[1]);
                $type = trim($matches[1]);
                $typeSpace = ($typeLen - strlen($type));
                $typeLen = strlen($type);
                if ($typeLen > $maxType) {
                    $maxType = $typeLen;
                }

                if (isset($matches[2]) === true) {
                    $var = str_replace('...', '', $matches[2]);
                    $varLen = strlen($var);
                    if ($varLen > $maxVar) {
                        $maxVar = $varLen;
                    }

                    if (isset($matches[4]) === true) {
                        $varSpace = strlen($matches[3]);
                        $comment = $matches[4];

                        // Any strings until the next tag belong to this comment.
                        if (isset($tokens[$commentStart]['comment_tags'][($pos
                                    + 1)]) === true
                        ) {
                            $end = $tokens[$commentStart]['comment_tags'][($pos
                                + 1)];
                        } else {
                            $end = $tokens[$commentStart]['comment_closer'];
                        }

                        for ($i = ($tag + 3); $i < $end; $i++) {
                            if ($tokens[$i]['code'] === T_DOC_COMMENT_STRING) {
                                $comment .= ' ' . $tokens[$i]['content'];
                            }
                        }
                    }

                    //$error = 'Missing parameter comment';
                    //$phpcsFile->addError($error, $tag, 'MissingParamComment');
                } else {
                    $error = 'Missing parameter name';
                    $phpcsFile->addError($error, $tag, 'MissingParamName');
                }
            } else {
                $error = 'Missing parameter type';
                $phpcsFile->addError($error, $tag, 'MissingParamType');
            }

            $params[] = [
                'tag' => $tag,
                'type' => $type,
                'var' => $var,
                'comment' => $comment,
                'type_space' => $typeSpace,
                'var_space' => $varSpace,
            ];
        }

        $realParams = $phpcsFile->getMethodParameters($stackPtr);
        $foundParams = [];

        foreach ($params as $pos => $param) {
            if ($param['var'] === '') {
                continue;
            }

            if (array_key_exists('type', $param)) {
                $types = explode('|', $param['type']);

                foreach ($types as $type) {
                    $this->checkParamType($type, $param['tag'], $phpcsFile);
                }
            }

            $foundParams[] = $param['var'];

            // Check number of spaces after the type.
            $spaces = 1;
            if ($param['type_space'] !== $spaces) {
                $error = 'Expected %s spaces after parameter type; %s found';
                $data = [
                    $spaces,
                    $param['type_space'],
                ];

                $fix = $phpcsFile->addFixableError(
                    $error,
                    $param['tag'],
                    'SpacingAfterParamType',
                    $data
                );
                if ($fix === true) {
                    $content = $param['type'];
                    $content .= str_repeat(' ', $spaces);
                    $content .= $param['var'];
                    $content .= str_repeat(' ', $param['var_space']);
                    $content .= $param['comment'];
                    $phpcsFile->fixer->replaceToken(
                        ($param['tag'] + 2),
                        $content
                    );
                }
            }

            // Make sure the param name is correct.
            if (isset($realParams[$pos]) === true) {
                $realName = $realParams[$pos]['name'];
                if ($realName !== $param['var']) {
                    $code = 'ParamNameNoMatch';
                    $data = [
                        $param['var'],
                        $realName,
                    ];

                    $error = 'Doc comment for parameter %s does not match ';
                    if (strtolower($param['var']) === strtolower($realName)) {
                        $error .= 'case of ';
                        $code = 'ParamNameNoCaseMatch';
                    }

                    $error .= 'actual variable name %s';

                    $phpcsFile->addError($error, $param['tag'], $code, $data);
                }
            } else {
                if (substr($param['var'], -4) !== ',...') {
                    // We must have an extra parameter comment.
                    $error = 'Superfluous parameter comment';
                    $phpcsFile->addError(
                        $error,
                        $param['tag'],
                        'ExtraParamComment'
                    );
                }
            }

            if ($param['comment'] === '') {
                continue;
            }

            // Check number of spaces after the var name.
            $spaces = 1;
            if ($param['var_space'] !== $spaces) {
                $error = 'Expected %s spaces after parameter name; %s found';
                $data = [
                    $spaces,
                    $param['var_space'],
                ];

                $fix = $phpcsFile->addFixableError(
                    $error,
                    $param['tag'],
                    'SpacingAfterParamName',
                    $data
                );

                if ($fix === true) {
                    $content = $param['type'];
                    $content .= str_repeat(' ', $param['type_space']);
                    $content .= $param['var'];
                    $content .= str_repeat(' ', $spaces);
                    $content .= $param['comment'];
                    $phpcsFile->fixer->replaceToken(
                        ($param['tag'] + 2),
                        $content
                    );
                }
            }
        }
    }
779838
protected function findDocBlock(File $phpCsFile, int $stackPointer): ?int
    {
        $tokens = $phpCsFile->getTokens();

        $index = $phpCsFile->findPrevious(T_WHITESPACE, $stackPointer - 1, null, true);

        if ($tokens[$index]['type'] === 'T_DOC_COMMENT_CLOSE_TAG') {
            return $index;
        }

        return null;
    }
761027
protected function loadStatements(File $phpcsFile) {
		if ($this->existingStatements !== null) {
			return;
		}

		$existingStatements = $this->getUseStatements($phpcsFile);
		$this->existingStatements = $existingStatements;
		$this->allStatements = $existingStatements;
		$this->newStatements = [];
	}
318237
protected function hasCorrectContent(File $phpCsFile, int $docBlockEndPosition): bool
    {
        $tokens = $phpCsFile->getTokens();

        $docBlockStartPosition = $tokens[$docBlockEndPosition]['comment_opener'];

        $content = '';
        for ($i = $docBlockStartPosition + 1; $i < $docBlockEndPosition; $i++) {
            if ($tokens[$i]['type'] !== 'T_DOC_COMMENT_STRING') {
                continue;
            }
            $content .= $tokens[$i]['content'];
        }

        if ($content === static::EXPLANATION_CONSTANTS_INTERFACE) {
            return true;
        }

        return false;
    }
362166
protected function processLicense(PHP_CodeSniffer_File $phpcsFile, array $tags)
	{
		$tokens = $phpcsFile->getTokens();

		foreach ($tags as $tag)
		{
			if ($tokens[($tag + 2)]['code'] !== T_DOC_COMMENT_STRING)
			{
				// No content.
				continue;
			}

			$content = $tokens[($tag + 2)]['content'];
			$matches = array();
			preg_match('/^([^\s]+)\s+(.*)/', $content, $matches);

			if (count($matches) !== 3)
			{
				$error = '@license tag must contain a URL and a license name';
				$phpcsFile->addError($error, $tag, 'IncompleteLicense');
			}
		}
	}
802238
protected function fixOrder(File $phpCsFile, int $docBlockStartIndex, int $docBlockEndIndex, array $tags): void
    {
        $errors = [];
        foreach ($tags as $i => $tag) {
            if (isset($tag['error'])) {
                $errors[$i] = $tag['error'];
            }
        }

        if (!$errors) {
            return;
        }

        $fix = $phpCsFile->addFixableError('Invalid order of tags: ' . implode(', ', $errors), $docBlockEndIndex, 'OrderInvalid');
        if (!$fix) {
            return;
        }

        $tokens = $phpCsFile->getTokens();

        $phpCsFile->fixer->beginChangeset();

        $order = $this->getTagOrderMap();

        $newOrder = [];
        foreach ($tags as $tag) {
            $tagOrder = isset($order[$tag['tag']]) ? $order[$tag['tag']] : -1;
            $newOrder[$tagOrder][] = $this->getContent($tokens, $tag['start'], $tag['end']);
        }

        ksort($newOrder);
        if (isset($newOrder[-1])) {
            ksort($newOrder[-1]);
        }

        $content = '';
        foreach ($newOrder as $tagGroup) {
            $content .= implode('', $tagGroup);
        }

        $firstTagTokenIndex = $tags[0]['start'];
        $lastTagTokenIndex = $tags[count($tags) - 1]['end'];

        for ($i = $firstTagTokenIndex; $i < $lastTagTokenIndex; $i++) {
            $phpCsFile->fixer->replaceToken($i, '');
        }

        $phpCsFile->fixer->replaceToken($lastTagTokenIndex, $content);

        $phpCsFile->fixer->endChangeset();
    }
488585
protected function assertExisting(File $phpcsFile, int $pointer, int $docBlockReturnIndex, ?string $returnType): void
    {
        $tokens = $phpcsFile->getTokens();

        $documentedReturnType = $tokens[$docBlockReturnIndex + 2]['content'];
        $whiteSpacePosition = mb_strpos($documentedReturnType, ' ');
        if ($whiteSpacePosition !== false) {
            $documentedReturnType = mb_substr($documentedReturnType, 0, $whiteSpacePosition);
        }

        if ($returnType !== 'void' || $documentedReturnType === 'void') {
            return;
        }
        if ($this->documentedTypesContainFuzzyVoid($documentedReturnType)) {
            return;
        }
        if ($this->bodyContainsYield($phpcsFile, $pointer)) {
            return;
        }

        // We need to skip for fake extension hooks.
        $scopeOpenerIndex = $tokens[$pointer]['scope_opener'];
        $firstToken = $phpcsFile->findNext(Tokens::$emptyTokens, $scopeOpenerIndex + 1, null, true);
        if ($tokens[$firstToken]['code'] === T_THROW) {
            return;
        }

        $phpcsFile->addError('Method is void, but doc block states otherwise.', $docBlockReturnIndex + 2, 'InvalidVoidBody');
    }
166610
protected function extractException(File $phpCsFile, int $contentIndex): array
    {
        $tokens = $phpCsFile->getTokens();

        $fullClass = '';

        $position = $contentIndex;
        while ($this->isGivenKind([T_NS_SEPARATOR, T_STRING], $tokens[$position])) {
            $fullClass .= $tokens[$position]['content'];
            ++$position;
        }

        $class = $fullClass;
        $lastSeparator = strrpos($class, '\\');
        if ($lastSeparator !== false) {
            $class = substr($class, $lastSeparator + 1);
        }

        return [
            'start' => $contentIndex,
            'end' => $position - 1,
            'fullClass' => $fullClass,
            'class' => $class,
        ];
    }
163137
public function process(File $phpcsFile, $stackPtr)
    {
        $tokens          = $phpcsFile->getTokens();
        $current         = $stackPtr;
        $previousLine    = $tokens[$stackPtr]['line'] - 1;
        $prevLineTokens  = array();

        while ($current >= 0 && $tokens[$current]['line'] >= $previousLine) {
            if ($tokens[$current]['line'] == $previousLine
                && $tokens[$current]['type'] !== 'T_WHITESPACE'
                && $tokens[$current]['type'] !== 'T_COMMENT'
                && $tokens[$current]['type'] !== 'T_DOC_COMMENT_CLOSE_TAG'
                && $tokens[$current]['type'] !== 'T_DOC_COMMENT_WHITESPACE'
            ) {
                $prevLineTokens[] = $tokens[$current]['type'];
            }
            $current--;
        }

        if (isset($prevLineTokens[0])
            && ($prevLineTokens[0] === 'T_OPEN_CURLY_BRACKET'
            || $prevLineTokens[0] === 'T_COLON')
        ) {
            return;
        } else if (count($prevLineTokens) > 0) {
            $fix = $phpcsFile->addFixableError(
                'Missing blank line before return statement',
                $stackPtr,
                'MissedBlankLineBeforeReturn'
            );

            if ($fix === true) {
                $phpcsFile->fixer->beginChangeset();
                $i = 1;
                while ($tokens[$stackPtr-$i]['type'] === "T_WHITESPACE") {
                    $i++;
                }

                $phpcsFile->fixer->addNewline($stackPtr-$i);
                $phpcsFile->fixer->endChangeset();
            }
        }

        return;
    }
172656
protected function isMarkedDeprecatedInDocBlock(File $phpCsFile, array $tokens, int $stackPointer): bool
    {
        $docBlockEndIndex = $this->findRelatedDocBlock($phpCsFile, $stackPointer);
        if (!$docBlockEndIndex) {
            return false;
        }
        $docBlockStartIndex = $tokens[$docBlockEndIndex]['comment_opener'];
        for ($i = $docBlockStartIndex + 1; $i < $docBlockEndIndex; $i++) {
            if ($tokens[$i]['type'] !== 'T_DOC_COMMENT_TAG') {
                continue;
            }
            if (!in_array($tokens[$i]['content'], ['@deprecated'])) {
                continue;
            }
            return true;
        }

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

        $tokens = $phpcsFile->getTokens();

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

        $switchOpener = $tokens[$stackPtr]['scope_opener'];
        $switchCloser = $tokens[$stackPtr]['scope_closer'];

        // Quick check whether we need to bother with the more complex logic.
        $hasContinue = $phpcsFile->findNext(\T_CONTINUE, ($switchOpener + 1), $switchCloser);
        if ($hasContinue === false) {
            return;
        }

        $caseDefault = $switchOpener;

        do {
            $caseDefault = $phpcsFile->findNext($this->caseTokens, ($caseDefault + 1), $switchCloser);
            if ($caseDefault === false) {
                break;
            }

            if (isset($tokens[$caseDefault]['scope_opener']) === false) {
                // Unknown start of the case, skip.
                continue;
            }

            $caseOpener      = $tokens[$caseDefault]['scope_opener'];
            $nextCaseDefault = $phpcsFile->findNext($this->caseTokens, ($caseDefault + 1), $switchCloser);
            if ($nextCaseDefault === false) {
                $caseCloser = $switchCloser;
            } else {
                $caseCloser = $nextCaseDefault;
            }

            // Check for unscoped control structures within the case.
            $controlStructure = $caseOpener;
            $doCount          = 0;
            while (($controlStructure = $phpcsFile->findNext($this->loopStructures, ($controlStructure + 1), $caseCloser)) !== false) {
                if ($tokens[$controlStructure]['code'] === \T_DO) {
                    $doCount++;
                }

                if (isset($tokens[$controlStructure]['scope_opener'], $tokens[$controlStructure]['scope_closer']) === false) {
                    if ($tokens[$controlStructure]['code'] === \T_WHILE && $doCount > 0) {
                        // While in a do-while construct.
                        $doCount--;
                        continue;
                    }

                    // Control structure without braces found within the case, ignore this case.
                    continue 2;
                }
            }

            // Examine the contents of the case.
            $continue = $caseOpener;

            do {
                $continue = $phpcsFile->findNext(\T_CONTINUE, ($continue + 1), $caseCloser);
                if ($continue === false) {
                    break;
                }

                $nextSemicolon = $phpcsFile->findNext(array(\T_SEMICOLON, \T_CLOSE_TAG), ($continue + 1), $caseCloser);
                $codeString    = '';
                for ($i = ($continue + 1); $i < $nextSemicolon; $i++) {
                    if (isset($this->acceptedLevelTokens[$tokens[$i]['code']]) === false) {
                        // Function call/variable or other token which make numeric level impossible to determine.
                        continue 2;
                    }

                    if (isset(Tokens::$emptyTokens[$tokens[$i]['code']]) === true) {
                        continue;
                    }

                    $codeString .= $tokens[$i]['content'];
                }

                $level = null;
                if ($codeString !== '') {
                    if (is_numeric($codeString)) {
                        $level = (int) $codeString;
                    } else {
                        // With the above logic, the string can only contain digits and operators, eval!
                        $level = eval("return ( $codeString );");
                    }
                }

                if (isset($level) === false || $level === 0) {
                    $level = 1;
                }

                // Examine which control structure is being targeted by the continue statement.
                if (isset($tokens[$continue]['conditions']) === false) {
                    continue;
                }

                $conditions = array_reverse($tokens[$continue]['conditions'], true);
                // PHPCS adds more structures to the conditions array than we want to take into
                // consideration, so clean up the array.
                foreach ($conditions as $tokenPtr => $tokenCode) {
                    if (isset($this->loopStructures[$tokenCode]) === false) {
                        unset($conditions[$tokenPtr]);
                    }
                }

                $targetCondition = \array_slice($conditions, ($level - 1), 1, true);
                if (empty($targetCondition)) {
                    continue;
                }

                $conditionToken = key($targetCondition);
                if ($conditionToken === $stackPtr) {
                    $phpcsFile->addWarning(
                        "Targeting a 'switch' control structure with a 'continue' statement is strongly discouraged and will throw a warning as of PHP 7.3.",
                        $continue,
                        'Found'
                    );
                }

            } while ($continue < $caseCloser);

        } while ($caseDefault < $switchCloser);
    }
310379
protected function getThrowAnnotationIndex(array $tokens, int $docBlockStartIndex): int
    {
        foreach ($tokens[$docBlockStartIndex]['comment_tags'] as $index) {
            if ($tokens[$index]['content'] !== '@throws') {
                continue;
            }

            $throwAnnotationIndex = $index;
            while ($tokens[$throwAnnotationIndex + 1]['line'] === $tokens[$index]['line']) {
                $throwAnnotationIndex++;
            }
            $throwAnnotationIndex++;

            return $throwAnnotationIndex;
        }

        foreach ($tokens[$docBlockStartIndex]['comment_tags'] as $index) {
            if ($tokens[$index]['content'] !== '@return') {
                continue;
            }

            $throwAnnotationIndex = $this->getFirstTokenOfLine($tokens, $index);

            return $throwAnnotationIndex;
        }

        $throwAnnotationIndex = $this->getFirstTokenOfLine($tokens, $tokens[$docBlockStartIndex]['comment_closer']);

        return $throwAnnotationIndex;
    }
499138
protected function getReturnTypes(File $phpCsFile, int $stackPointer): array
    {
        $tokens = $phpCsFile->getTokens();

        // We skip for interface methods
        if (empty($tokens[$stackPointer]['scope_opener']) || empty($tokens[$stackPointer]['scope_closer'])) {
            return [];
        }

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

        $returnTypes = [];
        for ($i = $scopeOpener; $i < $scopeCloser; $i++) {
            if ($tokens[$i]['code'] !== T_RETURN) {
                continue;
            }

            if (in_array(T_CLOSURE, $tokens[$i]['conditions'])) {
                continue;
            }

            $contentIndex = $phpCsFile->findNext(Tokens::$emptyTokens, $i + 1, $scopeCloser, true);
            if (!$contentIndex) {
                continue;
            }

            if ($tokens[$contentIndex]['code'] === T_PARENT) {
                $parentMethodName = $tokens[$contentIndex + 2]['content'];

                if ($parentMethodName === FunctionHelper::getName($phpCsFile, $stackPointer)) {
                    continue;
                }
            }

            $returnTypes[] = $tokens[$contentIndex]['content'];
        }

        return array_unique($returnTypes);
    }