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

@return void
767891
protected function checkBeginningOfDocBlock(File $phpCsFile, int $docBlockStartIndex, int $nextIndex): void
    {
        $tokens = $phpCsFile->getTokens();

        $diff = $tokens[$nextIndex]['line'] - $tokens[$docBlockStartIndex]['line'];
        if ($diff < 2) {
            return;
        }

        $fix = $phpCsFile->addFixableError('Expected no extra blank line before tags, got ' . ($diff - 1), $nextIndex, 'NoExtraNewlineBeforeTags');
        if ($fix) {
            return;
        }

        $phpCsFile->fixer->beginChangeset();

        for ($i = $docBlockStartIndex; $i < $nextIndex; $i++) {
            if ($tokens[$i]['line'] <= $tokens[$docBlockStartIndex]['line'] || $tokens[$i]['line'] >= $tokens[$nextIndex]['line']) {
                continue;
            }
            $phpCsFile->fixer->replaceToken($i, '');
        }

        $phpCsFile->fixer->endChangeset();
    }
195402
public function process(\PHP_CodeSniffer\Files\File $phpcsFile, $stackPtr)
    {
        $tokens = $phpcsFile->getTokens();

        // Find the next non whitespace token.
        $commentStart = $phpcsFile->findNext(T_WHITESPACE, ($stackPtr + 1), null, true);

        // Allow declare() statements at the top of the file.
        if ($tokens[$commentStart]['code'] === T_DECLARE) {
            $semicolon    = $phpcsFile->findNext(T_SEMICOLON, ($commentStart + 1));
            $commentStart = $phpcsFile->findNext(T_WHITESPACE, ($semicolon + 1), null, true);
        }

        // Ignore vim header.
        if ($tokens[$commentStart]['code'] === T_COMMENT) {
            if (strstr($tokens[$commentStart]['content'], 'vim:') !== false) {
                $commentStart = $phpcsFile->findNext(
                    T_WHITESPACE,
                    ($commentStart + 1),
                    null,
                    true
                    );
            }
        }

        $errorToken = ($stackPtr + 1);
        if (isset($tokens[$errorToken]) === false) {
            $errorToken--;
        }

        if ($tokens[$commentStart]['code'] === T_CLOSE_TAG) {
            // We are only interested if this is the first open tag.
            return ($phpcsFile->numTokens + 1);
        } else if ($tokens[$commentStart]['code'] === T_COMMENT) {
            $error = 'You must use "/**" style comments for a file comment';
            $phpcsFile->addError($error, $errorToken, 'WrongStyle');
            $phpcsFile->recordMetric($stackPtr, 'File has doc comment', 'yes');
            return ($phpcsFile->numTokens + 1);
        } else if ($commentStart === false
            || $tokens[$commentStart]['code'] !== T_DOC_COMMENT_OPEN_TAG
            ) {
                $phpcsFile->addError('Missing file doc comment', $errorToken, 'Missing');
                $phpcsFile->recordMetric($stackPtr, 'File has doc comment', 'no');
                return ($phpcsFile->numTokens + 1);
            }

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

            $nextToken = $phpcsFile->findNext(
                T_WHITESPACE,
                ($commentEnd + 1),
                null,
                true
                );

            $ignore = array(
                T_CLASS,
                T_INTERFACE,
                T_TRAIT,
                T_FUNCTION,
                T_CLOSURE,
                T_PUBLIC,
                T_PRIVATE,
                T_PROTECTED,
                T_FINAL,
                T_STATIC,
                T_ABSTRACT,
                T_CONST,
                T_PROPERTY,
                T_INCLUDE,
                T_INCLUDE_ONCE,
                T_REQUIRE,
                T_REQUIRE_ONCE,
            );

            if (in_array($tokens[$nextToken]['code'], $ignore) === true) {
                $phpcsFile->addError('Missing file doc comment', $stackPtr, 'Missing');
                $phpcsFile->recordMetric($stackPtr, 'File has doc comment', 'no');
                return ($phpcsFile->numTokens + 1);
            }

            $phpcsFile->recordMetric($stackPtr, 'File has doc comment', 'yes');

            // Check each tag.
            $this->processTags($phpcsFile, $stackPtr, $commentStart);

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

    }
1257356
public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr)
    {
        $tokens = $phpcsFile->getTokens();
        if (isset($tokens[$stackPtr]['scope_closer']) === false) {
            return;
        }

        $errorData = array(strtolower($tokens[$stackPtr]['content']));

        $nextClass = $phpcsFile->findNext(array(T_CLASS, T_INTERFACE, T_TRAIT), ($stackPtr + 1));
        if ($nextClass !== false) {
            $error = 'Each %s must be in a file by itself';
            $phpcsFile->addError($error, $nextClass, 'MultipleClasses', $errorData);
        }
    }
484307
protected function applyFix(File $phpCsFile,
		$index,
		$leftIndexStart,
		$leftIndexEnd,
		$rightIndexStart,
		$rightIndexEnd) {
		$tokens = $phpCsFile->getTokens();

		$token = $tokens[$index];
		// Check if we need to inverse comparison operator
		$comparisonValue = $this->getComparisonValue($token);

		$phpCsFile->fixer->beginChangeset();

		$leftValue = '';
		for ($i = $leftIndexStart; $i <= $leftIndexEnd; ++$i) {
			$leftValue .= $tokens[$i]['content'];
			$phpCsFile->fixer->replaceToken($i, '');
		}
		$rightValue = '';
		for ($i = $rightIndexStart; $i <= $rightIndexEnd; ++$i) {
			$rightValue .= $tokens[$i]['content'];
			$phpCsFile->fixer->replaceToken($i, '');
		}

		$phpCsFile->fixer->replaceToken($index, $comparisonValue);
		$phpCsFile->fixer->replaceToken($leftIndexEnd, $rightValue);
		$phpCsFile->fixer->replaceToken($rightIndexStart, $leftValue);

		$phpCsFile->fixer->endChangeset();
	}
1255168
public function process(File $phpcsFile, $stackPtr)
    {
        $tokens = $phpcsFile->getTokens();

        $nextIndex = $phpcsFile->findNext(Tokens::$emptyTokens, $stackPtr + 1, null, true);
        if ($tokens[$nextIndex]['content'] !== '__construct' && $tokens[$nextIndex]['content'] !== '__destruct') {
            return;
        }

        $docBlockEndIndex = $this->findRelatedDocBlock($phpcsFile, $stackPtr);
        if (!$docBlockEndIndex) {
            return;
        }

        $tokens = $phpcsFile->getTokens();

        $docBlockStartIndex = $tokens[$docBlockEndIndex]['comment_opener'];

        $firstLineIndex = $phpcsFile->findNext(T_DOC_COMMENT_STRING, $docBlockStartIndex, $docBlockEndIndex);
        if ($tokens[$firstLineIndex]['line'] !== $tokens[$docBlockStartIndex]['line'] + 1) {
            return;
        }

        if (!preg_match('/^\w+ (constructor|destructor)\.$/i', $tokens[$firstLineIndex]['content'])) {
            return;
        }

        $fix = $phpcsFile->addFixableError('Doc Block has unneeded header line.', $firstLineIndex, 'UnneededNoise');
        if (!$fix) {
            return;
        }

        $phpcsFile->fixer->beginChangeset();

        $phpcsFile->fixer->replaceToken($firstLineIndex, '');

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

        $phpcsFile->fixer->endChangeset();
    }
413293
protected function checkDescription(File $phpcsFile, int $stackPtr): void
    {
        $tokens = $phpcsFile->getTokens();

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

        if (!preg_match('/\s\s+/', $content)) {
            return;
        }

        $fix = $phpcsFile->addFixableError('There should be no inline alignment in doc blocks descriptions.', $stackPtr, 'DocBlockInlineAlignment');
        if ($fix) {
            $newContent = preg_replace('/\s\s+/', ' ', $content);
            $phpcsFile->fixer->replaceToken($stackPtr, $newContent);
        }
    }
268363
protected function fixDocCommentCloseTags(File $phpCsFile, int $index): void
    {
        $tokens = $phpCsFile->getTokens();

        $content = $tokens[$index]['content'];
        if ($content === '*/') {
            return;
        }

        $fix = $phpCsFile->addFixableError('Inline Doc Block comment end tag should be `*/`, got `' . $content . '`', $index, 'EndTag');
        if (!$fix) {
            return;
        }

        $phpCsFile->fixer->beginChangeset();

        $phpCsFile->fixer->replaceToken($index, '*/');

        $phpCsFile->fixer->endChangeset();
    }
1035136
protected function findDocBlockReturn(File $phpcsFile, int $docBlockStartIndex, int $docBlockEndIndex): ?int
    {
        $tokens = $phpcsFile->getTokens();

        for ($i = $docBlockStartIndex + 1; $i < $docBlockEndIndex; $i++) {
            if (!$this->isGivenKind(T_DOC_COMMENT_TAG, $tokens[$i])) {
                continue;
            }
            if ($tokens[$i]['content'] !== '@return') {
                continue;
            }

            return $i;
        }

        return null;
    }
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');
    }
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);
            }
        }
    }
602320
public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr)
    {
        $tokens = $phpcsFile->getTokens();
        $arrayStart = DWS_Helpers_Bracket::bracketStart($phpcsFile, $stackPtr);
        $arrayEnd = DWS_Helpers_Bracket::bracketEnd($phpcsFile, $stackPtr);

        if (!in_array($arrayStart, [$stackPtr, $stackPtr + 1])) {
            $phpcsFile->addError('No whitespace allowed between the array keyword and the opening parenthesis', $stackPtr, 'SpaceAfterKeyword');
        }

        $firstMember = $phpcsFile->findNext(T_WHITESPACE, $arrayStart + 1, $arrayEnd, true);
        if ($firstMember === false && $arrayEnd - $arrayStart !== 1) {
            $phpcsFile->addError('Empty array declaration must have no space between the brackets', $stackPtr, 'SpaceInEmptyArray');
        }
    }
792165
protected function _addNewTemplateDocBlock(File $file, array $annotations, $phpOpenTagIndex, $docBlockCloseIndex) {
		$helper = new DocBlockHelper(new View());

		$annotationStrings = [];
		foreach ($annotations as $key => $annotation) {
			if (!is_object($annotation)) {
				throw new RuntimeException('Must be object: ' . print_r($annotation, true));
			}
			$annotationStrings[$key] = (string)$annotation;
		}

		$annotationString = $helper->classDescription('', '', $annotationStrings);
		if (PHP_EOL !== "\n") {
			$annotationString = str_replace("\n", PHP_EOL, $annotationString);
		}

		if ($phpOpenTagIndex === null) {
			$annotationString = '<?php' . PHP_EOL . $annotationString . PHP_EOL . '?>';
		}

		$docBlock = $annotationString . PHP_EOL;
		if (!$file->getTokens()) {
			$this->_counter[static::COUNT_ADDED] = count($annotations);

			return $docBlock;
		}

		$fixer = $this->_getFixer($file);
		if ($phpOpenTagIndex === null) {
			$fixer->addContentBefore(0, $docBlock);
		} else {
			$fixer->addContent($phpOpenTagIndex, $docBlock);
		}

		$this->_counter[static::COUNT_ADDED] = count($annotations);

		if ($docBlockCloseIndex && $this->_isInlineDocBlockRedundant($file, $annotations, $docBlockCloseIndex)) {
			$tokens = $file->getTokens();
			$docBlockOpenIndex = $tokens[$docBlockCloseIndex]['comment_opener'];
			for ($i = $docBlockCloseIndex + 1; $i >= $docBlockOpenIndex; $i--) {
				$fixer->replaceToken($i, '');
			}

			$this->_counter[static::COUNT_ADDED]--;
		}

		$newContent = $fixer->getContents();

		return $newContent;
	}
1032288
protected function getFixableMethodAnnotations(File $phpCsFile, int $docBlockStartIndex, int $docBlockEndIndex): array
    {
        $tokens = $phpCsFile->getTokens();

        $path = $this->findBasePath($phpCsFile->getFilename());
        if (!$path) {
            // We cannot fix it then for now
            return [];
        }

        $annotations = [];
        for ($i = $docBlockStartIndex + 1; $i < $docBlockEndIndex; $i++) {
            if ($tokens[$i]['code'] !== T_DOC_COMMENT_TAG || $tokens[$i]['content'] !== '@method') {
                continue;
            }

            // T_DOC_COMMENT_STRING invalid, another sniff should check on this
            if (strpos($tokens[$i + 2]['content'], ' ') === false) {
                continue;
            }

            [$class, $method] = explode(' ', $tokens[$i + 2]['content'], 2);

            $ignoredMethods = [
                'getFactory()',
                'getConfig()',
                'getSharedConfig()',
                'getApplication()',
            ];
            if (in_array($method, $ignoredMethods, true)) {
                continue;
            }

            if (substr($class, -9) === 'Interface' || substr($class, 0, 5) === '\\Orm\\') {
                continue;
            }
            if (!preg_match('/^[A-Z]/', $class)) {
                continue;
            }
            if ($this->isAbstract($class)) {
                continue;
            }

            $interface = $class . 'Interface';
            $interfacePathElement = str_replace('\\', DIRECTORY_SEPARATOR, $interface);
            $interfacePath = $path . $interfacePathElement . '.php';

            if (!file_exists($interfacePath)) {
                $phpCsFile->addError(
                    sprintf('Interface missing for %s annotation of %s', $method, $class),
                    $i,
                    'Annotation.Interface.Missing'
                );
                continue;
            }

            $annotation = [
                'index' => $i,
                'method' => $method,
                'class' => $class,
                'interface' => $interface,
            ];

            $annotations[] = $annotation;
        }

        return $annotations;
    }
141111
protected function removeDefaultArgument(File $phpcsFile, int $startIndex, int $endIndex): void
    {
        $this->clearWhitespacesBeforeIndex($phpcsFile, $startIndex);
        for ($i = $startIndex; $i <= $endIndex; ++$i) {
            $phpcsFile->fixer->replaceToken($i, '');
        }
    }
442780
protected function assertSpacing(File $phpCsFile, array $first, array $second): void
    {
        $tokens = $phpCsFile->getTokens();

        $lastIndexOfFirst = $first['tagEnd'];
        $lastLineOfFirst = $tokens[$lastIndexOfFirst]['line'];

        $tagIndexOfSecond = $second['index'];
        $firstLineOfSecond = $tokens[$tagIndexOfSecond]['line'];

        if ($lastLineOfFirst === $firstLineOfSecond - 2) {
            return;
        }

        $error = 'A single newline expected between tags of different types `' . $first['tag'] . '`/`' . $second['tag'] . '`';
        $fix = $phpCsFile->addFixableError($error, $tagIndexOfSecond, 'NewlineBetweenDifferentTypes');
        if (!$fix) {
            return;
        }

        if ($lastLineOfFirst > $firstLineOfSecond - 2) {
            $phpCsFile->fixer->beginChangeset();

            $indentation = $this->getIndentationWhitespace($phpCsFile, $tagIndexOfSecond);
            $phpCsFile->fixer->addNewlineBefore($second['start']);
            $phpCsFile->fixer->addContentBefore($second['start'], $indentation . '*');

            $phpCsFile->fixer->endChangeset();

            return;
        }

        $phpCsFile->fixer->beginChangeset();

        for ($i = $first['tagEnd'] + 1; $i < $second['start']; $i++) {
            if ($tokens[$i]['line'] <= $firstLineOfSecond - 2) {
                continue;
            }

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

        $phpCsFile->fixer->endChangeset();
    }
771063
protected function assertNotThisOrStatic(File $phpCsFile, int $stackPointer): void
    {
        $docBlockEndIndex = $this->findRelatedDocBlock($phpCsFile, $stackPointer);

        if (!$docBlockEndIndex) {
            return;
        }

        $tokens = $phpCsFile->getTokens();

        $docBlockStartIndex = $tokens[$docBlockEndIndex]['comment_opener'];

        for ($i = $docBlockStartIndex + 1; $i < $docBlockEndIndex; $i++) {
            if ($tokens[$i]['type'] !== 'T_DOC_COMMENT_TAG') {
                continue;
            }
            if ($tokens[$i]['content'] !== '@return') {
                continue;
            }

            $classNameIndex = $i + 2;

            if ($tokens[$classNameIndex]['type'] !== 'T_DOC_COMMENT_STRING') {
                continue;
            }

            $content = $tokens[$classNameIndex]['content'];
            if (!$content || strpos($content, '\\') !== 0) {
                continue;
            }

            $classNameWithNamespace = $this->getClassNameWithNamespace($phpCsFile);
            if ($content !== $classNameWithNamespace) {
                continue;
            }

            $phpCsFile->addError('Class name repeated, expected `self` or `$this`.', $classNameIndex, 'TypeHint.Invalid.Class');
        }
    }
766128
protected function readTags(File $phpCsFile, int $docBlockStartIndex, int $docBlockEndIndex): array
    {
        $tokens = $phpCsFile->getTokens();

        $tags = [];

        for ($i = $docBlockStartIndex; $i < $docBlockEndIndex; $i++) {
            if ($tokens[$i]['code'] !== T_DOC_COMMENT_TAG) {
                continue;
            }

            $start = $this->getFirstTokenOfLine($tokens, $i);
            $end = $this->getEndIndex($tokens, $i);
            $tagEnd = $this->getTagEndIndex($tokens, $start, $end);

            $tag = [
                'index' => $i,
                'tag' => $tokens[$i]['content'],
                'tagEnd' => $tagEnd,
                'start' => $start,
                'end' => $end,
                'content' => $this->getContent($tokens, $i, $tagEnd),
            ];
            $tags[] = $tag;
            $i = $end;
        }

        return $tags;
    }