/** * 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. * * @return void */ protected function processMemberVar(File $phpcsFile, $stackPtr) { $tokens = $phpcsFile->getTokens(); if ($tokens[$stackPtr]['content'][1] === '_') { $error = 'Property name "%s" should not be prefixed with an underscore to indicate visibility'; $data = array($tokens[$stackPtr]['content']); $phpcsFile->addWarning($error, $stackPtr, 'Underscore', $data); } // Detect multiple properties defined at the same time. Throw an error // for this, but also only process the first property in the list so we don't // repeat errors. $find = Tokens::$scopeModifiers; $find = array_merge($find, array(T_VARIABLE, T_VAR, T_SEMICOLON)); $prev = $phpcsFile->findPrevious($find, $stackPtr - 1); if ($tokens[$prev]['code'] === T_VARIABLE) { return; } if ($tokens[$prev]['code'] === T_VAR) { $error = 'The var keyword must not be used to declare a property'; $phpcsFile->addError($error, $stackPtr, 'VarUsed'); } $next = $phpcsFile->findNext(array(T_VARIABLE, T_SEMICOLON), $stackPtr + 1); if ($tokens[$next]['code'] === T_VARIABLE) { $error = 'There must not be more than one property declared per statement'; $phpcsFile->addError($error, $stackPtr, 'Multiple'); } $modifier = $phpcsFile->findPrevious(Tokens::$scopeModifiers, $stackPtr); if ($modifier === false || $tokens[$modifier]['line'] !== $tokens[$stackPtr]['line']) { $error = 'Visibility must be declared on property "%s"'; $data = array($tokens[$stackPtr]['content']); $phpcsFile->addError($error, $stackPtr, 'ScopeMissing', $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(File $phpcsFile, $stackPtr) { $tokens = $phpcsFile->getTokens(); $find = Tokens::$methodPrefixes; $find[] = T_WHITESPACE; $commentEnd = $phpcsFile->findPrevious($find, $stackPtr - 1, null, true); if ($tokens[$commentEnd]['code'] !== T_DOC_COMMENT_CLOSE_TAG && $tokens[$commentEnd]['code'] !== T_COMMENT) { $phpcsFile->addError('Missing class doc comment', $stackPtr, 'Missing'); $phpcsFile->recordMetric($stackPtr, 'Class has doc comment', 'no'); return; } $phpcsFile->recordMetric($stackPtr, 'Class has doc comment', 'yes'); if ($tokens[$commentEnd]['code'] === T_COMMENT) { $phpcsFile->addError('You must use "/**" style comments for a class comment', $stackPtr, 'WrongStyle'); return; } if ($tokens[$commentEnd]['line'] !== $tokens[$stackPtr]['line'] - 1) { $error = 'There must be no blank lines after the class comment'; $phpcsFile->addError($error, $commentEnd, 'SpacingAfter'); } $commentStart = $tokens[$commentEnd]['comment_opener']; foreach ($tokens[$commentStart]['comment_tags'] as $tag) { $error = '%s tag is not allowed in class comment'; $data = array($tokens[$tag]['content']); $phpcsFile->addWarning($error, $tag, 'TagNotAllowed', $data); } }
/** * 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(File $phpcsFile, $stackPtr) { $tokens = $phpcsFile->getTokens(); $memberProps = $phpcsFile->getMemberProperties($stackPtr); if (empty($memberProps) === true) { return; } $memberName = ltrim($tokens[$stackPtr]['content'], '$'); $scope = $memberProps['scope']; $scopeSpecified = $memberProps['scope_specified']; if ($memberProps['scope'] === 'private') { $isPublic = false; } else { $isPublic = true; } // 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 ($isPublic === true && $scopeSpecified === true && $memberName[0] === '_') { $error = '%s member variable "%s" must not be prefixed with an underscore'; $data = array(ucfirst($scope), $memberName); $phpcsFile->addError($error, $stackPtr, 'PublicUnderscore', $data); 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(File $phpcsFile, $stackPtr) { $tokens = $phpcsFile->getTokens(); if ($tokens[$stackPtr]['content'] !== 'opacity') { return; } $next = $phpcsFile->findNext(array(T_COLON, T_WHITESPACE), $stackPtr + 1, null, true); if ($next === false || $tokens[$next]['code'] !== T_DNUMBER && $tokens[$next]['code'] !== T_LNUMBER) { return; } $value = $tokens[$next]['content']; if ($tokens[$next]['code'] === T_LNUMBER) { if ($value !== '0' && $value !== '1') { $error = 'Opacity values must be between 0 and 1'; $phpcsFile->addError($error, $next, 'Invalid'); } } else { if (strlen($value) > 3) { $error = 'Opacity values must have a single value after the decimal point'; $phpcsFile->addError($error, $next, 'DecimalPrecision'); } else { if ($value === '0.0' || $value === '1.0') { $error = 'Opacity value does not require decimal point; use %s instead'; $data = array($value[0]); $fix = $phpcsFile->addFixableError($error, $next, 'PointNotRequired', $data); if ($fix === true) { $phpcsFile->fixer->replaceToken($next, $value[0]); } } else { if ($value[0] === '.') { $error = 'Opacity values must not start with a decimal point; use 0%s instead'; $data = array($value); $fix = $phpcsFile->addFixableError($error, $next, 'StartWithPoint', $data); if ($fix === true) { $phpcsFile->fixer->replaceToken($next, '0' . $value); } } else { if ($value[0] !== '0') { $error = 'Opacity values must be between 0 and 1'; $phpcsFile->addError($error, $next, 'Invalid'); } } } } //end if } //end if }
/** * 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(File $phpcsFile, $stackPtr) { $tokens = $phpcsFile->getTokens(); // Ignore abstract methods. if (isset($tokens[$stackPtr]['scope_opener']) === false) { return; } // Detect start and end of this function definition. $start = $tokens[$stackPtr]['scope_opener']; $end = $tokens[$stackPtr]['scope_closer']; $nestingLevel = 0; // Find the maximum nesting level of any token in the function. for ($i = $start + 1; $i < $end; $i++) { $level = $tokens[$i]['level']; if ($nestingLevel < $level) { $nestingLevel = $level; } } // We subtract the nesting level of the function itself. $nestingLevel = $nestingLevel - $tokens[$stackPtr]['level'] - 1; if ($nestingLevel > $this->absoluteNestingLevel) { $error = 'Function\'s nesting level (%s) exceeds allowed maximum of %s'; $data = array($nestingLevel, $this->absoluteNestingLevel); $phpcsFile->addError($error, $stackPtr, 'MaxExceeded', $data); } else { if ($nestingLevel > $this->nestingLevel) { $warning = 'Function\'s nesting level (%s) exceeds %s; consider refactoring the function'; $data = array($nestingLevel, $this->nestingLevel); $phpcsFile->addWarning($warning, $stackPtr, 'TooHigh', $data); } } }
/** * 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(File $phpcsFile, $stackPtr) { $fileName = $phpcsFile->getFilename(); $matches = array(); if (preg_match('|/systems/(.*)/([^/]+)?actions.inc$|i', $fileName, $matches) === 0) { // Not an actions file. return; } $ownClass = $matches[2]; $tokens = $phpcsFile->getTokens(); $typeName = $phpcsFile->findNext(T_CONSTANT_ENCAPSED_STRING, $stackPtr + 2, null, false, true); $typeName = trim($tokens[$typeName]['content'], " '"); switch (strtolower($tokens[$stackPtr + 1]['content'])) { case 'includesystem': $included = strtolower($typeName); break; case 'includeasset': $included = strtolower($typeName) . 'assettype'; break; case 'includewidget': $included = strtolower($typeName) . 'widgettype'; break; default: return; } if ($included === strtolower($ownClass)) { $error = "You do not need to include \"%s\" from within the system's own actions file"; $data = array($ownClass); $phpcsFile->addError($error, $stackPtr, 'NotRequired', $data); } }
/** * 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(File $phpcsFile, $stackPtr) { $tokens = $phpcsFile->getTokens(); // Find the content of each style definition name. $styleNames = array(); $next = $stackPtr; $end = $tokens[$stackPtr]['bracket_closer']; do { $next = $phpcsFile->findNext(array(T_STYLE, T_OPEN_CURLY_BRACKET), $next + 1, $end); if ($next === false) { // Class definition is empty. break; } if ($tokens[$next]['code'] === T_OPEN_CURLY_BRACKET) { $next = $tokens[$next]['bracket_closer']; continue; } $name = $tokens[$next]['content']; if (isset($styleNames[$name]) === true) { $first = $styleNames[$name]; $error = 'Duplicate style definition found; first defined on line %s'; $data = array($tokens[$first]['line']); $phpcsFile->addError($error, $next, 'Found', $data); } else { $styleNames[$name] = $next; } } while ($next !== false); }
/** * 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(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); if ($nameEnd === false) { $name = $tokens[$nameStart]['content']; } else { $name = trim($phpcsFile->getTokensAsString($nameStart, $nameEnd - $nameStart)); } // Check for camel caps format. $valid = Common::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); $phpcsFile->recordMetric($stackPtr, 'CamelCase class name', 'no'); } else { $phpcsFile->recordMetric($stackPtr, 'CamelCase class name', 'yes'); } }
/** * 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(File $phpcsFile, $stackPtr) { $tokens = $phpcsFile->getTokens(); // We are only interested in the first token in a multi-line string. if ($tokens[$stackPtr]['code'] === $tokens[$stackPtr - 1]['code']) { return; } $workingString = $tokens[$stackPtr]['content']; $lastStringToken = $stackPtr; $i = $stackPtr + 1; if (isset($tokens[$i]) === true) { while ($i < $phpcsFile->numTokens && $tokens[$i]['code'] === $tokens[$stackPtr]['code']) { $workingString .= $tokens[$i]['content']; $lastStringToken = $i; $i++; } } // Check if it's a double quoted string. if (strpos($workingString, '"') === false) { return; } // Make sure it's not a part of a string started in a previous line. // If it is, then we have already checked it. if ($workingString[0] !== '"') { return; } // The use of variables in double quoted strings is not allowed. if ($tokens[$stackPtr]['code'] === T_DOUBLE_QUOTED_STRING) { $stringTokens = token_get_all('<?php ' . $workingString); foreach ($stringTokens as $token) { if (is_array($token) === true && $token[0] === T_VARIABLE) { $error = 'Variable "%s" not allowed in double quoted string; use concatenation instead'; $data = array($token[1]); $phpcsFile->addError($error, $stackPtr, 'ContainsVar', $data); } } return; } //end if $allowedChars = array('\\0', '\\1', '\\2', '\\3', '\\4', '\\5', '\\6', '\\7', '\\n', '\\r', '\\f', '\\t', '\\v', '\\x', '\\b', '\\e', '\\u', '\''); foreach ($allowedChars as $testChar) { if (strpos($workingString, $testChar) !== false) { return; } } $error = 'String %s does not require double quotes; use single quotes instead'; $data = array(str_replace("\n", '\\n', $workingString)); $fix = $phpcsFile->addFixableError($error, $stackPtr, 'NotRequired', $data); if ($fix === true) { $phpcsFile->fixer->beginChangeset(); $innerContent = substr($workingString, 1, -1); $innerContent = str_replace('\\"', '"', $innerContent); $phpcsFile->fixer->replaceToken($stackPtr, "'{$innerContent}'"); while ($lastStringToken !== $stackPtr) { $phpcsFile->fixer->replaceToken($lastStringToken, ''); $lastStringToken--; } $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(File $phpcsFile, $stackPtr) { $tokens = $phpcsFile->getTokens(); // Check if the next non whitespace token is a string. $index = $phpcsFile->findNext(T_WHITESPACE, $stackPtr + 1, null, true); if ($tokens[$index]['code'] !== T_CONSTANT_ENCAPSED_STRING) { return; } // Make sure it is the only thing in the square brackets. $next = $phpcsFile->findNext(T_WHITESPACE, $index + 1, null, true); if ($tokens[$next]['code'] !== T_CLOSE_SQUARE_BRACKET) { return; } // Allow indexes that have dots in them because we can't write // them in dot notation. $content = trim($tokens[$index]['content'], '"\' '); if (strpos($content, '.') !== false) { return; } // Also ignore reserved words. if ($content === 'super') { return; } // Token before the opening square bracket cannot be a var name. $prev = $phpcsFile->findPrevious(T_WHITESPACE, $stackPtr - 1, null, true); if ($tokens[$prev]['code'] === T_STRING) { $error = 'Object indexes must be written in dot notation'; $phpcsFile->addError($error, $prev, 'Found'); } }
/** * 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(File $phpcsFile, $stackPtr, $currScope) { $tokens = $phpcsFile->getTokens(); $methodName = $phpcsFile->getDeclarationName($stackPtr); if ($methodName === null) { // Ignore closures. return; } if ($phpcsFile->hasCondition($stackPtr, T_FUNCTION) === true) { // Ignore nested functions. return; } $modifier = null; for ($i = $stackPtr - 1; $i > 0; $i--) { if ($tokens[$i]['line'] < $tokens[$stackPtr]['line']) { break; } else { if (isset(Tokens::$scopeModifiers[$tokens[$i]['code']]) === true) { $modifier = $i; break; } } } if ($modifier === null) { $error = 'Visibility must be declared on method "%s"'; $data = array($methodName); $phpcsFile->addError($error, $stackPtr, 'Missing', $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(File $phpcsFile, $stackPtr) { $tokens = $phpcsFile->getTokens(); if ($tokens[$stackPtr]['content'] === 'ob_end_flush') { $phpcsFile->addError('Use of ob_end_flush() is not allowed; use ob_get_contents() and ob_end_clean() instead', $stackPtr, 'Found'); } }
/** * 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(File $phpcsFile, $stackPtr) { $tokens = $phpcsFile->getTokens(); // Ignore this.something and other uses of "this" that are not // direct assignments. $next = $phpcsFile->findNext(T_WHITESPACE, $stackPtr + 1, null, true); if ($tokens[$next]['code'] !== T_SEMICOLON) { if ($tokens[$next]['line'] === $tokens[$stackPtr]['line']) { return; } } // Something must be assigned to "this". $prev = $phpcsFile->findPrevious(T_WHITESPACE, $stackPtr - 1, null, true); if ($tokens[$prev]['code'] !== T_EQUAL) { return; } // A variable needs to be assigned to "this". $prev = $phpcsFile->findPrevious(T_WHITESPACE, $prev - 1, null, true); if ($tokens[$prev]['code'] !== T_STRING) { return; } // We can only assign "this" to a var called "self". if ($tokens[$prev]['content'] !== 'self' && $tokens[$prev]['content'] !== '_self') { $error = 'Keyword "this" can only be assigned to a variable called "self" or "_self"'; $phpcsFile->addError($error, $prev, 'NotSelf'); } }
/** * 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(File $phpcsFile, $stackPtr) { $this->currentFile = $phpcsFile; $tokens = $phpcsFile->getTokens(); // Ignore abstract methods. if (isset($tokens[$stackPtr]['scope_opener']) === false) { return; } // Detect start and end of this function definition. $start = $tokens[$stackPtr]['scope_opener']; $end = $tokens[$stackPtr]['scope_closer']; // Predicate nodes for PHP. $find = array(T_CASE => true, T_DEFAULT => true, T_CATCH => true, T_IF => true, T_FOR => true, T_FOREACH => true, T_WHILE => true, T_DO => true, T_ELSEIF => true); $complexity = 1; // Iterate from start to end and count predicate nodes. for ($i = $start + 1; $i < $end; $i++) { if (isset($find[$tokens[$i]['code']]) === true) { $complexity++; } } if ($complexity > $this->absoluteComplexity) { $error = 'Function\'s cyclomatic complexity (%s) exceeds allowed maximum of %s'; $data = array($complexity, $this->absoluteComplexity); $phpcsFile->addError($error, $stackPtr, 'MaxExceeded', $data); } else { if ($complexity > $this->complexity) { $warning = 'Function\'s cyclomatic complexity (%s) exceeds %s; consider refactoring the function'; $data = array($complexity, $this->complexity); $phpcsFile->addWarning($warning, $stackPtr, 'TooHigh', $data); } } }
/** * 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(File $phpcsFile, $stackPtr) { $tokens = $phpcsFile->getTokens(); $lastLine = $tokens[$stackPtr]['line']; $end = $tokens[$stackPtr]['bracket_closer']; $endLine = $tokens[$end]['line']; // Do not check nested style definitions as, for example, in @media style rules. $nested = $phpcsFile->findNext(T_OPEN_CURLY_BRACKET, $stackPtr + 1, $end); if ($nested !== false) { return; } $foundColon = false; $foundString = false; for ($i = $stackPtr + 1; $i <= $end; $i++) { if ($tokens[$i]['line'] !== $lastLine) { // We changed lines. if ($foundColon === false && $foundString !== false) { // We didn't find a colon on the previous line. $error = 'No style definition found on line; check for missing colon'; $phpcsFile->addError($error, $foundString, 'Found'); } $foundColon = false; $foundString = false; $lastLine = $tokens[$i]['line']; } if ($tokens[$i]['code'] === T_STRING) { $foundString = $i; } else { if ($tokens[$i]['code'] === T_COLON) { $foundColon = $i; } } } //end for }
/** * Processes the tokens within the scope. * * @param PHP_CodeSniffer_File $phpcsFile The file being processed. * @param int $stackPtr The position where this token was * found. * @param int $currScope The position of the current scope. * * @return void */ protected function processTokenWithinScope(File $phpcsFile, $stackPtr, $currScope) { $methodName = $phpcsFile->getDeclarationName($stackPtr); if ($methodName === null) { // Ignore closures. return; } // Ignore magic methods. if (preg_match('|^__|', $methodName) !== 0) { $magicPart = strtolower(substr($methodName, 2)); if (isset($this->magicMethods[$magicPart]) === true || isset($this->methodsDoubleUnderscore[$magicPart]) === true) { return; } } $testName = ltrim($methodName, '_'); if ($testName !== '' && Common::isCamelCaps($testName, false, true, false) === false) { $error = 'Method name "%s" is not in camel caps format'; $className = $phpcsFile->getDeclarationName($currScope); $errorData = array($className . '::' . $methodName); $phpcsFile->addError($error, $stackPtr, 'NotCamelCaps', $errorData); $phpcsFile->recordMetric($stackPtr, 'CamelCase method name', 'no'); } else { $phpcsFile->recordMetric($stackPtr, 'CamelCase method name', 'yes'); } }
/** * 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. * @param int $currScope A pointer to the start of the scope. * * @return void */ public function processTokenWithinScope(File $phpcsFile, $stackPtr, $currScope) { $tokens = $phpcsFile->getTokens(); $function = $tokens[$stackPtr + 2]; if ($function['code'] !== T_STRING) { return; } $functionName = $function['content']; $classOpener = $tokens[$currScope]['scope_condition']; $className = $tokens[$classOpener + 2]['content']; $methodProps = $phpcsFile->getMethodProperties($stackPtr); if ($methodProps['is_static'] === true) { if (isset($tokens[$stackPtr]['scope_closer']) === false) { // There is no scope opener or closer, so the function // must be abstract. return; } $thisUsage = $stackPtr; while (($thisUsage = $phpcsFile->findNext(array(T_VARIABLE), $thisUsage + 1, $tokens[$stackPtr]['scope_closer'], false, '$this')) !== false) { if ($thisUsage === false) { return; } $error = 'Usage of "$this" in static methods will cause runtime errors'; $phpcsFile->addError($error, $thisUsage, 'Found'); } } //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(File $phpcsFile, $stackPtr) { $closeTag = $phpcsFile->findNext(T_CLOSE_TAG, $stackPtr); if ($closeTag === false) { $error = 'The PHP open tag does not have a corresponding PHP close tag'; $phpcsFile->addError($error, $stackPtr, 'NotFound'); } }
/** * 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(File $phpcsFile, $stackPtr) { $tokens = $phpcsFile->getTokens(); if (strtolower($tokens[$stackPtr]['content']) === 'console') { $error = 'Variables, functions and labels must not be named "console"; name may conflict with Firebug internal variable'; $phpcsFile->addError($error, $stackPtr, 'ConflictFound'); } }
/** * 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(File $phpcsFile, $stackPtr) { $nextClass = $phpcsFile->findNext($this->register(), $stackPtr + 1); if ($nextClass !== false) { $error = 'Only one class is allowed in a file'; $phpcsFile->addError($error, $nextClass, 'MultipleFound'); } }
/** * 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(File $phpcsFile, $stackPtr) { $tokens = $phpcsFile->getTokens(); // Equal sign can't be the last thing on the line. $next = $phpcsFile->findNext(T_WHITESPACE, $stackPtr + 1, null, true); if ($next === false) { // Bad assignment. return; } if ($tokens[$next]['line'] !== $tokens[$stackPtr]['line']) { $error = 'Multi-line assignments must have the equal sign on the second line'; $phpcsFile->addError($error, $stackPtr, 'EqualSignLine'); return; } // Make sure it is the first thing on the line, otherwise we ignore it. $prev = $phpcsFile->findPrevious(T_WHITESPACE, $stackPtr - 1, false, true); if ($prev === false) { // Bad assignment. return; } if ($tokens[$prev]['line'] === $tokens[$stackPtr]['line']) { return; } // Find the required indent based on the ident of the previous line. $assignmentIndent = 0; $prevLine = $tokens[$prev]['line']; for ($i = $prev - 1; $i >= 0; $i--) { if ($tokens[$i]['line'] !== $prevLine) { $i++; break; } } if ($tokens[$i]['code'] === T_WHITESPACE) { $assignmentIndent = strlen($tokens[$i]['content']); } // Find the actual indent. $prev = $phpcsFile->findPrevious(T_WHITESPACE, $stackPtr - 1); $expectedIndent = $assignmentIndent + $this->indent; $foundIndent = strlen($tokens[$prev]['content']); if ($foundIndent !== $expectedIndent) { $error = 'Multi-line assignment not indented correctly; expected %s spaces but found %s'; $data = array($expectedIndent, $foundIndent); $phpcsFile->addError($error, $stackPtr, 'Indent', $data); } }
/** * 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(File $phpcsFile, $stackPtr) { $tokens = $phpcsFile->getTokens(); $next = $phpcsFile->findNext(Tokens::$emptyTokens, $stackPtr + 1, null, true); if ($next === false || $tokens[$next]['code'] === T_CLOSE_CURLY_BRACKET) { $error = 'Class definition is empty'; $phpcsFile->addError($error, $stackPtr, 'Found'); } }
/** * 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(File $phpcsFile, $stackPtr) { $tokens = $phpcsFile->getTokens(); $next = $phpcsFile->findNext(array(T_WHITESPACE, T_COLON), $stackPtr + 1, null, true); if ($next === false || $tokens[$next]['code'] === T_SEMICOLON || $tokens[$next]['line'] !== $tokens[$stackPtr]['line']) { $error = 'Style definition is empty'; $phpcsFile->addError($error, $stackPtr, 'Found'); } }
/** * Processes the tokens outside the scope. * * @param PHP_CodeSniffer_File $phpcsFile The file being processed. * @param int $stackPtr The position where this token was * found. * * @return void */ protected function processTokenOutsideScope(File $phpcsFile, $stackPtr) { $functionName = $phpcsFile->getDeclarationName($stackPtr); if ($functionName === null) { return; } $errorData = array($functionName); // Does this function claim to be magical? if (preg_match('|^__|', $functionName) !== 0) { $error = 'Function name "%s" is invalid; only PHP magic methods should be prefixed with a double underscore'; $phpcsFile->addError($error, $stackPtr, 'DoubleUnderscore', $errorData); return; } if (Common::isCamelCaps($functionName, false, true, false) === false) { $error = 'Function name "%s" is not in camel caps format'; $phpcsFile->addError($error, $stackPtr, 'NotCamelCaps', $errorData); } }
/** * 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(File $phpcsFile, $stackPtr) { $tokens = $phpcsFile->getTokens(); $nextVar = $tokens[$phpcsFile->findNext(array(T_VARIABLE), $stackPtr)]; $varName = str_replace('$', '', $nextVar['content']); $error = 'Use of the "global" keyword is forbidden; use "$GLOBALS[\'%s\']" instead'; $data = array($varName); $phpcsFile->addError($error, $stackPtr, 'NotAllowed', $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(File $phpcsFile, $stackPtr) { $tokens = $phpcsFile->getTokens(); // Ignore default value assignments in function definitions. $function = $phpcsFile->findPrevious(T_FUNCTION, $stackPtr - 1, null, false, null, true); if ($function !== false) { $opener = $tokens[$function]['parenthesis_opener']; $closer = $tokens[$function]['parenthesis_closer']; if ($opener < $stackPtr && $closer > $stackPtr) { return; } } // Ignore values in array definitions. $array = $phpcsFile->findNext(T_ARRAY, $stackPtr + 1, null, false, null, true); if ($array !== false) { return; } // Ignore function calls. $ignore = array(T_STRING, T_WHITESPACE, T_OBJECT_OPERATOR); $next = $phpcsFile->findNext($ignore, $stackPtr + 1, null, true); if ($tokens[$next]['code'] === T_OPEN_PARENTHESIS && $tokens[$next - 1]['code'] === T_STRING) { // Code will look like: $var = myFunction( // and will be ignored. return; } $endStatement = $phpcsFile->findNext(T_SEMICOLON, $stackPtr + 1); if ($tokens[$stackPtr]['conditions'] !== $tokens[$endStatement]['conditions']) { // This statement doesn't end with a semicolon, which is the case for // the last expression in a for loop. return; } for ($i = $stackPtr + 1; $i < $endStatement; $i++) { if (isset(Tokens::$comparisonTokens[$tokens[$i]['code']]) === true || $tokens[$i]['code'] === T_INLINE_THEN) { $error = 'The value of a comparison must not be assigned to a variable'; $phpcsFile->addError($error, $stackPtr, 'AssignedComparison'); break; } if (isset(Tokens::$booleanOperators[$tokens[$i]['code']]) === true || $tokens[$i]['code'] === T_BOOLEAN_NOT) { $error = 'The value of a boolean operation must not be assigned to a variable'; $phpcsFile->addError($error, $stackPtr, 'AssignedBool'); break; } } }
/** * 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(File $phpcsFile, $stackPtr) { $tokens = $phpcsFile->getTokens(); $scopeStart = $tokens[$stackPtr]['scope_opener']; $firstContent = $phpcsFile->findNext(T_WHITESPACE, $scopeStart + 1, $tokens[$stackPtr]['scope_closer'], true); if ($firstContent === false) { $error = 'Empty CATCH statement must have a comment to explain why the exception is not handled'; $phpcsFile->addError($error, $scopeStart, 'Missing'); } }
/** * 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(File $phpcsFile, $stackPtr) { $tokens = $phpcsFile->getTokens(); $content = $tokens[$stackPtr]['content']; if ($content !== strtolower($content)) { $error = '%s keyword must be lowercase; expected "%s" but found "%s"'; $data = array(strtoupper($content), strtolower($content), $content); $phpcsFile->addError($error, $stackPtr, 'FoundUppercase', $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(File $phpcsFile, $stackPtr) { // Ignore shebang lines. $tokens = $phpcsFile->getTokens(); if (substr($tokens[$stackPtr]['content'], 0, 2) === '#!') { return; } $error = 'PHP files must only contain PHP code'; $phpcsFile->addError($error, $stackPtr, 'Found'); return $phpcsFile->numTokens; }
/** * 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(File $phpcsFile, $stackPtr) { $error = 'Silencing errors is forbidden'; if ($this->error === true) { $error = 'Silencing errors is forbidden'; $phpcsFile->addError($error, $stackPtr, 'Forbidden'); } else { $error = 'Silencing errors is discouraged'; $phpcsFile->addWarning($error, $stackPtr, 'Discouraged'); } }