Returns true if the error was recorded and should be fixed.
public addFixableError ( string $error, integer $stackPtr, string $code = '', array $data = [], integer $severity ) : boolean | ||
$error | string | The error message. |
$stackPtr | integer | The stack position where the error occurred. |
$code | string | A violation code unique to the sniff message. |
$data | array | Replacements for the error message. |
$severity | integer | The severity level for this error. A value of 0 will be converted into the default severity level. |
return | boolean |
/** * 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(PHP_CodeSniffer_File $phpcsFile, $stackPtr) { $tokens = $phpcsFile->getTokens(); $lastLineChecked = $tokens[$stackPtr]['line']; for ($i = $stackPtr + 1; $i < $tokens[$stackPtr]['comment_closer'] - 1; $i++) { // We are only interested in the beginning of the line. if ($tokens[$i]['line'] === $lastLineChecked) { continue; } // The first token on the line must be a whitespace followed by a star. if ($tokens[$i]['code'] === T_DOC_COMMENT_WHITESPACE) { if ($tokens[$i + 1]['code'] !== T_DOC_COMMENT_STAR) { $error = 'Doc comment star missing'; $fix = $phpcsFile->addFixableError($error, $i, 'StarMissing'); if ($fix === true) { $phpcsFile->fixer->replaceToken($i, str_repeat(' ', $tokens[$stackPtr]['column']) . '* '); } } } else { if ($tokens[$i]['code'] !== T_DOC_COMMENT_STAR) { $error = 'Doc comment star missing'; $fix = $phpcsFile->addFixableError($error, $i, 'StarMissing'); if ($fix === true) { $phpcsFile->fixer->addContentBefore($i, str_repeat(' ', $tokens[$stackPtr]['column']) . '* '); } } } $lastLineChecked = $tokens[$i]['line']; } //end for }
/** * Processes this test, when one of its tokens is encountered. * * @param PHP_CodeSniffer_File $phpcsFile All the tokens found in the document. * @param integer $stackPtr The position of the current token * in the stack passed in $tokens. * @return void */ public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr) { $tokens = $phpcsFile->getTokens(); $next = $phpcsFile->findNext(T_WHITESPACE, $stackPtr + 1, null, true); if ($tokens[$next]['code'] !== T_WHITESPACE && $next !== $stackPtr + 2) { // Last character in a line is ok. if ($tokens[$next]['line'] === $tokens[$stackPtr]['line']) { $error = 'Missing space after comma'; $phpcsFile->addFixableError($error, $next); // Fix the error if ($phpcsFile->fixer->enabled === true) { $phpcsFile->fixer->addContent($stackPtr, ' '); } } } $previous = $phpcsFile->findPrevious(T_WHITESPACE, $stackPtr - 1, null, true); if ($tokens[$previous]['code'] !== T_WHITESPACE && $previous !== $stackPtr - 1) { $error = 'Space before comma, expected none, though'; $phpcsFile->addFixableError($error, $next); // Fix the error if ($phpcsFile->fixer->enabled === true) { $content = $tokens[$previous]['content']; $phpcsFile->fixer->replaceToken($previous + 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(PHP_CodeSniffer_File $phpcsFile, $stackPtr) { $tokens = $phpcsFile->getTokens(); if (isset($tokens[$stackPtr]['parenthesis_opener']) === true) { $parenOpener = $tokens[$stackPtr]['parenthesis_opener']; $parenCloser = $tokens[$stackPtr]['parenthesis_closer']; if ($tokens[$parenOpener + 1]['code'] === T_WHITESPACE) { $gap = strlen($tokens[$parenOpener + 1]['content']); $error = 'Expected 0 spaces after opening bracket; %s found'; $data = array($gap); $fix = $phpcsFile->addFixableError($error, $parenOpener + 1, 'SpacingAfterOpenBrace', $data); if ($fix === true && $phpcsFile->fixer->enabled === true) { $phpcsFile->fixer->replaceToken($parenOpener + 1, ''); } } if ($tokens[$parenOpener]['line'] === $tokens[$parenCloser]['line'] && $tokens[$parenCloser - 1]['code'] === T_WHITESPACE) { $gap = strlen($tokens[$parenCloser - 1]['content']); $error = 'Expected 0 spaces before closing bracket; %s found'; $data = array($gap); $fix = $phpcsFile->addFixableError($error, $parenCloser - 1, 'SpaceBeforeCloseBrace', $data); if ($fix === true && $phpcsFile->fixer->enabled === true) { $phpcsFile->fixer->replaceToken($parenCloser - 1, ''); } } } //end if }
/** * Processes the tokens that this sniff is interested in. * * @param PHP_CodeSniffer_File $phpcsFile The file where the token was found. * @param int $stackPtr The position in the stack where * the token was found. * * @return void */ public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr) { $tokens = $phpcsFile->getTokens(); $colour = $tokens[$stackPtr]['content']; $expected = strtoupper($colour); if ($colour !== $expected) { $error = 'CSS colours must be defined in uppercase; expected %s but found %s'; $data = array($expected, $colour); $fix = $phpcsFile->addFixableError($error, $stackPtr, 'NotUpper', $data); if ($fix === true && $phpcsFile->fixer->enabled === true) { $phpcsFile->fixer->replaceToken($stackPtr, $expected); } } // Now check if shorthand can be used. if (strlen($colour) !== 7) { return; } if ($colour[1] === $colour[2] && $colour[3] === $colour[4] && $colour[5] === $colour[6]) { $expected = '#' . $colour[1] . $colour[3] . $colour[5]; $error = 'CSS colours must use shorthand if available; expected %s but found %s'; $data = array($expected, $colour); $fix = $phpcsFile->addFixableError($error, $stackPtr, 'Shorthand', $data); if ($fix === true && $phpcsFile->fixer->enabled === true) { $phpcsFile->fixer->replaceToken($stackPtr, $expected); } } }
/** * @inheritdoc */ public function process(\PHP_CodeSniffer_File $phpcsFile, $stackPtr) { $tokens = $phpcsFile->getTokens(); if ($tokens[$stackPtr]['content'] === '!') { $prevIndex = $phpcsFile->findPrevious(T_WHITESPACE, $stackPtr - 1, null, true); if ($tokens[$prevIndex]['content'] !== '!') { return; } $fix = $phpcsFile->addFixableError('`!!` cast not allowed, use `(bool)`', $stackPtr); if ($fix) { $phpcsFile->fixer->replaceToken($prevIndex, ''); $phpcsFile->fixer->replaceToken($stackPtr, '(bool)'); } return; } $content = $tokens[$stackPtr]['content']; $key = strtolower($content); if (!isset(static::$matching[$key])) { return; } $fix = $phpcsFile->addFixableError($content . ' found, expected ' . static::$matching[$key], $stackPtr); if ($fix) { $phpcsFile->fixer->replaceToken($stackPtr, static::$matching[$key]); } }
/** * 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(PHP_CodeSniffer_File $phpcsFile, $stackPtr) { $tokens = $phpcsFile->getTokens(); if ($tokens[$stackPtr + 1]['code'] === T_SEMICOLON) { // No content for this language construct. return; } if ($tokens[$stackPtr + 1]['code'] === T_WHITESPACE) { $content = $tokens[$stackPtr + 1]['content']; $contentLength = strlen($content); if ($contentLength !== 1) { $error = 'Language constructs must be followed by a single space; expected 1 space but found %s'; $data = array($contentLength); $fix = $phpcsFile->addFixableError($error, $stackPtr, 'IncorrectSingle', $data); if ($fix === true) { $phpcsFile->fixer->replaceToken($stackPtr + 1, ' '); } } } else { $error = 'Language constructs must be followed by a single space; expected "%s" but found "%s"'; $data = array($tokens[$stackPtr]['content'] . ' ' . $tokens[$stackPtr + 1]['content'], $tokens[$stackPtr]['content'] . $tokens[$stackPtr + 1]['content']); $fix = $phpcsFile->addFixableError($error, $stackPtr, 'Incorrect', $data); if ($fix === true) { $phpcsFile->fixer->addContent($stackPtr, ' '); } } //end if }
/** * Processes this test, when one of its tokens is encountered. * * @param PHP_CodeSniffer_File $phpcsFile The file being scanned. * @param integer $stackPtr The position of the current token * in the stack passed in $tokens. * @return void */ public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr) { $tokens = $phpcsFile->getTokens(); $line = $tokens[$stackPtr]['line']; if ($stackPtr > 0 && $tokens[$stackPtr - 1]['line'] !== $line) { return; } if (strpos($tokens[$stackPtr]['content'], ' ') !== false) { $error = 'Double space found'; $phpcsFile->addFixableError($error, $stackPtr); if ($phpcsFile->fixer->enabled === true) { $phpcsFile->fixer->replaceToken($stackPtr, ' '); } } if (strpos($tokens[$stackPtr]['content'], " \t") !== false) { $error = 'Space and tab found'; $phpcsFile->addFixableError($error, $stackPtr); if ($phpcsFile->fixer->enabled === true) { $phpcsFile->fixer->replaceToken($stackPtr, ' '); } } if (strpos($tokens[$stackPtr]['content'], "\t ") !== false) { $error = 'Tab and space found'; $phpcsFile->addFixableError($error, $stackPtr); if ($phpcsFile->fixer->enabled === true) { $phpcsFile->fixer->replaceToken($stackPtr, ' '); } } }
/** * 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(PHP_CodeSniffer_File $phpcsFile, $stackPtr) { $tokens = $phpcsFile->getTokens(); $openTag = $tokens[$stackPtr]; if ($openTag['content'] === '<?') { $error = 'Short PHP opening tag used; expected "<?php" but found "%s"'; $data = array($openTag['content']); $fix = $phpcsFile->addFixableError($error, $stackPtr, 'Found', $data); if ($fix === true) { $phpcsFile->fixer->replaceToken($stackPtr, '<?php'); } $phpcsFile->recordMetric($stackPtr, 'PHP short open tag used', 'yes'); } else { $phpcsFile->recordMetric($stackPtr, 'PHP short open tag used', 'no'); } if ($openTag['code'] === T_OPEN_TAG_WITH_ECHO) { $nextVar = $tokens[$phpcsFile->findNext(PHP_CodeSniffer_Tokens::$emptyTokens, $stackPtr + 1, null, true)]; $error = 'Short PHP opening tag used with echo; expected "<?php echo %s ..." but found "%s %s ..."'; $data = array($nextVar['content'], $openTag['content'], $nextVar['content']); $fix = $phpcsFile->addFixableError($error, $stackPtr, 'EchoFound', $data); if ($fix === true) { if ($tokens[$stackPtr + 1]['code'] !== T_WHITESPACE) { $phpcsFile->fixer->replaceToken($stackPtr, '<?php echo '); } else { $phpcsFile->fixer->replaceToken($stackPtr, '<?php echo'); } } } }
/** * Processes this sniff, 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 * * @SuppressWarnings(PHPMD.CyclomaticComplexity) */ public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr) { $tokens = $phpcsFile->getTokens(); $token = $tokens[$stackPtr]; $content = $token['content']; // Check if the previous is an asterisk, if so => error. if ($token['code'] === T_DOC_COMMENT_STRING) { if ($tokens[$stackPtr - 1]['code'] === T_DOC_COMMENT_STAR) { $fix = $phpcsFile->addFixableError('Whitespace must be added after the asterisk in doc comments. Expected "* ' . $content . '" but "*' . $content . '" was found.', $stackPtr); if ($fix === true) { $phpcsFile->fixer->replaceToken($stackPtr, ' ' . $content); } } return; } $trimmed = ltrim($content); // We ignore empty lines in doc comment. if ($trimmed == '*') { return; } if (strpos($trimmed, '*') === 0 && strpos($trimmed, ' ') != 1 && strpos($trimmed, '/') != 1 && strpos($trimmed, "\n") != 1) { $asterisk = strpos($content, '*'); $prefix = substr($content, 0, $asterisk + 1) . ' '; $fix = $phpcsFile->addFixableError('Whitespace must be added after the asterisk in doc comments. Expected "' . $prefix . ltrim($trimmed, '*') . '" but "' . $content . '" was found.', $stackPtr); if ($fix === true) { $replacement = $prefix . ltrim($trimmed, '*'); $phpcsFile->fixer->replaceToken($stackPtr, $replacement); } } }
/** * @inheritdoc */ public function process(\PHP_CodeSniffer_File $phpCsFile, $stackPointer) { $tokens = $phpCsFile->getTokens(); $level = $tokens[$stackPointer]['level']; if ($level < 1) { return; } $openingBraceIndex = $phpCsFile->findNext(T_OPEN_CURLY_BRACKET, $stackPointer + 1); if (!$openingBraceIndex) { $openingParenthesisIndex = $phpCsFile->findNext(T_OPEN_PARENTHESIS, $stackPointer + 1); $closingParenthesisIndex = $tokens[$openingParenthesisIndex]['parenthesis_closer']; $semicolonIndex = $phpCsFile->findNext(PHP_CodeSniffer_Tokens::$emptyTokens, $closingParenthesisIndex + 1, null, true); $nextContentIndex = $phpCsFile->findNext(T_WHITESPACE, $semicolonIndex + 1, null, true); if ($tokens[$nextContentIndex]['line'] - $tokens[$semicolonIndex]['line'] <= 1) { $fix = $phpCsFile->addFixableError('Every function/method needs a newline afterwards', $closingParenthesisIndex, 'Abstract'); if ($fix) { $phpCsFile->fixer->addNewline($semicolonIndex); } } return; } $closingBraceIndex = $tokens[$openingBraceIndex]['scope_closer']; // Ignore closures $nextIndex = $phpCsFile->findNext(PHP_CodeSniffer_Tokens::$emptyTokens, $closingBraceIndex + 1, null, true); if (in_array($tokens[$nextIndex]['content'], [';', ',', ')'])) { return; } $nextContentIndex = $phpCsFile->findNext(T_WHITESPACE, $closingBraceIndex + 1, null, true); if (!$nextContentIndex || $tokens[$nextContentIndex]['line'] - $tokens[$closingBraceIndex]['line'] <= 1) { $fix = $phpCsFile->addFixableError('Every function/method needs a newline afterwards', $closingBraceIndex, 'Concrete'); if ($fix) { $phpCsFile->fixer->addNewline($closingBraceIndex); } } }
/** * @param \PHP_CodeSniffer_File $phpcsFile * @param int $stackPtr * * @return void */ protected function processIncDec(\PHP_CodeSniffer_File $phpcsFile, $stackPtr) { $tokens = $phpcsFile->getTokens(); $nextIndex = $phpcsFile->findNext(T_WHITESPACE, $stackPtr + 1, null, true); if ($tokens[$nextIndex]['code'] === T_VARIABLE) { if ($nextIndex - $stackPtr === 1) { return; } $fix = $phpcsFile->addFixableError('No whitespace should be between incrementor and variable.', $stackPtr); if ($fix) { $phpcsFile->fixer->beginChangeset(); $phpcsFile->fixer->replaceToken($stackPtr + 1, ''); $phpcsFile->fixer->endChangeset(); } return; } $prevIndex = $phpcsFile->findPrevious(T_WHITESPACE, $stackPtr - 1, null, true); if ($tokens[$prevIndex]['code'] === T_VARIABLE) { if ($stackPtr - $prevIndex === 1) { return; } $fix = $phpcsFile->addFixableError('No whitespace should be between variable and incrementor.', $stackPtr); if ($fix) { $phpcsFile->fixer->beginChangeset(); $phpcsFile->fixer->replaceToken($stackPtr - 1, ''); $phpcsFile->fixer->endChangeset(); } return; } }
/** * Processes the tokens that this sniff is interested in. * * @param PHP_CodeSniffer_File $phpcsFile The file where the token was found. * @param int $stackPtr The position in the stack where * the token was found. * * @return void */ public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr) { $tokens = $phpcsFile->getTokens(); // Do not check nested style definitions as, for example, in @media style rules. $nested = $phpcsFile->findNext(T_OPEN_CURLY_BRACKET, $stackPtr + 1, $tokens[$stackPtr]['bracket_closer']); if ($nested !== false) { return; } // Find the first blank line before this opening brace, unless we get // to another style definition, comment or the start of the file. $endTokens = array(T_OPEN_CURLY_BRACKET => T_OPEN_CURLY_BRACKET, T_CLOSE_CURLY_BRACKET => T_CLOSE_CURLY_BRACKET, T_OPEN_TAG => T_OPEN_TAG); $endTokens += PHP_CodeSniffer_Tokens::$commentTokens; $foundContent = false; $currentLine = $tokens[$stackPtr]['line']; for ($i = $stackPtr - 1; $i >= 0; $i--) { if (isset($endTokens[$tokens[$i]['code']]) === true) { break; } // A comma must be followed by a new line character. if ($tokens[$i]['code'] === T_COMMA && strpos($tokens[$i + 1]['content'], $phpcsFile->eolChar) === false) { $error = 'Multiple selectors should each be on a single line'; $fix = $phpcsFile->addFixableError($error, $i + 1, 'MultipleSelectors'); if ($fix === true) { $phpcsFile->fixer->addNewline($i); } } // Selectors must be on the same line. if ($tokens[$i]['code'] === T_WHITESPACE && strpos($tokens[$i]['content'], $phpcsFile->eolChar) !== false && isset($endTokens[$tokens[$i - 1]['code']]) === false && in_array($tokens[$i - 1]['code'], array(T_WHITESPACE, T_COMMA)) === false) { $error = 'Selectors must be on a single line'; $fix = $phpcsFile->addFixableError($error, $i, 'SeletorSingleLine'); if ($fix === true) { $phpcsFile->fixer->replaceToken($i, str_replace($phpcsFile->eolChar, ' ', $tokens[$i]['content'])); } } if ($tokens[$i]['line'] === $currentLine) { if ($tokens[$i]['code'] !== T_WHITESPACE) { $foundContent = true; } continue; } // We changed lines. if ($foundContent === false) { // Before we throw an error, make sure we are not looking // at a gap before the style definition. $prev = $phpcsFile->findPrevious(T_WHITESPACE, $i, null, true); if ($prev !== false && isset($endTokens[$tokens[$prev]['code']]) === false) { $error = 'Blank lines are not allowed between class names'; $fix = $phpcsFile->addFixableError($error, $i + 1, 'BlankLinesFound'); if ($fix === true) { $phpcsFile->fixer->replaceToken($i + 1, ''); } } break; } $foundContent = false; $currentLine = $tokens[$i]['line']; } //end for }
/** * Processes this test, when one of its tokens is encountered. * * @param PHP_CodeSniffer_File $phpcsFile All the tokens found in the document. * @param integer $stackPtr The position of the current token * in the stack passed in $tokens. * @return void */ public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr) { $tokens = $phpcsFile->getTokens(); // Make sure there is one space before. $previousToken = $phpcsFile->findPrevious(T_WHITESPACE, $stackPtr - 1, null, true); if ($stackPtr - $previousToken === 1) { $error = 'Expected 1 space before ternary IF, none found'; $phpcsFile->addFixableError($error, $stackPtr, 'NotFound'); if ($phpcsFile->fixer->enabled === true) { $phpcsFile->fixer->addContent($previousToken, ' '); } } // Make sure there is one space after - but not for short ternary. $nextToken = $phpcsFile->findNext(T_WHITESPACE, $stackPtr + 1, null, true); $shortTernary = false; if ($tokens[$nextToken]['code'] === T_INLINE_ELSE) { $shortTernary = true; if ($nextToken - $stackPtr > 1) { $error = 'Expected no space between short ternary IF/ELSE, 1 found'; $phpcsFile->addFixableError($error, $stackPtr, 'TooMany'); if ($phpcsFile->fixer->enabled === true) { $phpcsFile->fixer->replaceToken($stackPtr + 1, ''); } } } if (!$shortTernary && $nextToken - $stackPtr === 1) { $error = 'Expected 1 space after ternary IF, none found'; $phpcsFile->addFixableError($error, $stackPtr, 'NotFound'); if ($phpcsFile->fixer->enabled === true) { $phpcsFile->fixer->addContent($stackPtr, ' '); } } // Make sure the : has the correct spacing. $inlineElse = $phpcsFile->findNext(T_INLINE_ELSE, $stackPtr + 1, null, false); if (!$shortTernary) { $previousToken = $phpcsFile->findPrevious(T_WHITESPACE, $inlineElse - 1, null, true); if ($inlineElse - $previousToken === 1) { $error = 'Expected 1 space before ternary ELSE, none found'; $phpcsFile->addFixableError($error, $inlineElse, 'NotFound'); if ($phpcsFile->fixer->enabled === true) { $phpcsFile->fixer->addContent($previousToken, ' '); } } } $nextToken = $phpcsFile->findNext(T_WHITESPACE, $inlineElse + 1, null, true); if ($nextToken - $inlineElse === 1) { $error = 'Expected 1 space after ternary ELSE, none found'; $phpcsFile->addFixableError($error, $inlineElse, 'NotFound'); if ($phpcsFile->fixer->enabled === true) { $phpcsFile->fixer->addContent($inlineElse, ' '); } } }
/** * Processes the tokens that this sniff is interested in. * * @param PHP_CodeSniffer_File $phpcsFile The file where the token was found. * @param int $stackPtr The position in the stack where * the token was found. * * @return void */ public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr) { $tokens = $phpcsFile->getTokens(); $prev = $phpcsFile->findPrevious(PHP_CodeSniffer_Tokens::$emptyTokens, $stackPtr - 1, null, true); if ($tokens[$prev]['code'] !== T_STYLE) { // The colon is not part of a style definition. return; } if ($tokens[$prev]['content'] === 'progid') { // Special case for IE filters. return; } if ($tokens[$stackPtr - 1]['code'] === T_WHITESPACE) { $error = 'There must be no space before a colon in a style definition'; $fix = $phpcsFile->addFixableError($error, $stackPtr, 'Before'); if ($fix === true) { $phpcsFile->fixer->replaceToken($stackPtr - 1, ''); } } if ($tokens[$stackPtr + 1]['code'] === T_SEMICOLON) { // Empty style definition, ignore it. return; } if ($tokens[$stackPtr + 1]['code'] !== T_WHITESPACE) { $error = 'Expected 1 space after colon in style definition; 0 found'; $fix = $phpcsFile->addFixableError($error, $stackPtr, 'NoneAfter'); if ($fix === true) { $phpcsFile->fixer->addContent($stackPtr, ' '); } } else { $content = $tokens[$stackPtr + 1]['content']; if (strpos($content, $phpcsFile->eolChar) === false) { $length = strlen($content); if ($length !== 1) { $error = 'Expected 1 space after colon in style definition; %s found'; $data = array($length); $fix = $phpcsFile->addFixableError($error, $stackPtr, 'After', $data); if ($fix === true) { $phpcsFile->fixer->replaceToken($stackPtr + 1, ' '); } } } else { $error = 'Expected 1 space after colon in style definition; newline found'; $fix = $phpcsFile->addFixableError($error, $stackPtr, 'AfterNewline'); if ($fix === true) { $phpcsFile->fixer->replaceToken($stackPtr + 1, ' '); } } } //end if }
/** * Processes this sniff, 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(PHP_CodeSniffer_File $phpcsFile, $stackPtr) { // We are only interested if this is the first open tag and in a file // that only contains PHP code. if ($stackPtr !== 0) { if ($phpcsFile->findPrevious(array(T_OPEN_TAG, T_INLINE_HTML), $stackPtr - 1) !== false) { return; } } if ($phpcsFile->findNext(T_INLINE_HTML, $stackPtr + 1) !== false) { return; } // Skip to the end of the file. $tokens = $phpcsFile->getTokens(); $lastToken = $phpcsFile->numTokens - 1; // Hard-coding the expected \n in this sniff as it is PSR-2 specific and // PSR-2 enforces the use of unix style newlines. if (substr($tokens[$lastToken]['content'], -1) !== "\n") { $error = 'Expected 1 newline at end of file; 0 found'; $fix = $phpcsFile->addFixableError($error, $lastToken, 'NoneFound'); if ($fix === true && $phpcsFile->fixer->enabled === true) { $phpcsFile->fixer->addNewline($lastToken); } return; } // Go looking for the last non-empty line. $lastLine = $tokens[$lastToken]['line']; if ($tokens[$lastToken]['code'] === T_WHITESPACE) { $lastCode = $phpcsFile->findPrevious(T_WHITESPACE, $lastToken - 1, null, true); } else { $lastCode = $lastToken; } $lastCodeLine = $tokens[$lastCode]['line']; $blankLines = $lastLine - $lastCodeLine; if ($blankLines > 0) { $error = 'Expected 1 blank line at end of file; %s found'; $data = array($blankLines + 1); $fix = $phpcsFile->addFixableError($error, $lastCode, 'TooMany', $data); if ($fix === true && $phpcsFile->fixer->enabled === true) { $phpcsFile->fixer->beginChangeset(); $phpcsFile->fixer->replaceToken($lastCode, rtrim($tokens[$lastCode]['content'])); for ($i = $lastCode + 1; $i < $lastToken; $i++) { $phpcsFile->fixer->replaceToken($i, ''); } $phpcsFile->fixer->replaceToken($lastToken, $phpcsFile->eolChar); $phpcsFile->fixer->endChangeset(); } } //end if }
/** * Processes this sniff, 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(PHP_CodeSniffer_File $phpcsFile, $stackPtr) { if ($phpcsFile->findNext(T_INLINE_HTML, $stackPtr + 1) !== false) { return $phpcsFile->numTokens + 1; } // Skip to the end of the file. $tokens = $phpcsFile->getTokens(); $lastToken = $phpcsFile->numTokens - 1; if ($tokens[$lastToken]['content'] === '') { $lastToken--; } // Hard-coding the expected \n in this sniff as it is PSR-2 specific and // PSR-2 enforces the use of unix style newlines. if (substr($tokens[$lastToken]['content'], -1) !== "\n") { $error = 'Expected 1 newline at end of file; 0 found'; $fix = $phpcsFile->addFixableError($error, $lastToken, 'NoneFound'); if ($fix === true) { $phpcsFile->fixer->addNewline($lastToken); } $phpcsFile->recordMetric($stackPtr, 'Number of newlines at EOF', '0'); return $phpcsFile->numTokens + 1; } // Go looking for the last non-empty line. $lastLine = $tokens[$lastToken]['line']; if ($tokens[$lastToken]['code'] === T_WHITESPACE || $tokens[$lastToken]['code'] === T_DOC_COMMENT_WHITESPACE) { $lastCode = $phpcsFile->findPrevious(array(T_WHITESPACE, T_DOC_COMMENT_WHITESPACE), $lastToken - 1, null, true); } else { $lastCode = $lastToken; } $lastCodeLine = $tokens[$lastCode]['line']; $blankLines = $lastLine - $lastCodeLine + 1; $phpcsFile->recordMetric($stackPtr, 'Number of newlines at EOF', $blankLines); if ($blankLines > 1) { $error = 'Expected 1 blank line at end of file; %s found'; $data = array($blankLines); $fix = $phpcsFile->addFixableError($error, $lastCode, 'TooMany', $data); if ($fix === true) { $phpcsFile->fixer->beginChangeset(); $phpcsFile->fixer->replaceToken($lastCode, rtrim($tokens[$lastCode]['content'])); for ($i = $lastCode + 1; $i < $lastToken; $i++) { $phpcsFile->fixer->replaceToken($i, ''); } $phpcsFile->fixer->replaceToken($lastToken, $phpcsFile->eolChar); $phpcsFile->fixer->endChangeset(); } } // Skip the rest of the file. return $phpcsFile->numTokens + 1; }
/** * Processes this test, when one of its tokens is encountered. * * @param PHP_CodeSniffer_File $phpcsFile The file being scanned. * @param integer $stackPtr The position of the current token in the * stack passed in $tokens. * @return void */ public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr) { $tokens = $phpcsFile->getTokens(); if ($tokens[$stackPtr - 1]['code'] !== T_WHITESPACE) { $message = 'Expected 1 space before ., but 0 found'; $phpcsFile->addFixableError($message, $stackPtr, 'MissingBefore'); $this->_addSpace($phpcsFile, $stackPtr - 1); } else { $content = str_replace("\r\n", "\n", $tokens[$stackPtr - 1]['content']); $spaces = strlen($content); if ($spaces > 1) { $message = 'Expected 1 space before ., but %d found'; $data = array($spaces); // We cannot remove the indentation, let another sniff take care of this here //$phpcsFile->addError($message, $stackPtr, 'TooManyBefore', $data); } } if ($tokens[$stackPtr + 1]['code'] !== T_WHITESPACE) { $message = 'Expected 1 space after ., but 0 found'; $phpcsFile->addFixableError($message, $stackPtr, 'MissingAfter'); $this->_addSpace($phpcsFile, $stackPtr); } else { $content = str_replace("\r\n", "\n", $tokens[$stackPtr + 1]['content']); $spaces = strlen($content); if ($spaces > 1) { $message = 'Expected 1 space after ., but %d found'; $data = array($spaces); // Too many spaces should another sniff take care of //$phpcsFile->addError($message, $stackPtr, 'TooManyAfter', $data); } } }
/** * Processes this test, when one of its tokens is encountered. * * @param PHP_CodeSniffer_File $phpcsFile The file being scanned. * @param integer $stackPtr The position of the current token * in the stack passed in $tokens. * @return void */ public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr) { $tokens = $phpcsFile->getTokens(); if (isset($tokens[$stackPtr]['scope_opener']) === false) { // Probably an interface method. return; } $openBrace = $tokens[$stackPtr]['scope_opener']; $nextContent = $phpcsFile->findNext(T_WHITESPACE, $openBrace + 1, null, true); if ($nextContent === $tokens[$stackPtr]['scope_closer']) { // The next bit of content is the closing brace, so this // is an empty function and should have a blank line // between the opening and closing braces. return; } $braceLine = $tokens[$openBrace]['line']; $nextLine = $tokens[$nextContent]['line']; $found = $nextLine - $braceLine - 1; if ($found > 0) { $error = 'Expected 0 blank lines after opening function brace; %s found'; $data = array($found); $nextContent = $phpcsFile->findNext(T_WHITESPACE, $openBrace + 1, null, true); // If there is content after the brace and on the same line, we cannot fix this if ($nextContent && $tokens[$nextContent]['line'] === $nextLine) { $phpcsFile->addError($error, $openBrace, 'SpacingAfter', $data); return; } $phpcsFile->addFixableError($error, $openBrace, 'SpacingAfter', $data); //TODO } }
/** * 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(PHP_CodeSniffer_File $phpcsFile, $stackPtr, $currScope) { $tokens = $phpcsFile->getTokens(); $methodName = $phpcsFile->getDeclarationName($stackPtr); if ($methodName === null) { // Ignore closures. return; } $modifier = $phpcsFile->findPrevious(PHP_CodeSniffer_Tokens::$scopeModifiers, $stackPtr); if ($modifier === false || $tokens[$modifier]['line'] !== $tokens[$stackPtr]['line']) { $error = 'Visibility must be declared on method "%s"'; $data = array($methodName); $previous = $phpcsFile->findPrevious(array(T_WHITESPACE), $stackPtr - 1, null, true); // Only correct the trivial cases for now if (!$modifier && $tokens[$modifier]['line'] === $tokens[$stackPtr]['line']) { $phpcsFile->addFixableError($error, $stackPtr, 'Missing', $data); $visbility = 'public'; $name = substr($tokens[$stackPtr]['content'], 1); $totalUnderscores = 0; while (strpos($name, '_') === 0) { $totalUnderscores++; $name = substr($name, 1); } if ($totalUnderscores > 1) { $visbility = 'private'; } elseif ($totalUnderscores > 0) { $visbility = 'protected'; } } else { $phpcsFile->addError($error, $stackPtr, 'Missing', $data); } //TODO } }
/** * Processes this test, when one of its tokens is encountered. * * @param PHP_CodeSniffer_File $phpcsFile All the tokens found in the document. * @param int $stackPtr The position of the current token in * the stack passed in $tokens. * * @return void */ public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr) { $tokens = $phpcsFile->getTokens(); for ($i = $stackPtr + 1; $i < $phpcsFile->numTokens; $i++) { if ($tokens[$i]['column'] !== 1 || $tokens[$i]['code'] !== T_WHITESPACE) { continue; } if ($tokens[$i]['content'][0] === "\t") { $error = 'Spaces must be used to indent lines; tabs are not allowed'; $fix = $phpcsFile->addFixableError($error, $i, 'TabsUsed'); $phpcsFile->recordMetric($i, 'Line indent', 'tabs'); if ($fix === true && $phpcsFile->fixer->enabled === true) { // Replace tabs with spaces, usign an indent of 4 spaces. // Other sniffs can then correct the indent if they need to. $newContent = str_replace("\t", ' ', $tokens[$i]['content']); $phpcsFile->fixer->replaceToken($i, $newContent); } } else { if ($tokens[$i]['content'][0] === ' ') { $phpcsFile->recordMetric($i, 'Line indent', 'spaces'); } } } // Ignore the rest of the file. return $phpcsFile->numTokens + 1; }
/** * @param \PHP_CodeSniffer_File $phpCsFile * @param int $stackPointer * * @return void */ protected function addFixableMissingDocBlock(\PHP_CodeSniffer_File $phpCsFile, $stackPointer) { $fix = $phpCsFile->addFixableError(basename($phpCsFile->getFilename()) . ' has no File Doc Block.', $stackPointer); if ($fix) { $this->addFileDocBlock($phpCsFile, 0); } }
/** * Processes this sniff, 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(PHP_CodeSniffer_File $phpcsFile, $stackPtr) { $tokens = $phpcsFile->getTokens(); if (substr($tokens[$stackPtr]['content'], 0, 2) !== '//') { return; } $commentLine = $tokens[$stackPtr]['line']; $lastContent = $phpcsFile->findPrevious(T_WHITESPACE, $stackPtr - 1, null, true); if ($tokens[$lastContent]['line'] !== $commentLine) { return; } if ($tokens[$lastContent]['code'] === T_CLOSE_CURLY_BRACKET) { return; } // Special case for JS files. if ($tokens[$lastContent]['code'] === T_COMMA || $tokens[$lastContent]['code'] === T_SEMICOLON) { $lastContent = $phpcsFile->findPrevious(T_WHITESPACE, $lastContent - 1, null, true); if ($tokens[$lastContent]['code'] === T_CLOSE_CURLY_BRACKET) { return; } } $error = 'Comments may not appear after statements'; $fix = $phpcsFile->addFixableError($error, $stackPtr, 'Found'); if ($fix === true) { $phpcsFile->fixer->addNewlineBefore($stackPtr); } }
/** * Processes this test, when one of its tokens is encountered. * * @param PHP_CodeSniffer_File $phpcsFile All the tokens found in the document. * @param int $stackPtr The position of the current token in * the stack passed in $tokens. * * @return void */ public function process(PHP_CodeSniffer_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') { $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, 'MissedBlankLineBeforeRetrun'); 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; }
/** * 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(PHP_CodeSniffer_File $phpcsFile, $stackPtr) { $tokens = $phpcsFile->getTokens(); $prevType = $tokens[$stackPtr - 1]['code']; if (isset(PHP_CodeSniffer_Tokens::$emptyTokens[$prevType]) === false) { return; } $nonSpace = $phpcsFile->findPrevious(PHP_CodeSniffer_Tokens::$emptyTokens, $stackPtr - 2, null, true); if ($tokens[$nonSpace]['code'] === T_SEMICOLON) { // Empty statement. return; } $expected = $tokens[$nonSpace]['content'] . ';'; $found = $phpcsFile->getTokensAsString($nonSpace, $stackPtr - $nonSpace) . ';'; $error = 'Space found before semicolon; expected "%s" but found "%s"'; $data = array($expected, $found); $fix = $phpcsFile->addFixableError($error, $stackPtr, 'Incorrect', $data); if ($fix === true) { $phpcsFile->fixer->beginChangeset(); for ($i = $stackPtr - 1; $i > $nonSpace; $i--) { $phpcsFile->fixer->replaceToken($i, ''); } $phpcsFile->fixer->endChangeset(); } }
/** * Processes this sniff, 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(PHP_CodeSniffer_File $phpcsFile, $stackPtr) { $tokens = $phpcsFile->getTokens(); // Make sure this file only contains PHP code. for ($i = 0; $i < $phpcsFile->numTokens; $i++) { if ($tokens[$i]['code'] === T_INLINE_HTML && trim($tokens[$i]['content']) !== '') { return $phpcsFile->numTokens; } } // Find the last non-empty token. for ($last = $phpcsFile->numTokens - 1; $last > 0; $last--) { if (trim($tokens[$last]['content']) !== '') { break; } } if ($tokens[$last]['code'] === T_CLOSE_TAG) { $error = 'A closing tag is not permitted at the end of a PHP file'; $fix = $phpcsFile->addFixableError($error, $last, 'NotAllowed'); if ($fix === true) { $phpcsFile->fixer->replaceToken($last, ''); } $phpcsFile->recordMetric($stackPtr, 'PHP closing tag at end of PHP-only file', 'yes'); } else { $phpcsFile->recordMetric($stackPtr, 'PHP closing tag at end of PHP-only file', 'no'); } // Ignore the rest of the file. return $phpcsFile->numTokens; }
/** * Processes this test, when one of its tokens is encountered. * * @param PHP_CodeSniffer_File $phpcsFile All the tokens found in the document. * @param integer $stackPtr The position of the current token * in the stack passed in $tokens. * @return void */ public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr) { $tokens = $phpcsFile->getTokens(); $next = $phpcsFile->findNext(T_WHITESPACE, $stackPtr + 1, null, true); if ($tokens[$next]['code'] !== T_WHITESPACE && $next !== $stackPtr + 2) { // Skip if immediate char is comma if ($tokens[$next]['code'] === T_COMMA) { return; } // Last character in a line is ok. if ($tokens[$next]['line'] === $tokens[$stackPtr]['line']) { $error = 'Missing space after comma'; $fix = $phpcsFile->addFixableError($error, $next); if ($fix === true) { $phpcsFile->fixer->beginChangeset(); $phpcsFile->fixer->addContent($stackPtr, ' '); $phpcsFile->fixer->endChangeset(); } } } $previous = $phpcsFile->findPrevious(T_WHITESPACE, $stackPtr - 1, null, true); if ($tokens[$previous]['code'] !== T_WHITESPACE && $previous !== $stackPtr - 1) { $error = 'Space before comma, expected none, though'; $phpcsFile->addError($error, $next); } }
/** * 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(PHP_CodeSniffer_File $phpcsFile, $stackPtr) { $tokens = $phpcsFile->getTokens(); $firstContent = $phpcsFile->findNext(T_WHITESPACE, $stackPtr + 1, null, true); // If the first non-whitespace token is not an opening parenthesis, then we are not concerned. if ($tokens[$firstContent]['code'] !== T_OPEN_PARENTHESIS) { $phpcsFile->recordMetric($stackPtr, 'Brackets around echoed strings', 'no'); return; } $end = $phpcsFile->findNext(array(T_SEMICOLON, T_CLOSE_TAG), $stackPtr, null, false); // If the token before the semi-colon is not a closing parenthesis, then we are not concerned. $prev = $phpcsFile->findPrevious(T_WHITESPACE, $end - 1, null, true); if ($tokens[$prev]['code'] !== T_CLOSE_PARENTHESIS) { $phpcsFile->recordMetric($stackPtr, 'Brackets around echoed strings', 'no'); return; } // If the parenthesis don't match, then we are not concerned. if ($tokens[$firstContent]['parenthesis_closer'] !== $prev) { $phpcsFile->recordMetric($stackPtr, 'Brackets around echoed strings', 'no'); return; } $phpcsFile->recordMetric($stackPtr, 'Brackets around echoed strings', 'yes'); if ($phpcsFile->findNext(PHP_CodeSniffer_Tokens::$operators, $stackPtr, $end, false) === false) { // There are no arithmetic operators in this. $error = 'Echoed strings should not be bracketed'; $fix = $phpcsFile->addFixableError($error, $stackPtr, 'HasBracket'); if ($fix === true) { $phpcsFile->fixer->beginChangeset(); $phpcsFile->fixer->replaceToken($firstContent, ''); $phpcsFile->fixer->replaceToken($end - 1, ''); $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(PHP_CodeSniffer_File $phpcsFile, $stackPtr) { $tokens = $phpcsFile->getTokens(); // We are only interested in function/class/interface doc block comments. $nextToken = $phpcsFile->findNext(PHP_CodeSniffer_Tokens::$emptyTokens, $stackPtr + 1, null, true); $ignore = array(T_CLASS => true, T_INTERFACE => true, T_FUNCTION => true, T_PUBLIC => true, T_PRIVATE => true, T_PROTECTED => true, T_STATIC => true, T_ABSTRACT => true); if (isset($ignore[$tokens[$nextToken]['code']]) === false) { // Could be a file comment. $prevToken = $phpcsFile->findPrevious(PHP_CodeSniffer_Tokens::$emptyTokens, $stackPtr - 1, null, true); if ($tokens[$prevToken]['code'] !== T_OPEN_TAG) { return; } } // There must be one space after each star (unless it is an empty comment line) // and all the stars must be aligned correctly. $requiredColumn = $tokens[$stackPtr]['column'] + 1; $endComment = $tokens[$stackPtr]['comment_closer']; for ($i = $stackPtr + 1; $i <= $endComment; $i++) { if ($tokens[$i]['code'] !== T_DOC_COMMENT_STAR && $tokens[$i]['code'] !== T_DOC_COMMENT_CLOSE_TAG) { continue; } if ($tokens[$i]['column'] !== $requiredColumn) { $error = 'Expected %s space(s) before asterisk; %s found'; $data = array($requiredColumn - 1, $tokens[$i]['column'] - 1); $fix = $phpcsFile->addFixableError($error, $i, 'SpaceBeforeStar', $data); if ($fix === true) { $padding = str_repeat(' ', $requiredColumn - 1); if ($tokens[$i]['column'] === 1) { $phpcsFile->fixer->addContentBefore($i, $padding); } else { $phpcsFile->fixer->replaceToken($i - 1, $padding); } } } if ($tokens[$i]['code'] !== T_DOC_COMMENT_STAR) { continue; } if ($tokens[$i + 2]['line'] !== $tokens[$i]['line']) { // Line is empty. continue; } if ($tokens[$i + 1]['code'] !== T_DOC_COMMENT_WHITESPACE) { $error = 'Expected 1 space after asterisk; 0 found'; $fix = $phpcsFile->addFixableError($error, $i, 'NoSpaceAfterStar'); if ($fix === true) { $phpcsFile->fixer->addContent($i, ' '); } } else { if ($tokens[$i + 2]['code'] === T_DOC_COMMENT_TAG && $tokens[$i + 1]['content'] !== ' ') { $error = 'Expected 1 space after asterisk; %s found'; $data = array(strlen($tokens[$i + 1]['content'])); $fix = $phpcsFile->addFixableError($error, $i, 'SpaceAfterStar', $data); if ($fix === true) { $phpcsFile->fixer->replaceToken($i + 1, ' '); } } } } //end for }
/** * 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(PHP_CodeSniffer_File $phpcsFile, $stackPtr) { $tokens = $phpcsFile->getTokens(); if (isset($tokens[$stackPtr]['scope_opener']) === false) { // Probably an interface method. return; } $openBrace = $tokens[$stackPtr]['scope_opener']; $nextContent = $phpcsFile->findNext(T_WHITESPACE, $openBrace + 1, null, true); if ($nextContent === $tokens[$stackPtr]['scope_closer']) { // The next bit of content is the closing brace, so this // is an empty function and should have a blank line // between the opening and closing braces. return; } $braceLine = $tokens[$openBrace]['line']; $nextLine = $tokens[$nextContent]['line']; $found = $nextLine - $braceLine - 1; if ($found > 0) { $error = 'Expected 0 blank lines after opening function brace; %s found'; $data = array($found); $fix = $phpcsFile->addFixableError($error, $openBrace, 'SpacingAfter', $data); if ($fix === true) { $phpcsFile->fixer->beginChangeset(); for ($i = $openBrace + 1; $i < $nextContent; $i++) { if ($tokens[$i]['line'] === $nextLine) { break; } $phpcsFile->fixer->replaceToken($i, ''); } $phpcsFile->fixer->addNewline($openBrace); $phpcsFile->fixer->endChangeset(); } } }
/** * @param \PHP_CodeSniffer_File $phpCsFile * @param int $stackPointer * * @return void */ protected function addFixableExistingDocBlock(\PHP_CodeSniffer_File $phpCsFile, $stackPointer) { $fix = $phpCsFile->addFixableError(basename($phpCsFile->getFilename()) . ' has the wrong file doc block', $stackPointer); if ($fix) { $this->addFileDocBlock($phpCsFile, 0); } }