Returns the content of the tokens from the specified start position in
the token stack for the specified length.
/** * 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) { if ($phpcsFile->getTokensAsString($stackPtr, 4) === '$form_state[\'input\']' || $phpcsFile->getTokensAsString($stackPtr, 4) === '$form_state["input"]') { $warning = 'Do not use the raw $form_state[\'input\'], use $form_state[\'values\'] instead where possible'; $phpcsFile->addWarning($warning, $stackPtr, 'Input'); } }
/** * Processes this sniff, when one of its tokens is encountered. * * @param PHP_CodeSniffer_File $phpcsFile The current file being checked. * @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(); // No bracket can have space before them. $prevType = $tokens[$stackPtr - 1]['code']; if (in_array($prevType, PHP_CodeSniffer_Tokens::$emptyTokens) === true) { $nonSpace = $phpcsFile->findPrevious(PHP_CodeSniffer_Tokens::$emptyTokens, $stackPtr - 2, null, true); $expected = $tokens[$nonSpace]['content'] . $tokens[$stackPtr]['content']; $found = $phpcsFile->getTokensAsString($nonSpace, $stackPtr - $nonSpace) . $tokens[$stackPtr]['content']; $error = 'Space found before square bracket; expected "%s" but found "%s"'; $data = array($expected, $found); $phpcsFile->addError($error, $stackPtr, 'SpaceBeforeBracket', $data); } if ($tokens[$stackPtr]['type'] === 'T_OPEN_SQUARE_BRACKET') { // Open brackets can't have spaces on after them either. $nextType = $tokens[$stackPtr + 1]['code']; if (in_array($nextType, PHP_CodeSniffer_Tokens::$emptyTokens) === true) { $nonSpace = $phpcsFile->findNext(PHP_CodeSniffer_Tokens::$emptyTokens, $stackPtr + 2, null, true); $expected = $tokens[$stackPtr]['content'] . $tokens[$nonSpace]['content']; $found = $phpcsFile->getTokensAsString($stackPtr, $nonSpace - $stackPtr + 1); $error = 'Space found after square bracket; expected "%s" but found "%s"'; $data = array($expected, $found); $phpcsFile->addError($error, $stackPtr, 'SpaceAfterBracket', $data); } } }
/** * Processes this test, when one of its tokens is encountered. * * @param PHP_CodeSniffer_File $phpcsFile The current file being processed. * @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(); // Determine the name of the class or interface. Note that we cannot // simply look for the first T_STRING because a class name // starting with the number will be multiple tokens. $opener = $tokens[$stackPtr]['scope_opener']; $nameStart = $phpcsFile->findNext(T_WHITESPACE, $stackPtr + 1, $opener, true); $nameEnd = $phpcsFile->findNext(T_WHITESPACE, $nameStart, $opener); $name = trim($phpcsFile->getTokensAsString($nameStart, $nameEnd - $nameStart)); // check for lower case class names $legalChars = '[a-z]'; if (preg_match("|[^{$legalChars}]|", $name) === 0) { $valid = true; } else { $valid = false; } // Check for camel caps format. // $valid = PHP_CodeSniffer::isLowerCase($name, true, true, true); if ($valid === false) { $type = ucfirst($tokens[$stackPtr]['content']); $error = "{$type} name \"{$name}\" is not in lower case format"; $phpcsFile->addError($error, $stackPtr); } }
public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr) { // get tokens $tokens = $phpcsFile->getTokens(); $current = $tokens[$stackPtr]; // skip for-statements without body. if (isset($current['scope_opener']) === false) { return; } // get next $next = ++$current['scope_opener']; $end = --$current['scope_closer']; $emptyBody = true; for (; $next <= $end; ++$next) { if (in_array($tokens[$next]['code'], array(T_WHITESPACE)) === false) { $emptyBody = false; break; } } if ($emptyBody === true) { // Get token identifier. $name = $phpcsFile->getTokensAsString($stackPtr, 1); $error = sprintf('Empty %s statement detected', strtoupper($name)); $phpcsFile->addWarning($error, $stackPtr); } // cleanup unset($tokens); unset($current); unset($next); unset($end); }
/** * 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 test, when one of its tokens is encountered. * * @param PHP_CodeSniffer_File $phpcsFile The current file being processed. * @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) { $error = 'Possible parse error: %s missing opening or closing brace'; $data = array($tokens[$stackPtr]['content']); $phpcsFile->addWarning($error, $stackPtr, 'MissingBrace', $data); return; } // Determine the name of the class or interface. Note that we cannot // simply look for the first T_STRING because a class name // starting with the number will be multiple tokens. $opener = $tokens[$stackPtr]['scope_opener']; $nameStart = $phpcsFile->findNext(T_WHITESPACE, $stackPtr + 1, $opener, true); $nameEnd = $phpcsFile->findNext(T_WHITESPACE, $nameStart, $opener); $name = trim($phpcsFile->getTokensAsString($nameStart, $nameEnd - $nameStart)); // Check for camel caps format. $valid = PHP_CodeSniffer::isCamelCaps($name, true, true, false); if ($valid === false) { $type = ucfirst($tokens[$stackPtr]['content']); $error = '%s name "%s" is not in camel caps format'; $data = array($type, $name); $phpcsFile->addError($error, $stackPtr, 'NotCamelCaps', $data); } }
/** * 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(); $namespace = ''; $stackPtr = $phpcsFile->findNext(array(T_CLASS, T_INTERFACE, T_NAMESPACE), 0); while ($stackPtr !== false) { // Keep track of what namespace we are in. if ($tokens[$stackPtr]['code'] === T_NAMESPACE) { $nsEnd = $phpcsFile->findNext(array(T_NS_SEPARATOR, T_STRING, T_WHITESPACE), $stackPtr + 1, null, true); $namespace = trim($phpcsFile->getTokensAsString($stackPtr + 1, $nsEnd - $stackPtr - 1)); $stackPtr = $nsEnd; } else { $nameToken = $phpcsFile->findNext(T_STRING, $stackPtr); $name = $tokens[$nameToken]['content']; if ($namespace !== '') { $name = $namespace . '\\' . $name; } $compareName = strtolower($name); if (isset($this->foundClasses[$compareName]) === true) { $type = strtolower($tokens[$stackPtr]['content']); $file = $this->foundClasses[$compareName]['file']; $line = $this->foundClasses[$compareName]['line']; $error = 'Duplicate %s name "%s" found; first defined in %s on line %s'; $data = array($type, $name, $file, $line); $phpcsFile->addWarning($error, $stackPtr, 'Found', $data); } else { $this->foundClasses[$compareName] = array('file' => $phpcsFile->getFilename(), 'line' => $tokens[$stackPtr]['line']); } } $stackPtr = $phpcsFile->findNext(array(T_CLASS, T_INTERFACE, T_NAMESPACE), $stackPtr + 1); } //end while }
/** * Check if an php doc contains @inheritdoc. * * @param PHP_CodeSniffer_File $phpcsFile * @param int $stackPtr * @param int $commentStart * * @return bool */ protected function isInherited(PHP_CodeSniffer_File $phpcsFile, $commentStart) { $tokens = $phpcsFile->getTokens(); $comment = strtolower($phpcsFile->getTokensAsString($commentStart, $tokens[$commentStart]['comment_closer'])); // Accept inheriting of comments to be sufficient. return strpos($comment, '@inheritdoc') !== false; }
private static function getAlias(CodeSnifferFile $file, $stackPtr) { $nextPtr = $stackPtr; $alias = static::$aliasMap; $tokens = $file->getTokens(); $foundParenthesis = false; while (is_array($alias)) { $nextPtr = $file->findNext([T_WHITESPACE, T_COMMA, T_SEMICOLON], ++$nextPtr, null, true, null, true); if ($nextPtr === false) { break; } if ($tokens[$nextPtr]['code'] === T_OPEN_PARENTHESIS) { if ($foundParenthesis) { $nextPtr = $tokens[$nextPtr]['parenthesis_closer'] + 1; } $foundParenthesis = true; continue; } if (isset($alias[$tokens[$nextPtr]['code']])) { $alias = $alias[$tokens[$nextPtr]['code']]; } elseif (isset($alias[$tokens[$nextPtr]['content']])) { $alias = $alias[$tokens[$nextPtr]['content']]; } else { return [null, null]; } } return [$alias, sprintf('%s%s', $file->getTokensAsString($stackPtr + 1, $nextPtr - $stackPtr), static::getClosing($file, $nextPtr + 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 ($tokens[$stackPtr]['code'] === T_CASE && isset($tokens[$stackPtr]['scope_closer'])) { // $internalCase = $phpcsFile->findNext(T_CASE, $stackPtr + 1, $tokens[$stackPtr]['scope_closer']); // if ($internalCase !== false) { // $comment = $phpcsFile->findNext(T_COMMENT, $stackPtr + 1, $internalCase - 1); // if ($comment === false) { // $phpcsFile->addError($this->getReqPrefix('REQ.PHP.2.5.12') . '"case" has not break and has not any comment', $stackPtr); // } // } $switch = $phpcsFile->findPrevious(T_SWITCH, $stackPtr - 1); if ($switch !== false) { $nextCase = $phpcsFile->findNext(array(T_CASE, T_DEFAULT), $stackPtr + 1, $tokens[$switch]['scope_closer']); if ($nextCase !== false) { $prevBreak = $phpcsFile->findPrevious(T_BREAK, $nextCase - 1, $stackPtr); if ($prevBreak !== false) { $breakWS = $phpcsFile->findNext(T_WHITESPACE, $prevBreak + 1, $nextCase - 1); if ($breakWS !== false) { $str = $phpcsFile->getTokensAsString($breakWS, $nextCase - $breakWS - 1); if (!preg_match("/^\n\n[ ]*\$/Ss", $str)) { $breakWS = false; } } if ($breakWS === false) { $phpcsFile->addError($this->getReqPrefix('REQ.PHP.2.5.14') . '"case" must has empty line between current "case" and previous "break"', $stackPtr); } } } } } elseif ($tokens[$stackPtr]['code'] === T_DEFAULT) { } }
/** * Processes the tokens that this sniff is interested in. * * @param PHP_CodeSniffer_File $phpcsFile File where the token was found * @param int $stackPtr Position in the stack where the token was found * @return void */ public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr) { $open = $phpcsFile->findNext(T_OPEN_PARENTHESIS, $stackPtr, null, false, null, true); if ($open !== false && $phpcsFile->getTokensAsString($open, 2) == '()') { $phpcsFile->addError('Parentheses should not be used in calls to class constructors without parameters', $stackPtr); } }
public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr) { // If we've already parsed this comment, pass if ($phpcsFile == $this->_phpcsFile && $stackPtr < $this->_lastParsed) { return; } $this->_phpcsFile = $phpcsFile; $tokens = $phpcsFile->getTokens(); // Find the end of the comment block $endPtr = $phpcsFile->findNext($tokens[$stackPtr]['code'], $stackPtr + 1, null, true); $this->_lastParsed = $endPtr; // Get the whole comment text $comment = $phpcsFile->getTokensAsString($stackPtr, $endPtr - $stackPtr + 1); $this->parser = new Scisr_CommentParser_ChangeTagValues($comment, $phpcsFile); $this->parser->parse(); $elements = $this->parser->getTagElements(); $columns = $this->parser->getTagElementColumns(); foreach ($elements as $tagName => $tagArray) { $method = array($this, 'process' . ucfirst($tagName)); if (is_callable($method)) { foreach ($tagArray as $i => $tag) { call_user_func($method, $tag, $stackPtr, $phpcsFile, $columns[$tagName][$i]); } } } }
/** * 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(); $errorData = array($tokens[$stackPtr]['content']); // braces $openingBrace = $tokens[$stackPtr]['scope_opener']; $closingBrace = $tokens[$stackPtr]['scope_closer']; // look for empty bodies $body = $phpcsFile->getTokensAsString($openingBrace, $closingBrace - $openingBrace + 1); if (preg_match('/^\\{\\s*\\}$/', $body)) { if (preg_match('/\\s/', $body)) { $error = 'Opening and closing braces of an empty %s must be on the same line as the definition, with no spaces between them.'; $phpcsFile->addError($error, $stackPtr, 'EmptyBodyBraces', $errorData); } // body has content } else { parent::process($phpcsFile, $stackPtr); // check braces alignment if ($tokens[$openingBrace]['column'] !== $tokens[$closingBrace]['column']) { $error = 'Closing braces must have the same indentation than their respective opening one.'; $phpcsFile->addError($error, $closingBrace, 'BadClosingBraceIndentation', $errorData); } } }
/** * Is the comment an inheritdoc? * * @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 boolean True if the comment is an inheritdoc */ protected function isInheritDoc(PHP_CodeSniffer_File $phpcsFile, $stackPtr) { $start = $phpcsFile->findPrevious(T_DOC_COMMENT_OPEN_TAG, $stackPtr - 1); $end = $phpcsFile->findNext(T_DOC_COMMENT_CLOSE_TAG, $start); $content = $phpcsFile->getTokensAsString($start, $end - $start); return preg_match('#{@inheritDoc}#', $content) === 1; }
/** * Processes this test, when one of its tokens is encountered. * * @param PHP_CodeSniffer_File $phpcsFile The current file being processed. * @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) { $sequence = $phpcsFile->getTokensAsString($stackPtr, 3); if ($sequence === "['und']" || $sequence === '["und"]') { $warning = "Are you accessing field values here? Then you should use LANGUAGE_NONE instead of 'und'"; $phpcsFile->addWarning($warning, $stackPtr + 1, 'Und'); } }
/** * Processes this test, when one of its tokens is encountered. * * @param PHP_CodeSniffer_File $phpcsFile The current file being processed. * @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) { $string = $phpcsFile->getTokensAsString($stackPtr, 4); if ($string === '$_SERVER["REMOTE_ADDR"]' || $string === '$_SERVER[\'REMOTE_ADDR\']') { $error = 'Use the function ip_address() instead of $_SERVER[\'REMOTE_ADDR\']'; $phpcsFile->addError($error, $stackPtr, 'RemoteAddress'); } }
/** * Processes this test, when one of its tokens is encountered. * * @param PHP_CodeSniffer_File $phpcsFile The current file being processed. * @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(); // Determine the name of the class or interface. Note that we cannot // simply look for the first T_STRING because a class name // starting with the number will be multiple tokens. $type = $tokens[$stackPtr]['content']; $opener = $tokens[$stackPtr]['scope_opener']; $nameStart = $phpcsFile->findNext(T_WHITESPACE, $stackPtr + 1, $opener, true); $nameEnd = $phpcsFile->findNext(T_WHITESPACE, $nameStart, $opener); $name = trim($phpcsFile->getTokensAsString($nameStart, $nameEnd - $nameStart)); // Check that each new word starts with a small latter // and the last one with capital $validName = true; $nameBits = explode('_', $name); $className = $lastBit = array_pop($nameBits); foreach ($nameBits as $bit) { if ($bit === '' || $bit[0] !== strtolower($bit[0])) { $validName = false; break; } } $validName = $validName && PHP_CodeSniffer::isCamelCaps($lastBit, true, true, false); if ($validName === false) { // Strip underscores because they cause the suggested name // to be incorrect. $nameBits = explode('_', trim($name, '_')); $lastBit = array_pop($nameBits); if ($lastBit === '') { $error = '%s name is not valid'; $phpcsFile->addError($error, $stackPtr, 'Invalid', array($name)); } else { $newName = ''; foreach ($nameBits as $bit) { if ($bit !== '') { $newName .= strtolower($bit[0]) . substr($bit, 1) . '_'; } } $newName = $newName . ucfirst($lastBit); $error = '%s name is not valid; consider %s instead'; $data = array($name); $data[] = $newName; $phpcsFile->addError($error, $stackPtr, 'Invalid', $data); } } if ($type === 'interface') { if (substr($className, 0, 1) !== 'I') { $error = 'Interface name %s must start with "I"'; $data = array($name); $phpcsFile->addError($error, $stackPtr, 'BadInterfaceName', $data); } else { if (!PHP_CodeSniffer::isCamelCaps(substr($className, 1), true, true, false)) { $phpcsFile->addError('Interface name %s is not in camel caps format', $stackPtr, 'NotCamelCaps', $className); } } } }
public function process(\PHP_CodeSniffer_File $phpcsFile, $stackPtr) { $tokens = $phpcsFile->getTokens(); $varName = $tokens[$stackPtr]['content']; if ($varName !== '$_REQUEST' && $varName !== '$_GET' && $varName !== '$_POST' && $varName !== '$_FILES' && $varName !== '$_SERVER') { return; } // The only place these super globals can be accessed directly is // in the getRequestData() method of the Security class. $inClass = false; foreach ($tokens[$stackPtr]['conditions'] as $i => $type) { if ($tokens[$i]['code'] === T_CLASS) { $className = $phpcsFile->findNext(T_STRING, $i); $className = $tokens[$className]['content']; if (strtolower($className) === 'security') { $inClass = true; } else { // We don't have nested classes. break; } } else { if ($inClass === true && $tokens[$i]['code'] === T_FUNCTION) { $funcName = $phpcsFile->findNext(T_STRING, $i); $funcName = $tokens[$funcName]['content']; if (strtolower($funcName) === 'getrequestdata') { // This is valid. return; } else { // We don't have nested functions. break; } } } //end if } //end foreach // If we get to here, the super global was used incorrectly. // First find out how it is being used. $globalName = strtolower(substr($varName, 2)); $usedVar = ''; $openBracket = $phpcsFile->findNext(T_WHITESPACE, $stackPtr + 1, null, true); if ($tokens[$openBracket]['code'] === T_OPEN_SQUARE_BRACKET) { $closeBracket = $tokens[$openBracket]['bracket_closer']; $usedVar = $phpcsFile->getTokensAsString($openBracket + 1, $closeBracket - $openBracket - 1); } $type = 'SuperglobalAccessed'; $error = 'The %s super global must not be accessed directly; use Security::getRequestData('; $data = array($varName); if ($usedVar !== '') { $type .= 'WithVar'; $error .= '%s, \'%s\''; $data[] = $usedVar; $data[] = $globalName; } $error .= ') instead'; $phpcsFile->addError($error, $stackPtr, $type, $data); }
/** * Processes this sniff, when one of its tokens is encountered. * * @param PHP_CodeSniffer_File $phpcsFile The current file being checked. * @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(); // PHP 5.4 introduced a shorthand array declaration syntax, so we need // to ignore the these type of array declarations because this sniff is // only dealing with array usage. if ($tokens[$stackPtr]['code'] === T_OPEN_SQUARE_BRACKET) { $openBracket = $stackPtr; } else { $openBracket = $tokens[$stackPtr]['bracket_opener']; } $prev = $phpcsFile->findPrevious(PHP_CodeSniffer_Tokens::$emptyTokens, $openBracket - 1, null, true); if ($tokens[$prev]['code'] === T_EQUAL) { return; } // Square brackets can not have a space before them. $prevType = $tokens[$stackPtr - 1]['code']; if (isset(PHP_CodeSniffer_Tokens::$emptyTokens[$prevType]) === true) { $nonSpace = $phpcsFile->findPrevious(PHP_CodeSniffer_Tokens::$emptyTokens, $stackPtr - 2, null, true); $expected = $tokens[$nonSpace]['content'] . $tokens[$stackPtr]['content']; $found = $phpcsFile->getTokensAsString($nonSpace, $stackPtr - $nonSpace) . $tokens[$stackPtr]['content']; $error = 'Space found before square bracket; expected "%s" but found "%s"'; $data = array($expected, $found); $fix = $phpcsFile->addFixableError($error, $stackPtr, 'SpaceBeforeBracket', $data); if ($fix === true) { $phpcsFile->fixer->replaceToken($stackPtr - 1, ''); } } // Open square brackets can't ever have spaces after them. if ($tokens[$stackPtr]['code'] === T_OPEN_SQUARE_BRACKET) { $nextType = $tokens[$stackPtr + 1]['code']; if (isset(PHP_CodeSniffer_Tokens::$emptyTokens[$nextType]) === true) { $nonSpace = $phpcsFile->findNext(PHP_CodeSniffer_Tokens::$emptyTokens, $stackPtr + 2, null, true); $expected = $tokens[$stackPtr]['content'] . $tokens[$nonSpace]['content']; $found = $phpcsFile->getTokensAsString($stackPtr, $nonSpace - $stackPtr + 1); $error = 'Space found after square bracket; expected "%s" but found "%s"'; $data = array($expected, $found); $fix = $phpcsFile->addFixableError($error, $stackPtr, 'SpaceAfterBracket', $data); if ($fix === true) { $phpcsFile->fixer->replaceToken($stackPtr + 1, ''); } } } }
/** * Processes this test, when one of its tokens is encountered. * * @param PHP_CodeSniffer_File $phpcsFile The current 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) { $commentEnd = $phpcsFile->findNext(T_DOC_COMMENT_CLOSE_TAG, $stackPtr); $content = $phpcsFile->getTokensAsString($stackPtr, $commentEnd - $stackPtr); // If it is an inline doc comment for type hinting etc., return. if (substr($content, 0, 5) === '/** @') { return; } parent::process($phpcsFile, $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(); $prevType = $tokens[$stackPtr - 1]['code']; if (in_array($prevType, PHP_CodeSniffer_Tokens::$emptyTokens) === true) { $nonSpace = $phpcsFile->findPrevious(PHP_CodeSniffer_Tokens::$emptyTokens, $stackPtr - 2, null, true); $expected = $tokens[$nonSpace]['content'] . '->'; $found = $phpcsFile->getTokensAsString($nonSpace, $stackPtr - $nonSpace) . '->'; $error = "Space found before object operator; expected \"{$expected}\" but found \"{$found}\""; $phpcsFile->addError($error, $stackPtr); } $nextType = $tokens[$stackPtr + 1]['code']; if (in_array($nextType, PHP_CodeSniffer_Tokens::$emptyTokens) === true) { $nonSpace = $phpcsFile->findNext(PHP_CodeSniffer_Tokens::$emptyTokens, $stackPtr + 2, null, true); $expected = '->' . $tokens[$nonSpace]['content']; $found = $phpcsFile->getTokensAsString($stackPtr, $nonSpace - $stackPtr + 1); $error = "Space found after object operator; expected \"{$expected}\" but found \"{$found}\""; $phpcsFile->addError($error, $stackPtr); } }
function checkAccess($stackPtr, $commentStart, $commentEnd) { $tokens = $this->currentFile->getTokens(); $access = $this->commentParser->getAccess(); $prevWS = $this->currentFile->findPrevious(T_WHITESPACE, $stackPtr - 1, null, false, "\n"); $type = $this->currentFile->findNext(array(T_PRIVATE, T_PUBLIC, T_PROTECTED), $prevWS + 1, $stackPtr - 1); $code = $tokens[$type]['code']; if (!is_null($access) && ($code === T_PUBLIC && $access->getValue() !== 'public' || $code === T_PRIVATE && $access->getValue() !== 'private' || $code === T_PROTECTED && $access->getValue() !== 'protected')) { $cnt = substr_count(preg_replace('/@access.+$/Ss', '', $this->currentFile->getTokensAsString($commentStart, $commentEnd - $commentStart + 1)), "\n"); $this->currentFile->addError($this->getReqPrefix('REQ.PHP.4.1.25') . 'Значение тэга @access не совпадает с декларацией (декларированно как ' . $tokens[$type]['content'] . ', а @access равен ' . $access->getValue() . ')', $commentStart + $cnt); } }
/** * 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 (in_array($prevType, PHP_CodeSniffer_Tokens::$emptyTokens) === true) { $nonSpace = $phpcsFile->findPrevious(PHP_CodeSniffer_Tokens::$emptyTokens, $stackPtr - 2, null, true); $expected = $tokens[$nonSpace]['content'] . ';'; $found = $phpcsFile->getTokensAsString($nonSpace, $stackPtr - $nonSpace) . ';'; $error = "Space found before semicolon; expected \"{$expected}\" but found \"{$found}\""; $phpcsFile->addError($error, $stackPtr); } }
/** * Processes a token that is found within the scope that this test is * listening to. * * @param PHP_CodeSniffer_File $phpcsFile The file where this token was found. * @param int $stackPtr The position in the stack where this * token was found. * @param int $currScope The position in the tokens array that * opened the scope that this test is * listening for. * * @return void */ protected function processTokenWithinScope(PHP_CodeSniffer_File $phpcsFile, $stackPtr, $currScope) { $find = array(T_COMMENT, T_DOC_COMMENT_CLOSE_TAG, T_CLASS, T_CONST, T_FUNCTION, T_VARIABLE, T_OPEN_TAG); $tokens = $phpcsFile->getTokens(); $commentEnd = $phpcsFile->findPrevious($find, $stackPtr - 1); if ($commentEnd === false) { return; } $conditions = $tokens[$commentEnd]['conditions']; $lastCondition = array_pop($conditions); if ($lastCondition !== T_CLASS) { return; } $code = $tokens[$commentEnd]['code']; if ($code === T_DOC_COMMENT_CLOSE_TAG) { $commentStart = $tokens[$commentEnd]['comment_opener']; $isCommentOneLiner = $tokens[$commentStart]['line'] === $tokens[$commentEnd]['line']; $length = $commentEnd - $commentStart + 1; $tokensAsString = $phpcsFile->getTokensAsString($commentStart, $length); $varCount = count(preg_split('/\\s+@var\\s+/', $tokensAsString)) - 1; if ($varCount === 0) { $phpcsFile->addError('property doc comment must have one @var annotation', $commentStart, 'NoVarDefined'); } else { if ($varCount > 1) { $phpcsFile->addError('property doc comment must no multiple @var annotations', $commentStart, 'MultipleVarDefined'); } } if ($varCount === 1) { if ($isCommentOneLiner === true) { $fix = $phpcsFile->addFixableError('property doc comment must be multi line', $commentEnd, 'NotMultiLineDocBlock'); if ($fix === true) { $phpcsFile->fixer->beginChangeset(); $phpcsFile->fixer->addContent($commentStart, "\n *"); $phpcsFile->fixer->replaceToken($commentEnd - 1, rtrim($tokens[$commentEnd - 1]['content'])); $phpcsFile->fixer->addContentBefore($commentEnd, "\n "); $phpcsFile->fixer->endChangeset(); } } } else { if ($isCommentOneLiner === true) { $phpcsFile->addError('property doc comment must be multi line', $commentEnd, 'NotMultiLineDocBlock'); } } //end if } else { if ($code === T_COMMENT) { $commentStart = $phpcsFile->findPrevious(T_COMMENT, $commentEnd, null, true); $phpcsFile->addError('property doc comment must begin with /**', $commentStart + 1, 'NotADocBlock'); } } //end if }
/** * Processes this sniff, when one of its tokens is encountered. * * @param PHP_CodeSniffer_File $phpcsFile The current file being checked. * @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(); // PHP 5.4 introduced a shorthand array declaration syntax, so we need // to ignore the these type of array declarations because this sniff is // only dealing with array usage. if ($tokens[$stackPtr]['code'] === T_OPEN_SQUARE_BRACKET) { $openBracket = $stackPtr; } else { $openBracket = $tokens[$stackPtr]['bracket_opener']; } $prev = $phpcsFile->findPrevious(PHP_CodeSniffer_Tokens::$emptyTokens, $openBracket - 1, null, true); if ($tokens[$prev]['code'] === T_EQUAL) { return; } // Close Square brackets must have a space before them $prevType = $tokens[$stackPtr - 1]['code']; if ($tokens[$stackPtr]['code'] === T_CLOSE_SQUARE_BRACKET && in_array($prevType, PHP_CodeSniffer_Tokens::$emptyTokens) !== true && $prevType !== T_OPEN_SQUARE_BRACKET) { $nonSpace = $phpcsFile->findPrevious(PHP_CodeSniffer_Tokens::$emptyTokens, $stackPtr - 2, null, true); $expected = $tokens[$nonSpace]['content'] . $tokens[$stackPtr]['content']; $found = $phpcsFile->getTokensAsString($nonSpace, $stackPtr - $nonSpace) . $tokens[$stackPtr]['content']; $error = 'No space found before closing square bracket'; $data = array($expected, $found); $phpcsFile->addError($error, $stackPtr, 'SpaceBeforeBracket', $data); } // Open square brackets must have spaces after them. if ($tokens[$stackPtr]['code'] === T_OPEN_SQUARE_BRACKET) { $nextType = $tokens[$stackPtr + 1]['code']; if (in_array($nextType, PHP_CodeSniffer_Tokens::$emptyTokens) !== true && $nextType !== T_CLOSE_SQUARE_BRACKET) { $nonSpace = $phpcsFile->findNext(PHP_CodeSniffer_Tokens::$emptyTokens, $stackPtr + 2, null, true); $expected = $tokens[$stackPtr]['content'] . $tokens[$nonSpace]['content']; $found = $phpcsFile->getTokensAsString($stackPtr, $nonSpace - $stackPtr + 1); $error = 'No space found after opening square bracket'; $data = array($expected, $found); $phpcsFile->addError($error, $stackPtr, 'SpaceAfterBracket', $data); } } }
public function process(CodeSnifferFile $file, $stackPtr) { $content = $file->getTokensAsString($stackPtr, 3); $regex = '/@(?<annotation>var|param|return)\\s+(?<types>[^\\s]+)(?:\\s+|$)/xi'; if (!preg_match($regex, $content, $matches)) { return; } foreach (explode('|', $matches['types']) as $type) { if (!isset(static::$typeMap[$type])) { continue; } $file->addError(sprintf('Found "@%1$s %2$s", expected "@%1$s %3$s"', $matches['annotation'], $matches['types'], str_replace($type, static::$typeMap[$type], $matches['types'])), $stackPtr, 'ShortDocCommentTypes'); } }
/** * Processes this sniff, when one of its tokens is encountered. * * @param PHP_CodeSniffer_File $phpcsFile The current file being checked. * @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(); // No bracket can have space before them. $prevType = $tokens[$stackPtr - 1]['code']; if (in_array($prevType, PHP_CodeSniffer_Tokens::$emptyTokens) === true) { $nonSpace = $phpcsFile->findPrevious(PHP_CodeSniffer_Tokens::$emptyTokens, $stackPtr - 2, null, true); $expected = $tokens[$nonSpace]['content'] . $tokens[$stackPtr]['content']; $found = $phpcsFile->getTokensAsString($nonSpace, $stackPtr - $nonSpace) . $tokens[$stackPtr]['content']; $error = "[Arreglos#acceso] Espacio entre corchetes; se esperaba \"{$expected}\" en lugar de \"{$found}\""; $phpcsFile->addWarning($error, $stackPtr); } if ($tokens[$stackPtr]['type'] === 'T_OPEN_SQUARE_BRACKET') { // Open brackets can't have spaces on after them either. $nextType = $tokens[$stackPtr + 1]['code']; if (in_array($nextType, PHP_CodeSniffer_Tokens::$emptyTokens) === true) { $nonSpace = $phpcsFile->findNext(PHP_CodeSniffer_Tokens::$emptyTokens, $stackPtr + 2, null, true); $expected = $tokens[$stackPtr]['content'] . $tokens[$nonSpace]['content']; $found = $phpcsFile->getTokensAsString($stackPtr, $nonSpace - $stackPtr + 1); $error = "[Arreglos#acceso] Espacio entre corchetes; se esperaba \"{$expected}\" en lugar de \"{$found}\""; $phpcsFile->addWarning($error, $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 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']; $tokenCount = $phpcsFile->numTokens - 1; // Each case, break, and default should be on a separate line $start = $end = $stackPtr; while ($tokens[$start]['line'] == $line && $start > 0) { $start--; } while ($tokens[$end]['line'] == $line && $end < $tokenCount) { $end++; } $lineTokens = array_slice($tokens, $start, $end - $start + 1, true); foreach ($lineTokens as $tokenPtr => $token) { switch ($token['type']) { case 'T_CASE': case 'T_DEFAULT': case 'T_BREAK': if ($tokenPtr > $stackPtr) { $error = 'Each case, break, and default should be on a separate line'; $phpcsFile->addError($error, $stackPtr); } } } if ($tokens[$stackPtr]['type'] == 'T_BREAK') { return; } // Account for typos using ; instead of : on case lines if (!isset($tokens[$stackPtr]['scope_opener'])) { $error = 'Potential use of ; instead of : on a case line'; $phpcsFile->addWarning($error, $stackPtr); return; } // Code inside case and default blocks should be indented for ($open = $tokens[$stackPtr]['scope_opener']; $tokens[$open]['line'] == $line; $open++) { } for ($close = $tokens[$stackPtr]['scope_closer']; $tokens[$close]['line'] == $tokens[$close + 1]['line']; $close--) { } $indent = $phpcsFile->getTokensAsString($start, $stackPtr - $start); $tabCount = substr_count($indent, "\t") + 1; $tabString = str_repeat("\t", $tabCount); foreach (range($open, $close) as $tokenPtr) { if ($tokens[$tokenPtr]['line'] == $tokens[$tokenPtr - 1]['line'] + 1 && substr($tokens[$tokenPtr]['content'], 0, $tabCount) != $tabString) { $phpcsFile->addError('Code inside case and default blocks should be indented', $tokenPtr); } } }
/** * 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(); $has_errors = 0; if (isset($tokens[$stackPtr]['scope_opener'])) { $scope_open = $tokens[$stackPtr]['scope_opener']; } else { if ($tokens[$stackPtr + 2]['code'] === T_IF && isset($tokens[$stackPtr + 2]['scope_opener'])) { $scope_open = $tokens[$stackPtr + 2]['scope_opener']; } } if (isset($scope_open) && $tokens[$scope_open]['code'] !== T_COLON) { // Ignore alternative syntax $previous = $phpcsFile->findPrevious(T_CLOSE_CURLY_BRACKET, $stackPtr, null, false); if ($tokens[$previous]['line'] === $tokens[$stackPtr]['line']) { $error = 'else(if) statement must be on a new line'; $phpcsFile->addError($error, $stackPtr, 'NewLine'); $has_errors++; unset($error); } $start = $previous + 1; $other_start = null; $other_length = 0; for ($i = $start; $i < $stackPtr; $i++) { if ($tokens[$i]['code'] !== T_COMMENT && $tokens[$i]['code'] !== T_WHITESPACE) { if (!isset($other_start)) { $other_start = $i; } $other_length++; } } unset($i); if (isset($other_start, $other_length)) { $error = 'Nothing but whitespace and comments allowed between closing bracket and else(if) statement, found "%s"'; $data = $phpcsFile->getTokensAsString($other_start, $other_length); $phpcsFile->addError($error, $stackPtr, 'StatementFound', $data); $has_errors++; unset($error, $data, $other_start, $other_length); } if ($has_errors === 0) { if ($tokens[$previous]['column'] !== $tokens[$stackPtr]['column']) { $error = 'else(if) statement not aligned with previous part of the control structure'; $phpcsFile->addError($error, $stackPtr, 'Alignment'); unset($error); } } } }
/** * Processes class member variables. * * @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 */ protected function processMemberVar(PHP_CodeSniffer_File $phpcsFile, $stackPtr) { $tokens = $phpcsFile->getTokens(); $memberProps = $phpcsFile->getMemberProperties($stackPtr); if (empty($memberProps) === true) { return; } $memberName = ltrim($tokens[$stackPtr]['content'], '$'); $isPublic = $memberProps['scope'] === 'private' ? false : true; $scope = $memberProps['scope']; $scopeSpecified = $memberProps['scope_specified']; // Detect if it is marked deprecated $find = array(T_COMMENT, T_DOC_COMMENT, T_CLASS, T_FUNCTION, T_OPEN_TAG); $tokens = $phpcsFile->getTokens(); $commentEnd = $phpcsFile->findPrevious($find, $stackPtr - 1); if ($commentEnd !== false && $tokens[$commentEnd]['code'] === T_DOC_COMMENT) { $commentStart = $phpcsFile->findPrevious(T_DOC_COMMENT, $commentEnd - 1, null, true) + 1; $comment = $phpcsFile->getTokensAsString($commentStart, $commentEnd - $commentStart + 1); try { $this->commentParser = new PHP_CodeSniffer_CommentParser_FunctionCommentParser($comment, $phpcsFile); $this->commentParser->parse(); } catch (PHP_CodeSniffer_CommentParser_ParserException $e) { $line = $e->getLineWithinComment() + $commentStart; $phpcsFile->addError($e->getMessage(), $line, 'FailedParse'); return; } $deprecated = $this->commentParser->getDeprecated(); $isDeprecated = !is_null($deprecated); } else { $isDeprecated = false; } // If it's a private member, it must have an underscore on the front. if ($isPublic === false && $memberName[0] !== '_') { $error = 'Private member variable "%s" must be prefixed with an underscore'; $data = array($memberName); $phpcsFile->addError($error, $stackPtr, 'PrivateNoUnderscore', $data); return; } // If it's not a private member, it must not have an underscore on the front. if ($isDeprecated === false && $isPublic === true && $scopeSpecified === true && $memberName[0] === '_') { $error = '%s member variable "%s" must not be prefixed with an underscore'; $data = array(ucfirst($scope), $memberName); // AJE Changed from error to warning. $phpcsFile->addWarning($error, $stackPtr, 'PublicUnderscore', $data); return; } }