/**
  * 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) {
         $error = 'possible parse error: ';
         $error .= $tokens[$stackptr]['content'];
         $error .= ' missing opening or closing brace';
         $phpcsfile->addwarning($error, $stackptr);
         return;
     }
     $curlybrace = $tokens[$stackptr]['scope_opener'];
     $lastcontent = $phpcsfile->findprevious(T_WHITESPACE, $curlybrace - 1, $stackptr, true);
     $classline = $tokens[$lastcontent]['line'];
     $braceline = $tokens[$curlybrace]['line'];
     if ($braceline != $classline) {
         $error = 'Opening brace of a ';
         $error .= $tokens[$stackptr]['content'];
         $error .= ' must be on the same line as the definition';
         $phpcsfile->adderror($error, $curlybrace);
         return;
     }
     if ($tokens[$curlybrace - 1]['code'] === T_WHITESPACE) {
         $prevcontent = $tokens[$curlybrace - 1]['content'];
         if ($prevcontent !== $phpcsfile->eolChar) {
             $blankspace = substr($prevcontent, strpos($prevcontent, $phpcsfile->eolChar));
             $spaces = strlen($blankspace);
             if ($spaces !== 1) {
                 $error = "Expected 1 space before opening brace; {$spaces} found";
                 $phpcsfile->adderror($error, $curlybrace);
             }
         }
     }
 }
 /**
  * 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();
     $workingstring = $tokens[$stackptr]['content'];
     // Check if it's a double quoted string.
     if (strpos($workingstring, '"') === false) {
         return;
     }
     // Make sure it's not a part of a string started above.
     // If it is, then we have already checked it.
     if ($workingstring[0] !== '"') {
         return;
     }
     // Work through the following tokens, in case this string is stretched
     // over multiple Lines.
     for ($i = $stackptr + 1; $i < $phpcsfile->numTokens; $i++) {
         if ($tokens[$i]['type'] !== 'T_CONSTANT_ENCAPSED_STRING') {
             break;
         }
         $workingstring .= $tokens[$i]['content'];
     }
     $allowedchars = array('\\n', '\\r', '\\f', '\\t', '\\v', '\\x', '\'', '$');
     foreach ($allowedchars as $testchar) {
         if (strpos($workingstring, $testchar) !== false) {
             return;
         }
     }
     $error = "String {$workingstring} does not require double quotes; use single quotes instead";
     $phpcsfile->addwarning($error, $stackptr);
 }
Example #3
0
 /**
  * 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();
     $last_token = end($tokens);
     if ($last_token['code'] === T_CLOSE_TAG) {
         $error = 'Closing PHP tag is not required at the end of the file. Please remove.';
         $phpcsfile->addwarning($error, $stackptr);
     }
 }
Example #4
0
 /**
  * Process the version tag.
  *
  * @param int $errorpos The line number where the error occurs.
  *
  * @return void
  */
 protected function processversion($errorpos)
 {
     $version = $this->commentparser->getVersion();
     if ($version !== null) {
         $content = $version->getcontent();
         $matches = array();
         if (empty($content) === true) {
             $error = 'content missing for @version tag in file comment';
             $this->currentfile->adderror($error, $errorpos);
         } else {
             if (strstr($content, 'CVS:') === false && strstr($content, 'SVN:') === false) {
                 $error = "Invalid version \"{$content}\" in file comment; consider \"CVS: <cvs_id>\" or \"SVN: <svn_id>\" instead";
                 $this->currentfile->addwarning($error, $errorpos);
             }
         }
     }
 }
 /**
  * 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();
     $token = $tokens[$stackptr];
     // Skip for-statements without body.
     if (isset($token['scope_opener']) === false) {
         return;
     }
     // Fetch previous token.
     $prev = $phpcsfile->findprevious(PHP_CodeSniffer_tokens::$emptyTokens, $stackptr - 1, null, true);
     // Skip for non final class.
     if ($prev === false || $tokens[$prev]['code'] !== T_FINAL) {
         return;
     }
     $next = ++$token['scope_opener'];
     $end = --$token['scope_closer'];
     for (; $next <= $end; ++$next) {
         if ($tokens[$next]['code'] === T_FINAL) {
             $error = 'Unnecessary FINAL modifier in FINAL class';
             $phpcsfile->addwarning($error, $next);
         }
     }
 }
Example #6
0
 /**
  * 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();
     $token = $tokens[$stackptr];
     // Skip for-statements without body.
     if (isset($token['scope_opener']) === false) {
         return;
     }
     $next = ++$token['scope_opener'];
     $end = --$token['scope_closer'];
     $emptybody = true;
     for (; $next <= $end; ++$next) {
         if (in_array($tokens[$next]['code'], PHP_CodeSniffer_tokens::$emptyTokens) === false) {
             $emptybody = false;
             break;
         }
     }
     if ($emptybody === true) {
         // Get token identifier.
         $name = $phpcsfile->gettokensAsString($stackptr, 1);
         $error = sprintf('Empty %s statement detected', strtoupper($name));
         if ($this->_tokens[$token['code']] === true) {
             $phpcsfile->adderror($error, $stackptr);
         } else {
             $phpcsfile->addwarning($error, $stackptr);
         }
     }
 }
Example #7
0
 /**
  * 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)
 {
     // Modify array of required tags
     $this->tags['package']['required'] = false;
     $this->tags['copyright']['required'] = false;
     $this->tags['author']['required'] = false;
     $this->currentfile = $phpcsfile;
     $tokens = $phpcsfile->gettokens();
     $type = strtolower($tokens[$stackptr]['content']);
     $find = array(T_ABSTRACT, T_WHITESPACE, T_FINAL);
     // Extract the class comment docblock.
     $commentend = $phpcsfile->findprevious($find, $stackptr - 1, null, true);
     if ($commentend !== false && $tokens[$commentend]['code'] === T_COMMENT) {
         $phpcsfile->adderror("You must use \"/**\" style comments for a {$type} comment", $stackptr);
         return;
     } else {
         if ($commentend === false || $tokens[$commentend]['code'] !== T_DOC_COMMENT) {
             $phpcsfile->adderror("Missing {$type} doc comment", $stackptr);
             return;
         }
     }
     $commentstart = $phpcsfile->findprevious(T_DOC_COMMENT, $commentend - 1, null, true) + 1;
     $commentnext = $phpcsfile->findprevious(T_WHITESPACE, $commentend + 1, $stackptr, false, $phpcsfile->eolChar);
     // Distinguish file and class comment.
     $prevclasstoken = $phpcsfile->findprevious(T_CLASS, $stackptr - 1);
     if ($prevclasstoken === false) {
         // This is the first class token in this file, need extra checks.
         $prevnoncomment = $phpcsfile->findprevious(T_DOC_COMMENT, $commentstart - 1, null, true);
         if ($prevnoncomment !== false) {
             $prevcomment = $phpcsfile->findprevious(T_DOC_COMMENT, $prevnoncomment - 1);
             if ($prevcomment === false) {
                 // There is only 1 doc comment between open tag and class token.
                 $newlinetoken = $phpcsfile->findnext(T_WHITESPACE, $commentend + 1, $stackptr, false, $phpcsfile->eolChar);
                 if ($newlinetoken !== false) {
                     $newlinetoken = $phpcsfile->findnext(T_WHITESPACE, $newlinetoken + 1, $stackptr, false, $phpcsfile->eolChar);
                     if ($newlinetoken !== false) {
                         // Blank line between the class and the doc block.
                         // The doc block is most likely a file comment.
                         $phpcsfile->adderror("Missing {$type} doc comment", $stackptr + 1);
                         return;
                     }
                 }
             }
         }
     }
     $comment = $phpcsfile->gettokensAsString($commentstart, $commentend - $commentstart + 1);
     // Parse the class comment.docblock.
     try {
         $this->commentparser = new PHP_CodeSniffer_CommentParser_ClassCommentParser($comment, $phpcsfile);
         $this->commentparser->parse();
     } catch (PHP_CodeSniffer_CommentParser_ParserException $e) {
         $line = $e->getlinewithinComment() + $commentstart;
         $phpcsfile->adderror($e->getMessage(), $line);
         return;
     }
     $comment = $this->commentparser->getComment();
     if (is_null($comment) === true) {
         $error = ucfirst($type) . ' doc comment is empty';
         $phpcsfile->adderror($error, $commentstart);
         return;
     }
     // No extra newline before short description.
     $short = $comment->getShortComment();
     $newlinecount = 0;
     $newlinespan = strspn($short, $phpcsfile->eolChar);
     if ($short !== '' && $newlinespan > 0) {
         $line = $newlinespan > 1 ? 'newlines' : 'newline';
         $error = "Extra {$line} found before {$type} comment short description";
         $phpcsfile->adderror($error, $commentstart + 1);
     }
     $newlinecount = substr_count($short, $phpcsfile->eolChar) + 1;
     // Exactly one blank line between short and long description.
     $long = $comment->getlongcomment();
     if (empty($long) === false) {
         $between = $comment->getWhiteSpacebetween();
         $newlinebetween = substr_count($between, $phpcsfile->eolChar);
         if ($newlinebetween !== 2) {
             $error = "There must be exactly one blank line between descriptions in {$type} comments";
             $phpcsfile->adderror($error, $commentstart + $newlinecount + 1);
         }
         $newlinecount += $newlinebetween;
     }
     // Exactly one blank line before tags.
     $tags = $this->commentparser->gettagOrders();
     if (count($tags) > 1) {
         $newlinespan = $comment->getNewlineAfter();
         if ($newlinespan !== 2) {
             $error = "There must be exactly one blank line before the tags in {$type} comments";
             if ($long !== '') {
                 $newlinecount += substr_count($long, $phpcsfile->eolChar) - $newlinespan + 1;
             }
             $phpcsfile->addwarning($error, $commentstart + $newlinecount);
             $short = rtrim($short, $phpcsfile->eolChar . ' ');
         }
     }
     // Check each tag.
     $this->processtags($commentstart, $commentend);
 }
 /**
  * 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();
     $token = $tokens[$stackptr];
     // Skip broken function declarations.
     if (isset($token['scope_opener']) === false || isset($token['parenthesis_opener']) === false) {
         return;
     }
     $params = array();
     foreach ($phpcsfile->getmethodparameters($stackptr) as $param) {
         $params[$param['name']] = $stackptr;
     }
     $next = ++$token['scope_opener'];
     $end = --$token['scope_closer'];
     $emptybody = true;
     for (; $next <= $end; ++$next) {
         $token = $tokens[$next];
         $code = $token['code'];
         // Ingorable tokens.
         if (in_array($code, PHP_CodeSniffer_tokens::$emptyTokens) === true) {
             continue;
         } else {
             if ($code === T_THROW && $emptybody === true) {
                 // Throw statement and an empty body indicate an interface method.
                 return;
             } else {
                 if ($code === T_RETURN && $emptybody === true) {
                     // Return statement and an empty body indicate an interface method.
                     $tmp = $phpcsfile->findnext(PHP_CodeSniffer_tokens::$emptyTokens, $next + 1, null, true);
                     if ($tmp === false) {
                         return;
                     }
                     // There is a return.
                     if ($tokens[$tmp] === T_SEMICOLON) {
                         return;
                     }
                     $tmp = $phpcsfile->findnext(PHP_CodeSniffer_tokens::$emptyTokens, $tmp + 1, null, true);
                     // There is a return <token>.
                     if ($tmp !== false && $tokens[$tmp] === T_SEMICOLON) {
                         return;
                     }
                 }
             }
         }
         $emptybody = false;
         if ($code === T_VARIABLE && isset($params[$token['content']]) === true) {
             unset($params[$token['content']]);
         } else {
             if ($code === T_DOUBLE_QUOTED_STRING) {
                 // tokenize double quote string.
                 $strtokens = token_get_all(sprintf('<?php %s;?>', $token['content']));
                 foreach ($strtokens as $tok) {
                     if (is_array($tok) === false || $tok[0] !== T_VARIABLE) {
                         continue;
                     }
                     if (isset($params[$tok[1]]) === true) {
                         unset($params[$tok[1]]);
                     }
                 }
             }
         }
     }
     if ($emptybody === false && count($params) > 0) {
         foreach ($params as $paramname => $position) {
             $error = 'The method parameter ' . $paramname . ' is never used';
             $phpcsfile->addwarning($error, $position);
         }
     }
 }
 /**
  * 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();
     $token = $tokens[$stackptr];
     // Skip for-loop without body.
     if (isset($token['scope_opener']) === false) {
         return;
     }
     // Find incrementors for outer loop.
     $outer = $this->findincrementers($tokens, $token);
     // Skip if empty.
     if (count($outer) === 0) {
         return;
     }
     // Find nested for loops.
     $start = ++$token['scope_opener'];
     $end = --$token['scope_closer'];
     for (; $start <= $end; ++$start) {
         if ($tokens[$start]['code'] !== T_FOR) {
             continue;
         }
         $inner = $this->findincrementers($tokens, $tokens[$start]);
         $diff = array_intersect($outer, $inner);
         if (count($diff) !== 0) {
             $error = sprintf('Loop incrementor (%s) jumbling with inner loop', join(', ', $diff));
             $phpcsfile->addwarning($error, $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();
     $token = $tokens[$stackptr];
     // Skip invalid statement.
     if (isset($token['parenthesis_opener']) === false) {
         return;
     }
     $next = ++$token['parenthesis_opener'];
     $end = --$token['parenthesis_closer'];
     $position = 0;
     for (; $next <= $end; ++$next) {
         $code = $tokens[$next]['code'];
         if ($code === T_SEMICOLON) {
             ++$position;
         }
         if ($position < 1) {
             continue;
         } else {
             if ($position > 1) {
                 break;
             } else {
                 if ($code !== T_VARIABLE && $code !== T_STRING) {
                     continue;
                 }
             }
         }
         // Find next non empty token, if it is a open curly brace we have a
         // function call.
         $index = $phpcsfile->findnext(PHP_CodeSniffer_tokens::$emptyTokens, $next + 1, null, true);
         if ($tokens[$index]['code'] === T_OPEN_PARENTHESIS) {
             $error = 'Avoid function calls in a FOR loop test part';
             $phpcsfile->addwarning($error, $stackptr);
             break;
         }
     }
 }
 /**
  * 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();
     $token = $tokens[$stackptr];
     // Skip for-loop without body.
     if (isset($token['parenthesis_opener']) === false) {
         return;
     }
     $next = ++$token['parenthesis_opener'];
     $end = --$token['parenthesis_closer'];
     $goodcondition = false;
     for (; $next <= $end; ++$next) {
         $code = $tokens[$next]['code'];
         if (in_array($code, PHP_CodeSniffer_tokens::$emptyTokens) === true) {
             continue;
         } else {
             if ($code !== T_TRUE && $code !== T_FALSE) {
                 $goodcondition = true;
             }
         }
     }
     if ($goodcondition === false) {
         $error = 'Avoid IF statements that are always true or false';
         $phpcsfile->addwarning($error, $stackptr);
     }
 }
Example #12
0
 /**
  * Process the function parameter comments.
  *
  * @param int $commentstart The position in the stack where
  *                          the comment started.
  *
  * @return void
  */
 protected function processparams($commentstart)
 {
     $realparams = $this->currentfile->getmethodparameters($this->_functiontoken);
     $params = $this->commentparser->getparams();
     $foundparams = array();
     if (empty($params) === false) {
         $lastparm = count($params) - 1;
         if (substr_count($params[$lastparm]->getwhitespaceafter(), $this->currentfile->eolChar) !== 2) {
             $error = 'Last parameter comment requires a blank newline after it';
             $errorpos = $params[$lastparm]->getline() + $commentstart;
             $this->currentfile->addwarning($error, $errorpos);
         }
         $previousparam = null;
         $spacebeforevar = 10000;
         $spacebeforecomment = 10000;
         $longesttype = 0;
         $longestvar = 0;
         foreach ($params as $param) {
             $paramcomment = trim($param->getcomment());
             $errorpos = $param->getline() + $commentstart;
             // Make sure that there is only one space before the var type.
             if ($param->getwhitespacebeforetype() !== ' ') {
                 $error = 'Expected 1 space before variable type';
                 $this->currentfile->addwarning($error, $errorpos);
             }
             $spacecount = substr_count($param->getwhitespacebeforevarname(), ' ');
             if ($spacecount < $spacebeforevar) {
                 $spacebeforevar = $spacecount;
                 $longesttype = $errorpos;
             }
             $spacecount = substr_count($param->getwhitespacebeforecomment(), ' ');
             if ($spacecount < $spacebeforecomment && $paramcomment !== '') {
                 $spacebeforecomment = $spacecount;
                 $longestvar = $errorpos;
             }
             // Make sure they are in the correct order,
             // and have the correct name.
             $pos = $param->getposition();
             $paramname = $param->getvarname() !== '' ? $param->getvarname() : '[ UNKNOWN ]';
             if ($previousparam !== null) {
                 $previousname = $previousparam->getvarname() !== '' ? $previousparam->getvarname() : 'UNKNOWN';
                 // Check to see if the parameters align properly.
                 if ($param->alignsvariablewith($previousparam) === false) {
                     $error = 'The variable names for parameters ' . $previousname . ' (' . ($pos - 1) . ') and ' . $paramname . ' (' . $pos . ') do not align';
                     $this->currentfile->addwarning($error, $errorpos);
                 }
                 if ($param->alignsCommentWith($previousparam) === false) {
                     $error = 'The comments for parameters ' . $previousname . ' (' . ($pos - 1) . ') and ' . $paramname . ' (' . $pos . ') do not align';
                     $this->currentfile->addwarning($error, $errorpos);
                 }
             }
             // Make sure the names of the parameter comment matches the
             // actual parameter.
             if (isset($realparams[$pos - 1]) === true) {
                 $realname = $realparams[$pos - 1]['name'];
                 $foundparams[] = $realname;
                 // Append ampersand to name if passing by reference.
                 if ($realparams[$pos - 1]['pass_by_reference'] === true) {
                     $realname = '&' . $realname;
                 }
                 if ($realname !== $param->getvarname()) {
                     $error = 'Doc comment var "' . $paramname;
                     $error .= '" does not match actual variable name "' . $realname;
                     $error .= '" at position ' . $pos;
                     $this->currentfile->adderror($error, $errorpos);
                 }
             } else {
                 // We must have an extra parameter comment.
                 $error = 'Superfluous doc comment at position ' . $pos;
                 $this->currentfile->adderror($error, $errorpos);
             }
             if ($param->getvarname() === '') {
                 $error = 'Missing parameter name at position ' . $pos;
                 $this->currentfile->adderror($error, $errorpos);
             }
             if ($param->gettype() === '') {
                 $error = 'Missing type at position ' . $pos;
                 $this->currentfile->adderror($error, $errorpos);
             }
             if ($paramcomment === '') {
                 $error = 'Missing comment for param "' . $paramname . '" at position ' . $pos;
                 $this->currentfile->adderror($error, $errorpos);
             }
             $previousparam = $param;
         }
         if ($spacebeforevar !== 1 && $spacebeforevar !== 10000 && $spacebeforecomment !== 10000) {
             $error = 'Expected 1 space after the longest type';
             $this->currentfile->adderror($error, $longesttype);
         }
         if ($spacebeforecomment !== 1 && $spacebeforecomment !== 10000) {
             $error = 'Expected 1 space after the longest variable name';
             $this->currentfile->adderror($error, $longestvar);
         }
     }
     $realnames = array();
     foreach ($realparams as $realparam) {
         $realnames[] = $realparam['name'];
     }
     // Report and missing comments.
     $diff = array_diff($realnames, $foundparams);
     foreach ($diff as $neededparam) {
         if (count($params) !== 0) {
             $errorpos = $params[count($params) - 1]->getline() + $commentstart;
         } else {
             $errorpos = $commentstart;
         }
         $error = 'Doc comment for "' . $neededparam . '" missing';
         $this->currentfile->adderror($error, $errorpos);
     }
 }
 /**
  * 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();
     $token = $tokens[$stackptr];
     // Skip invalid statement.
     if (isset($token['parenthesis_opener']) === false) {
         return;
     }
     $next = ++$token['parenthesis_opener'];
     $end = --$token['parenthesis_closer'];
     $parts = array(0, 0, 0);
     $index = 0;
     for (; $next <= $end; ++$next) {
         $code = $tokens[$next]['code'];
         if ($code === T_SEMICOLON) {
             ++$index;
         } else {
             if (in_array($code, PHP_CodeSniffer_tokens::$emptyTokens) === false) {
                 ++$parts[$index];
             }
         }
     }
     if ($parts[0] === 0 && $parts[2] === 0 && $parts[1] > 0) {
         $error = 'This FOR loop can be simplified to a WHILE loop';
         $phpcsfile->addwarning($error, $stackptr);
     }
 }
Example #14
0
 /**
  * Checks if a line is too long.
  *
  * @param PHP_CodeSniffer_File $phpcsfile   The file being scanned.
  * @param int                  $stackptr    The token at the end of the line.
  * @param string               $linecontent The content of the line.
  *
  * @return void
  */
 protected function checklinelength(PHP_CodeSniffer_File $phpcsfile, $stackptr, $linecontent)
 {
     // If the content is a CVS or SVN id in a version tag, or it is
     // a license tag with a name and URL, there is nothing the
     // developer can do to shorten the line, so don't throw errors.
     if (preg_match('|@version[^\\$]+\\$Id|', $linecontent) === 0 && preg_match('|@license|', $linecontent) === 0) {
         $linelength = strlen($linecontent);
         if ($this->absolutelinelimit > 0 && $linelength > $this->absolutelinelimit) {
             $error = 'line exceeds maximum limit of ' . $this->absolutelinelimit . " characters; contains {$linelength} characters";
             $phpcsfile->adderror($error, $stackptr);
         } else {
             if ($linelength > $this->linelimit) {
                 $warning = 'line exceeds ' . $this->linelimit . " characters; contains {$linelength} characters";
                 $phpcsfile->addwarning($warning, $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();
     // Skip tokens that are the names of functions or classes
     // within their definitions. For example:
     // function myFunction...
     // "myFunction" is T_STRING but we should skip because it is not a
     // function or method *call*.
     $functionname = $stackptr;
     $functionkeyword = $phpcsfile->findprevious(PHP_CodeSniffer_tokens::$emptyTokens, $stackptr - 1, null, true);
     if ($tokens[$functionkeyword]['code'] === T_FUNCTION || $tokens[$functionkeyword]['code'] === T_CLASS) {
         return;
     }
     // If the next non-whitespace token after the function or method call
     // is not an opening parenthesis then it cant really be a *call*.
     $openbracket = $phpcsfile->findnext(PHP_CodeSniffer_tokens::$emptyTokens, $functionname + 1, null, true);
     if ($tokens[$openbracket]['code'] !== T_OPEN_PARENTHESIS) {
         return;
     }
     $closebracket = $tokens[$openbracket]['parenthesis_closer'];
     $nextseparator = $openbracket;
     while (($nextseparator = $phpcsfile->findnext(array(T_COMMA, T_VARIABLE), $nextseparator + 1, $closebracket)) !== false) {
         // Make sure the comma or variable belongs directly to this function call,
         // and is not inside a nested function call or array.
         $brackets = $tokens[$nextseparator]['nested_parenthesis'];
         $lastbracket = array_pop($brackets);
         if ($lastbracket !== $closebracket) {
             continue;
         }
         if ($tokens[$nextseparator]['code'] === T_COMMA) {
             if ($tokens[$nextseparator - 1]['code'] === T_WHITESPACE) {
                 $error = 'Space found before comma in function call';
                 $phpcsfile->addwarning($error, $stackptr);
             }
             if ($tokens[$nextseparator + 1]['code'] !== T_WHITESPACE) {
                 $error = 'No space found after comma in function call';
                 $phpcsfile->addwarning($error, $stackptr);
             } else {
                 // If there is a newline in the space, then the must be formatting
                 // each argument on a newline, which is valid, so ignore it.
                 if (strpos($tokens[$nextseparator + 1]['content'], $phpcsfile->eolChar) === false) {
                     $space = strlen($tokens[$nextseparator + 1]['content']);
                     if ($space > 1) {
                         $error = 'Expected 1 space after comma in function call; ';
                         $error .= $space . ' found';
                         $phpcsfile->addwarning($error, $stackptr);
                     }
                 }
             }
         } else {
             // token is a variable.
             $nexttoken = $phpcsfile->findnext(PHP_CodeSniffer_tokens::$emptyTokens, $nextseparator + 1, $closebracket, true);
             if ($nexttoken !== false) {
                 if ($tokens[$nexttoken]['code'] === T_EQUAL) {
                     if ($tokens[$nexttoken - 1]['code'] !== T_WHITESPACE) {
                         $error = 'Expected 1 space before = sign of default value';
                         $phpcsfile->addwarning($error, $stackptr);
                     }
                     if ($tokens[$nexttoken + 1]['code'] !== T_WHITESPACE) {
                         $error = 'Expected 1 space after = sign of default value';
                         $phpcsfile->addwarning($error, $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();
     $token = $tokens[$stackptr];
     // Skip function without body.
     if (isset($token['scope_opener']) === false) {
         return;
     }
     // Get function name.
     $methodname = $phpcsfile->getdeclarationname($stackptr);
     // Get all parameters from method signature.
     $signature = array();
     foreach ($phpcsfile->getmethodparameters($stackptr) as $param) {
         $signature[] = $param['name'];
     }
     $next = ++$token['scope_opener'];
     $end = --$token['scope_closer'];
     for (; $next <= $end; ++$next) {
         $code = $tokens[$next]['code'];
         if (in_array($code, PHP_CodeSniffer_tokens::$emptyTokens) === true) {
             continue;
         } else {
             if ($code === T_RETURN) {
                 continue;
             }
         }
         break;
     }
     // Any token except 'parent' indicates correct code.
     if ($tokens[$next]['code'] !== T_PARENT) {
         return;
     }
     // Find next non empty token index, should be double colon.
     $next = $phpcsfile->findnext(PHP_CodeSniffer_tokens::$emptyTokens, $next + 1, null, true);
     // Skip for invalid code.
     if ($next === false || $tokens[$next]['code'] !== T_DOUBLE_COLON) {
         return;
     }
     // Find next non empty token index, should be the function name.
     $next = $phpcsfile->findnext(PHP_CodeSniffer_tokens::$emptyTokens, $next + 1, null, true);
     // Skip for invalid code or other method.
     if ($next === false || $tokens[$next]['content'] !== $methodname) {
         return;
     }
     // Find next non empty token index, should be the open parenthesis.
     $next = $phpcsfile->findnext(PHP_CodeSniffer_tokens::$emptyTokens, $next + 1, null, true);
     // Skip for invalid code.
     if ($next === false || $tokens[$next]['code'] !== T_OPEN_PARENTHESIS) {
         return;
     }
     $validparametertypes = array(T_VARIABLE, T_LNUMBER, T_CONSTANT_ENCAPSED_STRING);
     $parameters = array('');
     $parenthesiscount = 1;
     $count = count($tokens);
     for (++$next; $next < $count; ++$next) {
         $code = $tokens[$next]['code'];
         if ($code === T_OPEN_PARENTHESIS) {
             ++$parenthesiscount;
         } else {
             if ($code === T_CLOSE_PARENTHESIS) {
                 --$parenthesiscount;
             } else {
                 if ($parenthesiscount === 1 && $code === T_COMMA) {
                     $parameters[] = '';
                 } else {
                     if (in_array($code, PHP_CodeSniffer_tokens::$emptyTokens) === false) {
                         $parameters[count($parameters) - 1] .= $tokens[$next]['content'];
                     }
                 }
             }
         }
         if ($parenthesiscount === 0) {
             break;
         }
     }
     $next = $phpcsfile->findnext(PHP_CodeSniffer_tokens::$emptyTokens, $next + 1, null, true);
     if ($next === false || $tokens[$next]['code'] !== T_SEMICOLON) {
         return;
     }
     // Check rest of the scope.
     for (++$next; $next <= $end; ++$next) {
         $code = $tokens[$next]['code'];
         // Skip for any other content.
         if (in_array($code, PHP_CodeSniffer_tokens::$emptyTokens) === false) {
             return;
         }
     }
     $parameters = array_map('trim', $parameters);
     $parameters = array_filter($parameters);
     if (count($parameters) === count($signature) && $parameters === $signature) {
         $phpcsfile->addwarning('Useless method overriding detected', $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();
     if (isset($tokens[$stackptr]['scope_opener']) === false) {
         // Ignore the ELSE in ELSE IF. We'll process the IF part later.
         if ($tokens[$stackptr]['code'] === T_ELSE && $tokens[$stackptr + 2]['code'] === T_IF) {
             return;
         }
         if ($tokens[$stackptr]['code'] === T_WHILE) {
             // This could be from a DO WHILE, which doesn't have an opening brace.
             $lastcontent = $phpcsfile->findprevious(T_WHITESPACE, $stackptr - 1, null, true);
             if ($tokens[$lastcontent]['code'] === T_CLOSE_CURLY_BRACKET) {
                 $brace = $tokens[$lastcontent];
                 if (isset($brace['scope_condition']) === true) {
                     $condition = $tokens[$brace['scope_condition']];
                     if ($condition['code'] === T_DO) {
                         return;
                     }
                 }
             }
         }
         // This is a control structure without an opening brace,
         // so it is an inline statement.
         if ($this->error === true) {
             $phpcsfile->adderror('Inline control structures are not allowed', $stackptr);
         } else {
             $phpcsfile->addwarning('Inline control structures are discouraged', $stackptr);
         }
         return;
     }
 }