findFirstOnLine() public method

Returns false if no token can be found.
public findFirstOnLine ( integer | array $types, integer $start, boolean $exclude = false, string $value = null ) : integer | boolean
$types integer | array The type(s) of tokens to search for.
$start integer The position to start searching from in the token stack. The first token matching on this line before this token will be returned.
$exclude boolean If true, find the token that is NOT of the types specified in $types.
$value string The value that the token must be equal to. If value is omitted, tokens with any value will be returned.
return integer | boolean | bool
 /**
  * Processes this test, when one of its tokens is encountered.
  *
  * @param PHP_CodeSniffer_File $phpcsFile All the tokens found in the document.
  * @param int                  $stackPtr  The position of the current token in the
  *                                        stack passed in $tokens.
  *
  * @return void
  */
 public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr)
 {
     $tokens = $phpcsFile->getTokens();
     // If this is an inline condition (ie. there is no scope opener), then
     // return, as this is not a new scope.
     if (isset($tokens[$stackPtr]['scope_closer']) === false) {
         return;
     }
     // We need to actually find the first piece of content on this line,
     // as if this is a method with tokens before it (public, static etc)
     // or an if with an else before it, then we need to start the scope
     // checking from there, rather than the current token.
     $lineStart = $phpcsFile->findFirstOnLine(T_WHITESPACE, $stackPtr, true);
     $startColumn = $tokens[$lineStart]['column'];
     $scopeStart = $tokens[$stackPtr]['scope_opener'];
     $scopeEnd = $tokens[$stackPtr]['scope_closer'];
     // Check that the closing brace is on it's own line.
     $lastContent = $phpcsFile->findPrevious(array(T_WHITESPACE, T_INLINE_HTML, T_OPEN_TAG), $scopeEnd - 1, $scopeStart, true);
     if ($tokens[$lastContent]['line'] === $tokens[$scopeEnd]['line']) {
         $error = 'Closing brace must be on a line by itself';
         $fix = $phpcsFile->addFixableError($error, $scopeEnd, 'ContentBefore');
         if ($fix === true) {
             $phpcsFile->fixer->addNewlineBefore($scopeEnd);
         }
         return;
     }
 }
Example #2
0
 /**
  * Checks if a line is too long.
  *
  * @param PHP_CodeSniffer_File $phpcsFile The file being scanned.
  * @param array $tokens The token stack.
  * @param int $stackPtr The first token on the next line.
  *
  * @return void
  */
 protected function checkLineLength(PHP_CodeSniffer_File $phpcsFile, $tokens, $stackPtr)
 {
     if (isset(PHP_CodeSniffer_Tokens::$commentTokens[$tokens[$stackPtr - 1]['code']]) === TRUE) {
         $doc_comment_tag = $phpcsFile->findFirstOnLine(T_DOC_COMMENT_TAG, $stackPtr - 1);
         if ($doc_comment_tag !== FALSE) {
             // Allow doc comment tags such as long @param tags to exceed the 80
             // character limit.
             return;
         }
         if ($tokens[$stackPtr - 1]['code'] === T_COMMENT && (preg_match('/^[[:space:]]*\\/\\/ @.+/', $tokens[$stackPtr - 1]['content']) === 1 || strpos(trim($tokens[$stackPtr - 1]['content'], "/ \n"), ' ') === FALSE)) {
             // Allow @link and @see documentation to exceed the 80 character
             // limit.
             return;
         }
         // Code examples between @code and @endcode are allowed to exceed 80
         // characters.
         if (isset($tokens[$stackPtr]) === TRUE && $tokens[$stackPtr]['code'] === T_DOC_COMMENT_WHITESPACE) {
             $tag = $phpcsFile->findPrevious(array(T_DOC_COMMENT_TAG, T_DOC_COMMENT_OPEN_TAG), $stackPtr - 1);
             if ($tokens[$tag]['content'] === '@code') {
                 return;
             }
         }
         // Drupal 8 annotations can have long translatable descriptions and we
         // allow them to exceed 80 characters.
         if ($tokens[$stackPtr - 2]['code'] === T_DOC_COMMENT_STRING && strpos($tokens[$stackPtr - 2]['content'], '@Translation(') !== FALSE) {
             return;
         }
         // Allow comments preceded by the line with @code and ended by the line
         // with @endcode to be excluded.
         if ($this->isInCodeExample($phpcsFile, $stackPtr) === TRUE) {
             return;
         }
         parent::checkLineLength($phpcsFile, $tokens, $stackPtr);
     }
 }
 /**
  * @param \PHP_CodeSniffer_File $phpCsFile
  * @param int $stackPointer
  *
  * @return bool
  */
 protected function isPublicMethod(\PHP_CodeSniffer_File $phpCsFile, $stackPointer)
 {
     $publicPosition = $phpCsFile->findFirstOnLine(T_PUBLIC, $stackPointer);
     if ($publicPosition) {
         return true;
     }
     return false;
 }
 /**
  * @param \PHP_CodeSniffer_File $phpCsFile
  * @param int $stackPointer
  *
  * @return bool
  */
 protected function isMethodPrivate(\PHP_CodeSniffer_File $phpCsFile, $stackPointer)
 {
     $privateTokenPointer = $phpCsFile->findFirstOnLine(T_PRIVATE, $stackPointer);
     if ($privateTokenPointer) {
         return true;
     }
     return false;
 }
 /**
  * Processes this test, when one of its tokens is encountered.
  *
  * @param PHP_CodeSniffer_File $phpcsFile All the tokens found in the document.
  * @param int                  $stackPtr  The position of the current token in the
  *                                        stack passed in $tokens.
  *
  * @return void
  */
 public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr)
 {
     $tokens = $phpcsFile->getTokens();
     // If this is an inline condition (ie. there is no scope opener), then
     // return, as this is not a new scope.
     if (isset($tokens[$stackPtr]['scope_closer']) === false) {
         return;
     }
     // We need to actually find the first piece of content on this line,
     // as if this is a method with tokens before it (public, static etc)
     // or an if with an else before it, then we need to start the scope
     // checking from there, rather than the current token.
     $lineStart = $phpcsFile->findFirstOnLine(T_WHITESPACE, $stackPtr, true);
     $startColumn = $tokens[$lineStart]['column'];
     $scopeStart = $tokens[$stackPtr]['scope_opener'];
     $scopeEnd = $tokens[$stackPtr]['scope_closer'];
     // Check that the closing brace is on it's own line.
     $lastContent = $phpcsFile->findPrevious(array(T_INLINE_HTML, T_WHITESPACE, T_OPEN_TAG), $scopeEnd - 1, $scopeStart, true);
     if ($tokens[$lastContent]['line'] === $tokens[$scopeEnd]['line']) {
         $error = 'Closing brace must be on a line by itself';
         $fix = $phpcsFile->addFixableError($error, $scopeEnd, 'ContentBefore');
         if ($fix === true) {
             $phpcsFile->fixer->addNewlineBefore($scopeEnd);
         }
         return;
     }
     // Check now that the closing brace is lined up correctly.
     $lineStart = $phpcsFile->findFirstOnLine(T_WHITESPACE, $scopeEnd, true);
     $braceIndent = $tokens[$lineStart]['column'];
     if ($tokens[$stackPtr]['code'] !== T_DEFAULT && $tokens[$stackPtr]['code'] !== T_CASE && $braceIndent !== $startColumn) {
         $error = 'Closing brace indented incorrectly; expected %s spaces, found %s';
         $data = array($startColumn - 1, $braceIndent - 1);
         $fix = $phpcsFile->addFixableError($error, $scopeEnd, 'Indent', $data);
         if ($fix === true) {
             $diff = $startColumn - $braceIndent;
             if ($diff > 0) {
                 $phpcsFile->fixer->addContentBefore($scopeEnd, str_repeat(' ', $diff));
             } else {
                 $phpcsFile->fixer->substrToken($scopeEnd - 1, 0, $diff);
             }
         }
     }
     //end if
 }
 /**
  * Processes this test, when one of its tokens is encountered.
  *
  * @param PHP_CodeSniffer_File $phpcsFile The file being scanned.
  * @param integer              $stackPtr  The position of the current token in the
  *                                        stack passed in $tokens.
  *
  * @return void
  */
 public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr)
 {
     $tokens = $phpcsFile->getTokens();
     if ($stackPtr === 0) {
         $trim_len = -1;
     } else {
         $trim_len = strlen(trim($tokens[$stackPtr - 1]['content']));
     }
     if ($tokens[$stackPtr]['code'] === T_CLOSE_TAG) {
         if ($tokens[$stackPtr - 1]['line'] !== $tokens[$stackPtr]['line']) {
             return;
         }
         $lastContent = $phpcsFile->findFirstOnLine(T_OPEN_TAG, $stackPtr);
         if ($lastContent === false && $trim_len === 0) {
             $error = 'Closing PHP tag must not be indented when on its own line';
             $phpcsFile->addError($error, $stackPtr, 'CloseTag', array());
             return;
         }
     } elseif ($tokens[$stackPtr]['code'] === T_OPEN_TAG) {
         if ($trim_len === 0 && $tokens[$stackPtr - 1]['line'] === $tokens[$stackPtr]['line']) {
             $error = 'Opening PHP tag must not be indented when on its own line';
             $phpcsFile->addError($error, $stackPtr, 'OpenTag', array());
             return;
         }
         $closeTagPtr = $phpcsFile->findNext(T_CLOSE_TAG, $stackPtr);
         if ($closeTagPtr !== false && $tokens[$closeTagPtr]['line'] === $tokens[$stackPtr]['line']) {
             return;
         }
         if (isset($tokens[$stackPtr + 1]) && $tokens[$stackPtr + 1]['line'] === $tokens[$stackPtr]['line']) {
             $error = 'Can not have code on same line as PHP open tag';
             $phpcsFile->addError($error, $stackPtr, 'SameLine', array());
             return;
         }
     }
     if ($tokens[$stackPtr]['level'] !== 0) {
         if ($tokens[$stackPtr]['code'] === T_CLOSE_TAG) {
             $openTagPtr = $phpcsFile->findPrevious(T_OPEN_TAG, $stackPtr);
             if ($openTagPtr === false || $tokens[$openTagPtr]['line'] != $tokens[$stackPtr]['line']) {
                 return;
             }
             if (isset($tokens[$openTagPtr - 1]) && $tokens[$openTagPtr - 1]['line'] != $tokens[$openTagPtr]['line']) {
                 $error = 'Can not use inline PHP within indented block';
                 $phpcsFile->addError($error, $stackPtr, 'Inline', array());
                 return;
             }
         }
     }
 }
 /**
  * Checks if a line is too long.
  *
  * @param PHP_CodeSniffer_File $phpcsFile The file being scanned.
  * @param array                $tokens    The token stack.
  * @param int                  $stackPtr  The first token on the next line.
  *
  * @return void
  */
 protected function checkLineLength(PHP_CodeSniffer_File $phpcsFile, $tokens, $stackPtr)
 {
     if (isset(PHP_CodeSniffer_Tokens::$commentTokens[$tokens[$stackPtr - 1]['code']]) === true) {
         $doc_comment_tag = $phpcsFile->findFirstOnLine(T_DOC_COMMENT_TAG, $stackPtr - 1);
         if ($doc_comment_tag !== false) {
             // Allow doc comment tags such as long @param tags to exceed the 80
             // character limit.
             return;
         }
         if ($tokens[$stackPtr - 1]['code'] === T_COMMENT && preg_match('/^[[:space:]]*\\/\\/ @.+/', $tokens[$stackPtr - 1]['content']) === 1) {
             // Allow @link and @see documentation to exceed the 80 character
             // limit.
             return;
         }
         parent::checkLineLength($phpcsFile, $tokens, $stackPtr);
     }
 }
 public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr)
 {
     $tokens = $phpcsFile->getTokens();
     // Find first non-whitespace token on current line
     $first_token = $phpcsFile->findFirstOnLine(T_WHITESPACE, $stackPtr, true);
     // If this token ( -> ) is the first token on the line, skip "space found before operator" check
     if ($first_token !== $stackPtr) {
         // Find token preceding operator
         $prevType = $tokens[$stackPtr - 1]['code'];
         // If preceding operator is whitespace, throw error
         if (in_array($prevType, PHP_CodeSniffer_Tokens::$emptyTokens) === true) {
             $error = 'Space found before object operator';
             $phpcsFile->addError($error, $stackPtr, 'Before');
         }
     }
     $nextType = $tokens[$stackPtr + 1]['code'];
     if (in_array($nextType, PHP_CodeSniffer_Tokens::$emptyTokens) === true) {
         $error = 'Space found after object operator';
         $phpcsFile->addError($error, $stackPtr, 'After');
     }
 }
 /**
  * Processes the closing section of a class declaration.
  *
  * @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 processClose(PHP_CodeSniffer_File $phpcsFile, $stackPtr)
 {
     $tokens = $phpcsFile->getTokens();
     if (isset($tokens[$stackPtr]['scope_closer']) === false) {
         return;
     }
     $closeBrace = $tokens[$stackPtr]['scope_closer'];
     // Check that the closing brace has one blank line after it.
     for ($nextContent = $closeBrace + 1; $nextContent < $phpcsFile->numTokens; $nextContent++) {
         // Ignore comments on the same lines as the brace.
         if ($tokens[$nextContent]['line'] === $tokens[$closeBrace]['line'] && ($tokens[$nextContent]['code'] === T_WHITESPACE || $tokens[$nextContent]['code'] === T_COMMENT)) {
             continue;
         }
         if ($tokens[$nextContent]['code'] !== T_WHITESPACE) {
             break;
         }
     }
     if ($nextContent === $phpcsFile->numTokens) {
         // Ignore the line check as this is the very end of the file.
         $difference = 1;
     } else {
         $difference = $tokens[$nextContent]['line'] - $tokens[$closeBrace]['line'] - 1;
     }
     $lastContent = $phpcsFile->findPrevious(T_WHITESPACE, $closeBrace - 1, $stackPtr, true);
     if ($difference === -1 || $tokens[$lastContent]['line'] === $tokens[$closeBrace]['line']) {
         $error = 'Closing %s brace must be on a line by itself';
         $data = array($tokens[$stackPtr]['content']);
         $fix = $phpcsFile->addFixableError($error, $closeBrace, 'CloseBraceSameLine', $data);
         if ($fix === true) {
             if ($difference === -1) {
                 $phpcsFile->fixer->addNewlineBefore($nextContent);
             }
             if ($tokens[$lastContent]['line'] === $tokens[$closeBrace]['line']) {
                 $phpcsFile->fixer->addNewlineBefore($closeBrace);
             }
         }
     } else {
         if ($tokens[$closeBrace - 1]['code'] === T_WHITESPACE) {
             $prevContent = $tokens[$closeBrace - 1]['content'];
             if ($prevContent !== $phpcsFile->eolChar) {
                 $blankSpace = substr($prevContent, strpos($prevContent, $phpcsFile->eolChar));
                 $spaces = strlen($blankSpace);
                 if ($spaces !== 0) {
                     if ($tokens[$closeBrace - 1]['line'] !== $tokens[$closeBrace]['line']) {
                         $error = 'Expected 0 spaces before closing brace; newline found';
                         $phpcsFile->addError($error, $closeBrace, 'NewLineBeforeCloseBrace');
                     } else {
                         $error = 'Expected 0 spaces before closing brace; %s found';
                         $data = array($spaces);
                         $fix = $phpcsFile->addFixableError($error, $closeBrace, 'SpaceBeforeCloseBrace', $data);
                         if ($fix === true) {
                             $phpcsFile->fixer->replaceToken($closeBrace - 1, '');
                         }
                     }
                 }
             }
         }
     }
     //end if
     if ($difference !== -1 && $difference !== 1) {
         $error = 'Closing brace of a %s must be followed by a single blank line; found %s';
         $data = array($tokens[$stackPtr]['content'], $difference);
         $fix = $phpcsFile->addFixableError($error, $closeBrace, 'NewlinesAfterCloseBrace', $data);
         if ($fix === true) {
             if ($difference === 0) {
                 $first = $phpcsFile->findFirstOnLine(array(), $nextContent, true);
                 $phpcsFile->fixer->addNewlineBefore($first);
             } else {
                 $phpcsFile->fixer->beginChangeset();
                 for ($i = $closeBrace + 1; $i < $nextContent; $i++) {
                     if ($tokens[$i]['line'] <= $tokens[$closeBrace]['line'] + 1) {
                         continue;
                     } else {
                         if ($tokens[$i]['line'] === $tokens[$nextContent]['line']) {
                             break;
                         }
                     }
                     $phpcsFile->fixer->replaceToken($i, '');
                 }
                 $phpcsFile->fixer->endChangeset();
             }
         }
     }
     //end if
 }
 /**
  * Processes this test, when one of its tokens is encountered.
  *
  * @param PHP_CodeSniffer_File $phpcsFile All the tokens found in the document.
  * @param int                  $stackPtr  The position of the current token
  *                                        in the stack passed in $tokens.
  *
  * @return void
  */
 public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr)
 {
     if ($this->_tabWidth === null) {
         $cliValues = $phpcsFile->phpcs->cli->getCommandLineValues();
         if (isset($cliValues['tabWidth']) === false || $cliValues['tabWidth'] === 0) {
             // We have no idea how wide tabs are, so assume 4 spaces for fixing.
             // It shouldn't really matter because indent checks elsewhere in the
             // standard should fix things up.
             $this->_tabWidth = 4;
         } else {
             $this->_tabWidth = $cliValues['tabWidth'];
         }
     }
     $currentIndent = 0;
     $lastOpenTag = $stackPtr;
     $lastCloseTag = null;
     $openScopes = array();
     $adjustments = array();
     $tokens = $phpcsFile->getTokens();
     $currentIndent = $tokens[$stackPtr]['column'] - 1;
     if (empty($this->_ignoreIndentationTokens) === true) {
         $this->_ignoreIndentationTokens = array(T_INLINE_HTML => true);
         foreach ($this->ignoreIndentationTokens as $token) {
             if (is_int($token) === false) {
                 if (defined($token) === false) {
                     continue;
                 }
                 $token = constant($token);
             }
             $this->_ignoreIndentationTokens[$token] = true;
         }
     }
     //end if
     $this->exact = (bool) $this->exact;
     $this->tabIndent = (bool) $this->tabIndent;
     for ($i = $stackPtr + 1; $i < $phpcsFile->numTokens; $i++) {
         if ($i === false) {
             // Something has gone very wrong; maybe a parse error.
             break;
         }
         $checkToken = null;
         $checkIndent = null;
         $exact = (bool) $this->exact;
         if ($exact === true && isset($tokens[$i]['nested_parenthesis']) === true) {
             // Don't check indents exactly between parenthesis as they
             // tend to have custom rules, such as with multi-line function calls
             // and control structure conditions.
             $exact = false;
         }
         // Detect line changes and figure out where the indent is.
         if ($tokens[$i]['column'] === 1) {
             $trimmed = ltrim($tokens[$i]['content']);
             if ($trimmed === '') {
                 if (isset($tokens[$i + 1]) === true && $tokens[$i]['line'] === $tokens[$i + 1]['line']) {
                     $checkToken = $i + 1;
                     $tokenIndent = $tokens[$i + 1]['column'] - 1;
                 }
             } else {
                 $checkToken = $i;
                 $tokenIndent = strlen($tokens[$i]['content']) - strlen($trimmed);
             }
         }
         // Closing parenthesis should just be indented to at least
         // the same level as where they were opened (but can be more).
         if ($checkToken !== null && $tokens[$checkToken]['code'] === T_CLOSE_PARENTHESIS && isset($tokens[$checkToken]['parenthesis_opener']) === true) {
             if ($this->_debug === true) {
                 $line = $tokens[$i]['line'];
                 echo "Closing parenthesis found on line {$line}" . PHP_EOL;
             }
             $first = $phpcsFile->findFirstOnLine(T_WHITESPACE, $tokens[$checkToken]['parenthesis_opener'], true);
             $checkIndent = $tokens[$first]['column'] - 1;
             if (isset($adjustments[$first]) === true) {
                 $checkIndent += $adjustments[$first];
             }
             $exact = false;
             if ($this->_debug === true) {
                 $line = $tokens[$first]['line'];
                 $type = $tokens[$first]['type'];
                 echo "\t* first token on line {$line} is {$type} *" . PHP_EOL;
             }
             $prev = $phpcsFile->findStartOfStatement($first);
             if ($prev !== $first) {
                 // This is not the start of the statement.
                 if ($this->_debug === true) {
                     $line = $tokens[$prev]['line'];
                     $type = $tokens[$prev]['type'];
                     echo "\t* previous is {$type} on line {$line} *" . PHP_EOL;
                 }
                 $first = $phpcsFile->findFirstOnLine(T_WHITESPACE, $prev, true);
                 $prev = $phpcsFile->findStartOfStatement($first);
                 $first = $phpcsFile->findFirstOnLine(T_WHITESPACE, $prev, true);
                 if ($this->_debug === true) {
                     $line = $tokens[$first]['line'];
                     $type = $tokens[$first]['type'];
                     echo "\t* amended first token is {$type} on line {$line} *" . PHP_EOL;
                 }
             }
             // Don't force current indent to divisible because there could be custom
             // rules in place between parenthesis, such as with arrays.
             $currentIndent = $tokens[$first]['column'] - 1;
             if (isset($adjustments[$first]) === true) {
                 $currentIndent += $adjustments[$first];
             }
             if ($this->_debug === true) {
                 echo "\t=> checking indent of {$checkIndent}; main indent set to {$currentIndent}" . PHP_EOL;
             }
         }
         //end if
         // Closing parenthesis should just be indented to at least
         // the same level as where they were opened (but can be more).
         if ($checkToken !== null && $tokens[$checkToken]['code'] === T_CLOSE_SHORT_ARRAY) {
             if ($this->_debug === true) {
                 $line = $tokens[$i]['line'];
                 echo "Closing short array bracket found on line {$line}" . PHP_EOL;
             }
             $first = $phpcsFile->findFirstOnLine(T_WHITESPACE, $tokens[$checkToken]['bracket_opener'], true);
             $checkIndent = $tokens[$first]['column'] - 1;
             if (isset($adjustments[$first]) === true) {
                 $checkIndent += $adjustments[$first];
             }
             $exact = false;
             if ($this->_debug === true) {
                 $line = $tokens[$first]['line'];
                 $type = $tokens[$first]['type'];
                 echo "\t* first token on line {$line} is {$type} *" . PHP_EOL;
             }
             $prev = $phpcsFile->findStartOfStatement($first);
             if ($prev !== $first) {
                 // This is not the start of the statement.
                 if ($this->_debug === true) {
                     $line = $tokens[$prev]['line'];
                     $type = $tokens[$prev]['type'];
                     echo "\t* previous is {$type} on line {$line} *" . PHP_EOL;
                 }
                 $first = $phpcsFile->findFirstOnLine(T_WHITESPACE, $prev, true);
                 $prev = $phpcsFile->findStartOfStatement($first);
                 $first = $phpcsFile->findFirstOnLine(T_WHITESPACE, $prev, true);
                 if ($this->_debug === true) {
                     $line = $tokens[$first]['line'];
                     $type = $tokens[$first]['type'];
                     echo "\t* amended first token is {$type} on line {$line} *" . PHP_EOL;
                 }
             }
             // Don't force current indent to be divisible because there could be custom
             // rules in place for arrays.
             $currentIndent = $tokens[$first]['column'] - 1;
             if (isset($adjustments[$first]) === true) {
                 $currentIndent += $adjustments[$first];
             }
             if ($this->_debug === true) {
                 echo "\t=> checking indent of {$checkIndent}; main indent set to {$currentIndent}" . PHP_EOL;
             }
         }
         //end if
         // Adjust lines within scopes while auto-fixing.
         if ($checkToken !== null && $exact === false && (empty($tokens[$checkToken]['conditions']) === false || isset($tokens[$checkToken]['scope_opener']) === true && $tokens[$checkToken]['scope_opener'] === $checkToken)) {
             if (empty($tokens[$checkToken]['conditions']) === false) {
                 end($tokens[$checkToken]['conditions']);
                 $condition = key($tokens[$checkToken]['conditions']);
             } else {
                 $condition = $tokens[$checkToken]['scope_condition'];
             }
             $first = $phpcsFile->findFirstOnLine(T_WHITESPACE, $condition, true);
             if (isset($adjustments[$first]) === true && ($adjustments[$first] < 0 && $tokenIndent > $currentIndent || $adjustments[$first] > 0 && $tokenIndent < $currentIndent)) {
                 $padding = $tokenIndent + $adjustments[$first];
                 if ($padding > 0) {
                     if ($this->tabIndent === true) {
                         $numTabs = floor($padding / $this->_tabWidth);
                         $numSpaces = $padding - $numTabs * $this->_tabWidth;
                         $padding = str_repeat("\t", $numTabs) . str_repeat(' ', $numSpaces);
                     } else {
                         $padding = str_repeat(' ', $padding);
                     }
                 } else {
                     $padding = '';
                 }
                 if ($checkToken === $i) {
                     $phpcsFile->fixer->replaceToken($checkToken, $padding . $trimmed);
                 } else {
                     // Easier to just replace the entire indent.
                     $phpcsFile->fixer->replaceToken($checkToken - 1, $padding);
                 }
                 if ($this->_debug === true) {
                     $length = strlen($padding);
                     $line = $tokens[$checkToken]['line'];
                     $type = $tokens[$checkToken]['type'];
                     echo "Indent adjusted to {$length} for {$type} on line {$line}" . PHP_EOL;
                 }
                 $adjustments[$checkToken] = $adjustments[$first];
                 if ($this->_debug === true) {
                     $line = $tokens[$checkToken]['line'];
                     $type = $tokens[$checkToken]['type'];
                     echo "\t=> Add adjustment of " . $adjustments[$checkToken] . " for token {$checkToken} ({$type}) on line {$line}" . PHP_EOL;
                 }
             }
             //end if
         }
         //end if
         // Scope closers reset the required indent to the same level as the opening condition.
         if ($checkToken !== null && isset($openScopes[$checkToken]) === true || isset($tokens[$checkToken]['scope_condition']) === true && isset($tokens[$checkToken]['scope_closer']) === true && $tokens[$checkToken]['scope_closer'] === $checkToken && $tokens[$checkToken]['line'] !== $tokens[$tokens[$checkToken]['scope_opener']]['line'] || ($checkToken === null && isset($openScopes[$i]) === true || isset($tokens[$i]['scope_condition']) === true && isset($tokens[$i]['scope_closer']) === true && $tokens[$i]['scope_closer'] === $i && $tokens[$i]['line'] !== $tokens[$tokens[$i]['scope_opener']]['line'])) {
             if ($this->_debug === true) {
                 if ($checkToken === null) {
                     $type = $tokens[$tokens[$i]['scope_condition']]['type'];
                     $line = $tokens[$i]['line'];
                 } else {
                     $type = $tokens[$tokens[$checkToken]['scope_condition']]['type'];
                     $line = $tokens[$checkToken]['line'];
                 }
                 echo "Close scope ({$type}) on line {$line}" . PHP_EOL;
             }
             $scopeCloser = $checkToken;
             if ($scopeCloser === null) {
                 $scopeCloser = $i;
             } else {
                 array_pop($openScopes);
             }
             $first = $phpcsFile->findFirstOnLine(T_WHITESPACE, $tokens[$scopeCloser]['scope_condition'], true);
             $currentIndent = $tokens[$first]['column'] - 1;
             if (isset($adjustments[$first]) === true) {
                 $currentIndent += $adjustments[$first];
             }
             // Make sure it is divisible by our expected indent.
             if ($tokens[$tokens[$scopeCloser]['scope_condition']]['code'] !== T_CLOSURE) {
                 $currentIndent = (int) (ceil($currentIndent / $this->indent) * $this->indent);
             }
             if ($this->_debug === true) {
                 echo "\t=> indent set to {$currentIndent}" . PHP_EOL;
             }
             // We only check the indent of scope closers if they are
             // curly braces because other constructs tend to have different rules.
             if ($tokens[$scopeCloser]['code'] === T_CLOSE_CURLY_BRACKET) {
                 $exact = true;
             } else {
                 $checkToken = null;
             }
         }
         //end if
         // Handle scope for JS object notation.
         if ($phpcsFile->tokenizerType === 'JS' && ($checkToken !== null && $tokens[$checkToken]['code'] === T_CLOSE_OBJECT && $tokens[$checkToken]['line'] !== $tokens[$tokens[$checkToken]['bracket_opener']]['line'] || $checkToken === null && $tokens[$i]['code'] === T_CLOSE_OBJECT && $tokens[$i]['line'] !== $tokens[$tokens[$i]['bracket_opener']]['line'])) {
             if ($this->_debug === true) {
                 $line = $tokens[$i]['line'];
                 echo "Close JS object on line {$line}" . PHP_EOL;
             }
             $scopeCloser = $checkToken;
             if ($scopeCloser === null) {
                 $scopeCloser = $i;
             } else {
                 array_pop($openScopes);
             }
             $parens = 0;
             if (isset($tokens[$scopeCloser]['nested_parenthesis']) === true && empty($tokens[$scopeCloser]['nested_parenthesis']) === false) {
                 end($tokens[$scopeCloser]['nested_parenthesis']);
                 $parens = key($tokens[$scopeCloser]['nested_parenthesis']);
                 if ($this->_debug === true) {
                     $line = $tokens[$parens]['line'];
                     echo "\t* token has nested parenthesis {$parens} on line {$line} *" . PHP_EOL;
                 }
             }
             $condition = 0;
             if (isset($tokens[$scopeCloser]['conditions']) === true && empty($tokens[$scopeCloser]['conditions']) === false) {
                 end($tokens[$scopeCloser]['conditions']);
                 $condition = key($tokens[$scopeCloser]['conditions']);
                 if ($this->_debug === true) {
                     $line = $tokens[$condition]['line'];
                     $type = $tokens[$condition]['type'];
                     echo "\t* token is inside condition {$condition} ({$type}) on line {$line} *" . PHP_EOL;
                 }
             }
             if ($parens > $condition) {
                 if ($this->_debug === true) {
                     echo "\t* using parenthesis *" . PHP_EOL;
                 }
                 $first = $phpcsFile->findFirstOnLine(T_WHITESPACE, $parens, true);
                 $condition = 0;
             } else {
                 if ($condition > 0) {
                     if ($this->_debug === true) {
                         echo "\t* using condition *" . PHP_EOL;
                     }
                     $first = $phpcsFile->findFirstOnLine(T_WHITESPACE, $condition, true);
                     $parens = 0;
                 } else {
                     if ($this->_debug === true) {
                         $line = $tokens[$tokens[$scopeCloser]['bracket_opener']]['line'];
                         echo "\t* token is not in parenthesis or condition; using opener on line {$line} *" . PHP_EOL;
                     }
                     $first = $phpcsFile->findFirstOnLine(T_WHITESPACE, $tokens[$scopeCloser]['bracket_opener'], true);
                 }
             }
             //end if
             $currentIndent = $tokens[$first]['column'] - 1;
             if (isset($adjustments[$first]) === true) {
                 $currentIndent += $adjustments[$first];
             }
             if ($parens > 0 || $condition > 0) {
                 $checkIndent = $tokens[$first]['column'] - 1;
                 if (isset($adjustments[$first]) === true) {
                     $checkIndent += $adjustments[$first];
                 }
                 if ($condition > 0) {
                     $checkIndent += $this->indent;
                     $currentIndent += $this->indent;
                     $exact = true;
                 }
             } else {
                 $checkIndent = $currentIndent;
             }
             // Make sure it is divisible by our expected indent.
             $currentIndent = (int) (ceil($currentIndent / $this->indent) * $this->indent);
             $checkIndent = (int) (ceil($checkIndent / $this->indent) * $this->indent);
             if ($this->_debug === true) {
                 echo "\t=> checking indent of {$checkIndent}; main indent set to {$currentIndent}" . PHP_EOL;
             }
         }
         //end if
         if ($checkToken !== null && isset(PHP_CodeSniffer_Tokens::$scopeOpeners[$tokens[$checkToken]['code']]) === true && in_array($tokens[$checkToken]['code'], $this->nonIndentingScopes) === false && isset($tokens[$checkToken]['scope_opener']) === true) {
             $exact = true;
             $lastOpener = null;
             if (empty($openScopes) === false) {
                 end($openScopes);
                 $lastOpener = current($openScopes);
             }
             // A scope opener that shares a closer with another token (like multiple
             // CASEs using the same BREAK) needs to reduce the indent level so its
             // indent is checked correctly. It will then increase the indent again
             // (as all openers do) after being checked.
             if ($lastOpener !== null && isset($tokens[$lastOpener]['scope_closer']) === true && $tokens[$lastOpener]['level'] === $tokens[$checkToken]['level'] && $tokens[$lastOpener]['scope_closer'] === $tokens[$checkToken]['scope_closer']) {
                 $currentIndent -= $this->indent;
                 if ($this->_debug === true) {
                     $line = $tokens[$i]['line'];
                     echo "Shared closer found on line {$line}" . PHP_EOL;
                     echo "\t=> indent set to {$currentIndent}" . PHP_EOL;
                 }
             }
             if ($tokens[$checkToken]['code'] === T_CLOSURE && $tokenIndent > $currentIndent) {
                 // The opener is indented more than needed, which is fine.
                 // But just check that it is divisible by our expected indent.
                 $checkIndent = (int) (ceil($tokenIndent / $this->indent) * $this->indent);
                 $exact = false;
                 if ($this->_debug === true) {
                     $line = $tokens[$i]['line'];
                     echo "Closure found on line {$line}" . PHP_EOL;
                     echo "\t=> checking indent of {$checkIndent}; main indent remains at {$currentIndent}" . PHP_EOL;
                 }
             }
         }
         //end if
         // JS property indentation has to be exact or else if will break
         // things like function and object indentation.
         if ($checkToken !== null && $tokens[$checkToken]['code'] === T_PROPERTY) {
             $exact = true;
         }
         // PHP tags needs to be indented to exact column positions
         // so they don't cause problems with indent checks for the code
         // within them, but they don't need to line up with the current indent.
         if ($checkToken !== null && ($tokens[$checkToken]['code'] === T_OPEN_TAG || $tokens[$checkToken]['code'] === T_OPEN_TAG_WITH_ECHO || $tokens[$checkToken]['code'] === T_CLOSE_TAG)) {
             $exact = true;
             $checkIndent = $tokens[$checkToken]['column'] - 1;
             $checkIndent = (int) (ceil($checkIndent / $this->indent) * $this->indent);
         }
         // Check the line indent.
         if ($checkIndent === null) {
             $checkIndent = $currentIndent;
         }
         $adjusted = false;
         if ($checkToken !== null && isset($this->_ignoreIndentationTokens[$tokens[$checkToken]['code']]) === false && ($tokenIndent !== $checkIndent && $exact === true || $tokenIndent < $checkIndent && $exact === false)) {
             $type = 'IncorrectExact';
             $error = 'Line indented incorrectly; expected ';
             if ($exact === false) {
                 $error .= 'at least ';
                 $type = 'Incorrect';
             }
             if ($this->tabIndent === true) {
                 $error .= '%s tabs, found %s';
                 $data = array(floor($checkIndent / $this->_tabWidth), floor($tokenIndent / $this->_tabWidth));
             } else {
                 $error .= '%s spaces, found %s';
                 $data = array($checkIndent, $tokenIndent);
             }
             if ($this->_debug === true) {
                 $line = $tokens[$checkToken]['line'];
                 $message = vsprintf($error, $data);
                 echo "[Line {$line}] {$message}" . PHP_EOL;
             }
             $fix = $phpcsFile->addFixableError($error, $checkToken, $type, $data);
             if ($fix === true || $this->_debug === true) {
                 $padding = '';
                 if ($this->tabIndent === true) {
                     $numTabs = floor($checkIndent / $this->_tabWidth);
                     if ($numTabs > 0) {
                         $numSpaces = $checkIndent - $numTabs * $this->_tabWidth;
                         $padding = str_repeat("\t", $numTabs) . str_repeat(' ', $numSpaces);
                     }
                 } else {
                     if ($checkIndent > 0) {
                         $padding = str_repeat(' ', $checkIndent);
                     }
                 }
                 if ($checkToken === $i) {
                     $accepted = $phpcsFile->fixer->replaceToken($checkToken, $padding . $trimmed);
                 } else {
                     // Easier to just replace the entire indent.
                     $accepted = $phpcsFile->fixer->replaceToken($checkToken - 1, $padding);
                 }
                 if ($accepted === true) {
                     $adjustments[$checkToken] = $checkIndent - $tokenIndent;
                     if ($this->_debug === true) {
                         $line = $tokens[$checkToken]['line'];
                         $type = $tokens[$checkToken]['type'];
                         echo "\t=> Add adjustment of " . $adjustments[$checkToken] . " for token {$checkToken} ({$type}) on line {$line}" . PHP_EOL;
                     }
                 }
             }
             //end if
         }
         //end if
         if ($checkToken !== null) {
             $i = $checkToken;
         }
         // Completely skip here/now docs as the indent is a part of the
         // content itself.
         if ($tokens[$i]['code'] === T_START_HEREDOC || $tokens[$i]['code'] === T_START_NOWDOC) {
             $i = $phpcsFile->findNext(array(T_END_HEREDOC, T_END_NOWDOC), $i + 1);
             continue;
         }
         // Completely skip multi-line strings as the indent is a part of the
         // content itself.
         if ($tokens[$i]['code'] === T_CONSTANT_ENCAPSED_STRING || $tokens[$i]['code'] === T_DOUBLE_QUOTED_STRING) {
             $i = $phpcsFile->findNext($tokens[$i]['code'], $i + 1, null, true);
             $i--;
             continue;
         }
         // Completely skip doc comments as they tend to have complex
         // indentation rules.
         if ($tokens[$i]['code'] === T_DOC_COMMENT_OPEN_TAG) {
             $i = $tokens[$i]['comment_closer'];
             continue;
         }
         // Open tags reset the indent level.
         if ($tokens[$i]['code'] === T_OPEN_TAG || $tokens[$i]['code'] === T_OPEN_TAG_WITH_ECHO) {
             if ($this->_debug === true) {
                 $line = $tokens[$i]['line'];
                 echo "Open PHP tag found on line {$line}" . PHP_EOL;
             }
             if ($checkToken === null) {
                 $first = $phpcsFile->findFirstOnLine(T_WHITESPACE, $i, true);
                 $currentIndent = strlen($tokens[$first]['content']) - strlen(ltrim($tokens[$first]['content']));
             } else {
                 $currentIndent = $tokens[$i]['column'] - 1;
             }
             $lastOpenTag = $i;
             if (isset($adjustments[$i]) === true) {
                 $currentIndent += $adjustments[$i];
             }
             // Make sure it is divisible by our expected indent.
             $currentIndent = (int) (ceil($currentIndent / $this->indent) * $this->indent);
             if ($this->_debug === true) {
                 echo "\t=> indent set to {$currentIndent}" . PHP_EOL;
             }
             continue;
         }
         //end if
         // Close tags reset the indent level, unless they are closing a tag
         // opened on the same line.
         if ($tokens[$i]['code'] === T_CLOSE_TAG) {
             if ($this->_debug === true) {
                 $line = $tokens[$i]['line'];
                 echo "Close PHP tag found on line {$line}" . PHP_EOL;
             }
             if ($tokens[$lastOpenTag]['line'] !== $tokens[$i]['line']) {
                 $currentIndent = $tokens[$i]['column'] - 1;
                 $lastCloseTag = $i;
             } else {
                 if ($lastCloseTag === null) {
                     $currentIndent = 0;
                 } else {
                     $currentIndent = $tokens[$lastCloseTag]['column'] - 1;
                 }
             }
             if (isset($adjustments[$i]) === true) {
                 $currentIndent += $adjustments[$i];
             }
             // Make sure it is divisible by our expected indent.
             $currentIndent = (int) (ceil($currentIndent / $this->indent) * $this->indent);
             if ($this->_debug === true) {
                 echo "\t=> indent set to {$currentIndent}" . PHP_EOL;
             }
             continue;
         }
         //end if
         // Closures set the indent based on their own indent level.
         if ($tokens[$i]['code'] === T_CLOSURE) {
             $closer = $tokens[$i]['scope_closer'];
             if ($tokens[$i]['line'] === $tokens[$closer]['line']) {
                 if ($this->_debug === true) {
                     $line = $tokens[$i]['line'];
                     echo "* ignoring single-line closure on line {$line}" . PHP_EOL;
                 }
                 $i = $closer;
                 continue;
             }
             if ($this->_debug === true) {
                 $line = $tokens[$i]['line'];
                 echo "Open closure on line {$line}" . PHP_EOL;
             }
             $first = $phpcsFile->findFirstOnLine(T_WHITESPACE, $i, true);
             $currentIndent = $tokens[$first]['column'] - 1 + $this->indent;
             if (isset($adjustments[$first]) === true) {
                 $currentIndent += $adjustments[$first];
             }
             // Make sure it is divisible by our expected indent.
             $currentIndent = (int) (floor($currentIndent / $this->indent) * $this->indent);
             $i = $tokens[$i]['scope_opener'];
             if ($this->_debug === true) {
                 echo "\t=> indent set to {$currentIndent}" . PHP_EOL;
             }
             continue;
         }
         //end if
         // Scope openers increase the indent level.
         if (isset($tokens[$i]['scope_condition']) === true && isset($tokens[$i]['scope_opener']) === true && $tokens[$i]['scope_opener'] === $i) {
             $closer = $tokens[$i]['scope_closer'];
             if ($tokens[$i]['line'] === $tokens[$closer]['line']) {
                 if ($this->_debug === true) {
                     $line = $tokens[$i]['line'];
                     $type = $tokens[$i]['type'];
                     echo "* ignoring single-line {$type} on line {$line}" . PHP_EOL;
                 }
                 $i = $closer;
                 continue;
             }
             $condition = $tokens[$tokens[$i]['scope_condition']]['code'];
             if (isset(PHP_CodeSniffer_Tokens::$scopeOpeners[$condition]) === true && in_array($condition, $this->nonIndentingScopes) === false) {
                 if ($this->_debug === true) {
                     $line = $tokens[$i]['line'];
                     $type = $tokens[$tokens[$i]['scope_condition']]['type'];
                     echo "Open scope ({$type}) on line {$line}" . PHP_EOL;
                 }
                 $currentIndent += $this->indent;
                 $openScopes[$tokens[$i]['scope_closer']] = $tokens[$i]['scope_condition'];
                 if ($this->_debug === true) {
                     echo "\t=> indent set to {$currentIndent}" . PHP_EOL;
                 }
                 continue;
             }
         }
         //end if
         // JS objects set the indent level.
         if ($phpcsFile->tokenizerType === 'JS' && $tokens[$i]['code'] === T_OBJECT) {
             $closer = $tokens[$i]['bracket_closer'];
             if ($tokens[$i]['line'] === $tokens[$closer]['line']) {
                 if ($this->_debug === true) {
                     $line = $tokens[$i]['line'];
                     echo "* ignoring single-line JS object on line {$line}" . PHP_EOL;
                 }
                 $i = $closer;
                 continue;
             }
             if ($this->_debug === true) {
                 $line = $tokens[$i]['line'];
                 echo "Open JS object on line {$line}" . PHP_EOL;
             }
             $first = $phpcsFile->findFirstOnLine(T_WHITESPACE, $i, true);
             $currentIndent = $tokens[$first]['column'] - 1 + $this->indent;
             if (isset($adjustments[$first]) === true) {
                 $currentIndent += $adjustments[$first];
             }
             // Make sure it is divisible by our expected indent.
             $currentIndent = (int) (ceil($currentIndent / $this->indent) * $this->indent);
             if ($this->_debug === true) {
                 echo "\t=> indent set to {$currentIndent}" . PHP_EOL;
             }
             continue;
         }
         //end if
         // Closing a closure.
         if (isset($tokens[$i]['scope_condition']) === true && $tokens[$i]['scope_closer'] === $i && $tokens[$tokens[$i]['scope_condition']]['code'] === T_CLOSURE) {
             if ($this->_debug === true) {
                 $line = $tokens[$i]['line'];
                 echo "Close closure on line {$line}" . PHP_EOL;
             }
             $prev = false;
             $object = 0;
             if ($phpcsFile->tokenizerType === 'JS') {
                 $conditions = $tokens[$i]['conditions'];
                 krsort($conditions, SORT_NUMERIC);
                 foreach ($conditions as $token => $condition) {
                     if ($condition === T_OBJECT) {
                         $object = $token;
                         break;
                     }
                 }
                 if ($this->_debug === true && $object !== 0) {
                     $line = $tokens[$object]['line'];
                     echo "\t* token is inside JS object {$object} on line {$line} *" . PHP_EOL;
                 }
             }
             $parens = 0;
             if (isset($tokens[$i]['nested_parenthesis']) === true && empty($tokens[$i]['nested_parenthesis']) === false) {
                 end($tokens[$i]['nested_parenthesis']);
                 $parens = key($tokens[$i]['nested_parenthesis']);
                 if ($this->_debug === true) {
                     $line = $tokens[$parens]['line'];
                     echo "\t* token has nested parenthesis {$parens} on line {$line} *" . PHP_EOL;
                 }
             }
             $condition = 0;
             if (isset($tokens[$i]['conditions']) === true && empty($tokens[$i]['conditions']) === false) {
                 end($tokens[$i]['conditions']);
                 $condition = key($tokens[$i]['conditions']);
                 if ($this->_debug === true) {
                     $line = $tokens[$condition]['line'];
                     $type = $tokens[$condition]['type'];
                     echo "\t* token is inside condition {$condition} ({$type}) on line {$line} *" . PHP_EOL;
                 }
             }
             if ($parens > $object && $parens > $condition) {
                 if ($this->_debug === true) {
                     echo "\t* using parenthesis *" . PHP_EOL;
                 }
                 $prev = $phpcsFile->findPrevious(PHP_CodeSniffer_Tokens::$emptyTokens, $parens - 1, null, true);
                 $object = 0;
                 $condition = 0;
             } else {
                 if ($object > 0 && $object >= $condition) {
                     if ($this->_debug === true) {
                         echo "\t* using object *" . PHP_EOL;
                     }
                     $prev = $object;
                     $parens = 0;
                     $condition = 0;
                 } else {
                     if ($condition > 0) {
                         if ($this->_debug === true) {
                             echo "\t* using condition *" . PHP_EOL;
                         }
                         $prev = $condition;
                         $object = 0;
                         $parens = 0;
                     }
                 }
             }
             //end if
             if ($prev === false) {
                 $prev = $phpcsFile->findPrevious(array(T_EQUAL, T_RETURN), $tokens[$i]['scope_condition'] - 1, null, false, null, true);
                 if ($prev === false) {
                     $prev = $i;
                     if ($this->_debug === true) {
                         echo "\t* could not find a previous T_EQUAL or T_RETURN token; will use current token *" . PHP_EOL;
                     }
                 }
             }
             if ($this->_debug === true) {
                 $line = $tokens[$prev]['line'];
                 $type = $tokens[$prev]['type'];
                 echo "\t* previous token is {$type} on line {$line} *" . PHP_EOL;
             }
             $first = $phpcsFile->findFirstOnLine(T_WHITESPACE, $prev, true);
             if ($this->_debug === true) {
                 $line = $tokens[$first]['line'];
                 $type = $tokens[$first]['type'];
                 echo "\t* first token on line {$line} is {$type} *" . PHP_EOL;
             }
             $prev = $phpcsFile->findStartOfStatement($first);
             if ($prev !== $first) {
                 // This is not the start of the statement.
                 if ($this->_debug === true) {
                     $line = $tokens[$prev]['line'];
                     $type = $tokens[$prev]['type'];
                     echo "\t* amended previous is {$type} on line {$line} *" . PHP_EOL;
                 }
                 $first = $phpcsFile->findFirstOnLine(T_WHITESPACE, $prev, true);
                 if ($this->_debug === true) {
                     $line = $tokens[$first]['line'];
                     $type = $tokens[$first]['type'];
                     echo "\t* amended first token is {$type} on line {$line} *" . PHP_EOL;
                 }
             }
             $currentIndent = $tokens[$first]['column'] - 1;
             if ($object > 0 || $condition > 0) {
                 $currentIndent += $this->indent;
             }
             // Make sure it is divisible by our expected indent.
             $currentIndent = (int) (ceil($currentIndent / $this->indent) * $this->indent);
             if ($this->_debug === true) {
                 echo "\t=> indent set to {$currentIndent}" . PHP_EOL;
             }
         }
         //end if
     }
     //end for
     // Don't process the rest of the file.
     return $phpcsFile->numTokens;
 }
 /**
  * Processes this test, when one of its tokens is encountered.
  *
  * @param PHP_CodeSniffer_File $file The file being scanned.
  * @param int $stackPtr The position of the current token in the
  * stack passed in $tokens.
  *
  */
 public function process(PHP_CodeSniffer_File $file, $stackPtr)
 {
     $tokens = $file->getTokens();
     if (isset($tokens[$stackPtr]['scope_opener']) === false) {
         return;
     }
     // The end of the function occurs at the end of the argument list. Its
     // like this because some people like to break long function
     // declarations over multiple lines.
     $openingBrace = $tokens[$stackPtr]['scope_opener'];
     $parenthesisOpener = $tokens[$stackPtr]['parenthesis_opener'];
     $parenthesisCloser = $tokens[$stackPtr]['parenthesis_closer'];
     $functionStartLine = $tokens[$parenthesisOpener]['line'];
     $functionLine = $tokens[$parenthesisCloser]['line'];
     $braceLine = $tokens[$openingBrace]['line'];
     $lineDifference = $braceLine - $functionLine;
     $isMultiline = $functionStartLine != $functionLine;
     if ($lineDifference === 0 && !$isMultiline) {
         $error = 'Opening brace should be on a new line';
         $fix = $file->addFixableError($error, $openingBrace, 'BraceOnSameLine');
         if ($fix === true) {
             $file->fixer->beginChangeset();
             $indent = $file->findFirstOnLine([], $openingBrace);
             if ($tokens[$indent]['code'] === T_WHITESPACE) {
                 $file->fixer->addContentBefore($openingBrace, $tokens[$indent]['content']);
             }
             $file->fixer->addNewlineBefore($openingBrace);
             $file->fixer->endChangeset();
         }
         $file->recordMetric($stackPtr, 'Function opening brace placement', 'same line');
     } else {
         if ($lineDifference > 1) {
             $error = 'Opening brace should be on the line after the' . ' declaration; found %s blank line(s)';
             $data = [$lineDifference - 1];
             $fix = $file->addFixableError($error, $openingBrace, 'BraceSpacing', $data);
             if ($fix === true) {
                 $afterCloser = $parenthesisCloser + 1;
                 for ($i = $afterCloser; $i < $openingBrace; $i++) {
                     if ($tokens[$i]['line'] === $braceLine) {
                         $file->fixer->addNewLineBefore($i);
                         break;
                     }
                     $file->fixer->replaceToken($i, '');
                 }
             }
         }
     }
     $next = $file->findNext(T_WHITESPACE, $openingBrace + 1, null, true);
     if ($tokens[$next]['line'] === $tokens[$openingBrace]['line']) {
         if ($next === $tokens[$stackPtr]['scope_closer']) {
             // Ignore empty functions.
             return;
         }
         $error = 'Opening brace must be the last content on the line';
         $fix = $file->addFixableError($error, $openingBrace, 'ContentAfterBrace');
         if ($fix === true) {
             $file->fixer->addNewline($openingBrace);
         }
     }
     // Only continue checking if the opening brace looks good.
     if ($lineDifference !== 1) {
         return;
     }
     // We need to actually find the first piece of content on this line,
     // as if this is a method with tokens before it (public, static etc)
     // or an if with an else before it, then we need to start the scope
     // checking from there, rather than the current token.
     $lineStart = $stackPtr;
     while (($lineStart = $file->findPrevious(T_WHITESPACE, $lineStart - 1, null, false)) !== false) {
         $position = strpos($tokens[$lineStart]['content'], $file->eolChar);
         if ($position !== false) {
             break;
         }
     }
     // We found a new line, now go forward and find the first
     // non-whitespace token.
     $lineStart = $file->findNext(T_WHITESPACE, $lineStart, null, true);
     // The opening brace is on the correct line, now it needs to be
     // checked to be correctly indented.
     $startColumn = $tokens[$lineStart]['column'];
     $braceIndent = $tokens[$openingBrace]['column'];
     if ($braceIndent !== $startColumn) {
         $expected = $startColumn - 1;
         $found = $braceIndent - 1;
         $error = 'Opening brace indented incorrectly;' . ' expected %s spaces, found %s';
         $data = [$expected, $found];
         $fix = $file->addFixableError($error, $openingBrace, 'BraceIndent', $data);
         if ($fix === true) {
             $indent = str_repeat(' ', $expected);
             if ($found === 0) {
                 $file->fixer->addContentBefore($openingBrace, $indent);
             } else {
                 $file->fixer->replaceToken($openingBrace - 1, $indent);
             }
         }
     }
     $file->recordMetric($stackPtr, 'Function opening brace placement', 'new line');
 }
 /**
  * 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(PHP_CodeSniffer_File $phpcsFile, $stackPtr)
 {
     $tokens = $phpcsFile->getTokens();
     $ignore = PHP_CodeSniffer_Tokens::$methodPrefixes;
     $ignore[] = T_VAR;
     $ignore[] = T_WHITESPACE;
     $start = $stackPtr;
     $prev = $phpcsFile->findPrevious($ignore, $stackPtr - 1, null, true);
     if (isset(PHP_CodeSniffer_Tokens::$commentTokens[$tokens[$prev]['code']]) === true) {
         // Assume the comment belongs to the member var if it is on a line by itself.
         $prevContent = $phpcsFile->findPrevious(PHP_CodeSniffer_Tokens::$emptyTokens, $prev - 1, null, true);
         if ($tokens[$prevContent]['line'] !== $tokens[$prev]['line']) {
             // Check the spacing, but then skip it.
             $foundLines = $tokens[$stackPtr]['line'] - $tokens[$prev]['line'] - 1;
             if ($foundLines > 0) {
                 $error = 'Expected 0 blank lines after member var comment; %s found';
                 $data = array($foundLines);
                 $fix = $phpcsFile->addFixableError($error, $prev, 'AfterComment', $data);
                 if ($fix === true) {
                     $phpcsFile->fixer->beginChangeset();
                     for ($i = $prev + 1; $i <= $stackPtr; $i++) {
                         if ($tokens[$i]['line'] === $tokens[$stackPtr]['line']) {
                             break;
                         }
                         $phpcsFile->fixer->replaceToken($i, '');
                     }
                     $phpcsFile->fixer->addNewline($prev);
                     $phpcsFile->fixer->endChangeset();
                 }
             }
             //end if
             $start = $prev;
         }
         //end if
     }
     //end if
     // There needs to be 0 blank line before the var, if there are not comments, otherwise 1 blank line
     $expectedLines = 0;
     if ($start === $stackPtr) {
         // No comment found.
         $first = $phpcsFile->findFirstOnLine(PHP_CodeSniffer_Tokens::$emptyTokens, $start, true);
         if ($first === false) {
             $first = $start;
         }
     } else {
         if ($tokens[$start]['code'] === T_DOC_COMMENT_CLOSE_TAG) {
             $first = $tokens[$start]['comment_opener'];
             $openingBracket = $phpcsFile->findPrevious(T_OPEN_CURLY_BRACKET, $first - 1, null);
             $isFirst = true;
             for ($i = $openingBracket + 1; $i <= $first - 1; $i++) {
                 if ($tokens[$i]['code'] !== T_WHITESPACE) {
                     $isFirst = false;
                     break;
                 }
             }
             if (!$isFirst) {
                 $expectedLines = 1;
             } else {
                 $first--;
             }
         } else {
             $first = $phpcsFile->findPrevious(PHP_CodeSniffer_Tokens::$emptyTokens, $start - 1, null, true);
             $first = $phpcsFile->findNext(PHP_CodeSniffer_Tokens::$commentTokens, $first + 1);
         }
     }
     $prev = $phpcsFile->findPrevious(PHP_CodeSniffer_Tokens::$emptyTokens, $first - 1, null, true);
     $foundLines = $tokens[$first]['line'] - $tokens[$prev]['line'] - 1;
     if ($foundLines === $expectedLines) {
         return;
     }
     if ($expectedLines === 0) {
         $error = 'Expected 0 blank lines before member var without comment or first member var; %s found';
     } else {
         $error = 'Expected 1 blank line before member var with comment; %s found';
     }
     $data = array($foundLines);
     $fix = $phpcsFile->addFixableError($error, $stackPtr, 'Incorrect', $data);
     if ($fix === true) {
         $phpcsFile->fixer->beginChangeset();
         if ($expectedLines === 1) {
             for ($i = $prev + 1; $i < $first; $i++) {
                 if ($tokens[$i]['line'] === $tokens[$prev]['line']) {
                     continue;
                 }
                 if ($tokens[$i]['line'] === $tokens[$first]['line']) {
                     $phpcsFile->fixer->addNewline($i - 1);
                     break;
                 }
                 $phpcsFile->fixer->replaceToken($i, '');
             }
         } else {
             for ($i = $prev + 1; $i < $first; $i++) {
                 if ($tokens[$i]['line'] === $tokens[$prev]['line']) {
                     continue;
                 }
                 $phpcsFile->fixer->replaceToken($i, '');
             }
         }
         $phpcsFile->fixer->endChangeset();
     }
     //end if
 }
Example #13
0
 /**
  * Validates embedded PHP that exists on multiple lines.
  *
  * @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
  */
 private function _validateMultilineEmbeddedPhp(PHP_CodeSniffer_File $phpcsFile, $stackPtr)
 {
     $tokens = $phpcsFile->getTokens();
     $prevTag = $phpcsFile->findPrevious(T_OPEN_TAG, $stackPtr - 1);
     if ($prevTag === false) {
         // This is the first open tag.
         return;
     }
     $firstContent = $phpcsFile->findNext(T_WHITESPACE, $stackPtr + 1, null, true);
     $closingTag = $phpcsFile->findNext(T_CLOSE_TAG, $stackPtr);
     if ($closingTag !== false) {
         $nextContent = $phpcsFile->findNext(T_WHITESPACE, $closingTag + 1, $phpcsFile->numTokens, true);
         if ($nextContent === false) {
             // Final closing tag. It will be handled elsewhere.
             return;
         }
         // We have an opening and a closing tag, that lie within other content.
         if ($firstContent === $closingTag) {
             $error = 'Empty embedded PHP tag found';
             $fix = $phpcsFile->addFixableError($error, $stackPtr, 'Empty');
             if ($fix === true) {
                 $phpcsFile->fixer->beginChangeset();
                 for ($i = $stackPtr; $i <= $closingTag; $i++) {
                     $phpcsFile->fixer->replaceToken($i, '');
                 }
                 $phpcsFile->fixer->endChangeset();
             }
             return;
         }
     }
     //end if
     if ($tokens[$firstContent]['line'] === $tokens[$stackPtr]['line']) {
         $error = 'Opening PHP tag must be on a line by itself';
         $fix = $phpcsFile->addFixableError($error, $stackPtr, 'ContentAfterOpen');
         if ($fix === true) {
             $first = $phpcsFile->findFirstOnLine(T_WHITESPACE, $stackPtr, true);
             $padding = strlen($tokens[$first]['content']) - strlen(ltrim($tokens[$first]['content']));
             $phpcsFile->fixer->beginChangeset();
             $phpcsFile->fixer->addNewline($stackPtr);
             $phpcsFile->fixer->addContent($stackPtr, str_repeat(' ', $padding));
             $phpcsFile->fixer->endChangeset();
         }
     } else {
         // Check the indent of the first line, except if it is a scope closer.
         if (isset($tokens[$firstContent]['scope_closer']) === false || $tokens[$firstContent]['scope_closer'] !== $firstContent) {
             // Check for a blank line at the top.
             if ($tokens[$firstContent]['line'] > $tokens[$stackPtr]['line'] + 1) {
                 // Find a token on the blank line to throw the error on.
                 $i = $stackPtr;
                 do {
                     $i++;
                 } while ($tokens[$i]['line'] !== $tokens[$stackPtr]['line'] + 1);
                 $error = 'Blank line found at start of embedded PHP content';
                 $fix = $phpcsFile->addFixableError($error, $i, 'SpacingBefore');
                 if ($fix === true) {
                     $phpcsFile->fixer->beginChangeset();
                     for ($i = $stackPtr + 1; $i < $firstContent; $i++) {
                         if ($tokens[$i]['line'] === $tokens[$firstContent]['line'] || $tokens[$i]['line'] === $tokens[$stackPtr]['line']) {
                             continue;
                         }
                         $phpcsFile->fixer->replaceToken($i, '');
                     }
                     $phpcsFile->fixer->endChangeset();
                 }
             }
             //end if
             $first = $phpcsFile->findFirstOnLine(T_WHITESPACE, $stackPtr);
             if ($first === false) {
                 $first = $phpcsFile->findFirstOnLine(T_INLINE_HTML, $stackPtr);
                 $indent = strlen($tokens[$first]['content']) - strlen(ltrim($tokens[$first]['content']));
             } else {
                 $indent = $tokens[$first + 1]['column'] - 1;
             }
             $contentColumn = $tokens[$firstContent]['column'] - 1;
             if ($contentColumn !== $indent) {
                 $error = 'First line of embedded PHP code must be indented %s spaces; %s found';
                 $data = array($indent, $contentColumn);
                 $fix = $phpcsFile->addFixableError($error, $firstContent, 'Indent', $data);
                 if ($fix === true) {
                     $padding = str_repeat(' ', $indent);
                     if ($contentColumn === 0) {
                         $phpcsFile->fixer->addContentBefore($firstContent, $padding);
                     } else {
                         $phpcsFile->fixer->replaceToken($firstContent - 1, $padding);
                     }
                 }
             }
         }
         //end if
     }
     //end if
     $lastContent = $phpcsFile->findPrevious(T_WHITESPACE, $stackPtr - 1, null, true);
     if ($tokens[$lastContent]['line'] === $tokens[$stackPtr]['line'] && trim($tokens[$lastContent]['content']) !== '') {
         $error = 'Opening PHP tag must be on a line by itself';
         $fix = $phpcsFile->addFixableError($error, $stackPtr, 'ContentBeforeOpen');
         if ($fix === true) {
             $first = $phpcsFile->findFirstOnLine(T_WHITESPACE, $stackPtr);
             if ($first === false) {
                 $first = $phpcsFile->findFirstOnLine(T_INLINE_HTML, $stackPtr);
                 $padding = strlen($tokens[$first]['content']) - strlen(ltrim($tokens[$first]['content']));
             } else {
                 $padding = $tokens[$first + 1]['column'] - 1;
             }
             $phpcsFile->fixer->addContentBefore($stackPtr, $phpcsFile->eolChar . str_repeat(' ', $padding));
         }
     } else {
         // Find the first token on the first non-empty line we find.
         for ($first = $stackPtr - 1; $first > 0; $first--) {
             if ($tokens[$first]['line'] === $tokens[$stackPtr]['line']) {
                 continue;
             } else {
                 if (trim($tokens[$first]['content']) !== '') {
                     $first = $phpcsFile->findFirstOnLine(array(), $first, true);
                     break;
                 }
             }
         }
         $expected = 0;
         if ($tokens[$first]['code'] === T_INLINE_HTML && trim($tokens[$first]['content']) !== '') {
             $expected = strlen($tokens[$first]['content']) - strlen(ltrim($tokens[$first]['content']));
         } else {
             if ($tokens[$first]['code'] === T_WHITESPACE) {
                 $expected = $tokens[$first + 1]['column'] - 1;
             }
         }
         $expected += 4;
         $found = $tokens[$stackPtr]['column'] - 1;
         if ($found > $expected) {
             $error = 'Opening PHP tag indent incorrect; expected no more than %s spaces but found %s';
             $data = array($expected, $found);
             $fix = $phpcsFile->addFixableError($error, $stackPtr, 'OpenTagIndent', $data);
             if ($fix === true) {
                 $phpcsFile->fixer->replaceToken($stackPtr - 1, str_repeat(' ', $expected));
             }
         }
     }
     //end if
     if ($closingTag === false) {
         return;
     }
     $lastContent = $phpcsFile->findPrevious(T_WHITESPACE, $closingTag - 1, $stackPtr + 1, true);
     $nextContent = $phpcsFile->findNext(T_WHITESPACE, $closingTag + 1, null, true);
     if ($tokens[$lastContent]['line'] === $tokens[$closingTag]['line']) {
         $error = 'Closing PHP tag must be on a line by itself';
         $fix = $phpcsFile->addFixableError($error, $closingTag, 'ContentBeforeEnd');
         if ($fix === true) {
             $first = $phpcsFile->findFirstOnLine(T_WHITESPACE, $closingTag, true);
             $phpcsFile->fixer->beginChangeset();
             $phpcsFile->fixer->addContentBefore($closingTag, str_repeat(' ', $tokens[$first]['column'] - 1));
             $phpcsFile->fixer->addNewlineBefore($closingTag);
             $phpcsFile->fixer->endChangeset();
         }
     } else {
         if ($tokens[$nextContent]['line'] === $tokens[$closingTag]['line']) {
             $error = 'Closing PHP tag must be on a line by itself';
             $fix = $phpcsFile->addFixableError($error, $closingTag, 'ContentAfterEnd');
             if ($fix === true) {
                 $first = $phpcsFile->findFirstOnLine(T_WHITESPACE, $closingTag, true);
                 $phpcsFile->fixer->beginChangeset();
                 $phpcsFile->fixer->addNewline($closingTag);
                 $phpcsFile->fixer->addContent($closingTag, str_repeat(' ', $tokens[$first]['column'] - 1));
                 $phpcsFile->fixer->endChangeset();
             }
         }
     }
     //end if
     $next = $phpcsFile->findNext(T_OPEN_TAG, $closingTag + 1);
     if ($next === false) {
         return;
     }
     // Check for a blank line at the bottom.
     if ((isset($tokens[$lastContent]['scope_closer']) === false || $tokens[$lastContent]['scope_closer'] !== $lastContent) && $tokens[$lastContent]['line'] < $tokens[$closingTag]['line'] - 1) {
         // Find a token on the blank line to throw the error on.
         $i = $closingTag;
         do {
             $i--;
         } while ($tokens[$i]['line'] !== $tokens[$closingTag]['line'] - 1);
         $error = 'Blank line found at end of embedded PHP content';
         $fix = $phpcsFile->addFixableError($error, $i, 'SpacingAfter');
         if ($fix === true) {
             $phpcsFile->fixer->beginChangeset();
             for ($i = $lastContent + 1; $i < $closingTag; $i++) {
                 if ($tokens[$i]['line'] === $tokens[$lastContent]['line'] || $tokens[$i]['line'] === $tokens[$closingTag]['line']) {
                     continue;
                 }
                 $phpcsFile->fixer->replaceToken($i, '');
             }
             $phpcsFile->fixer->endChangeset();
         }
     }
     //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(PHP_CodeSniffer_File $phpcsFile, $stackPtr)
 {
     $tokens = $phpcsFile->getTokens();
     if (isset($tokens[$stackPtr]['scope_opener']) === false) {
         return;
     }
     $openingBrace = $tokens[$stackPtr]['scope_opener'];
     // The end of the function occurs at the end of the argument list. Its
     // like this because some people like to break long function declarations
     // over multiple lines.
     $functionLine = $tokens[$tokens[$stackPtr]['parenthesis_closer']]['line'];
     $braceLine = $tokens[$openingBrace]['line'];
     $lineDifference = $braceLine - $functionLine;
     if ($lineDifference === 0) {
         $error = 'Opening brace should be on a new line';
         $fix = $phpcsFile->addFixableError($error, $openingBrace, 'BraceOnSameLine');
         if ($fix === true && $phpcsFile->fixer->enabled === true) {
             $phpcsFile->fixer->beginChangeset();
             $indent = $phpcsFile->findFirstOnLine(T_WHITESPACE, $openingBrace);
             if ($indent !== false) {
                 $phpcsFile->fixer->addContentBefore($openingBrace, $tokens[$indent]['content']);
             }
             $phpcsFile->fixer->addNewlineBefore($openingBrace);
             $phpcsFile->fixer->endChangeset();
         }
         return;
     }
     if ($lineDifference > 1) {
         $error = 'Opening brace should be on the line after the declaration; found %s blank line(s)';
         $data = array($lineDifference - 1);
         $fix = $phpcsFile->addFixableError($error, $openingBrace, 'BraceSpacing', $data);
         if ($fix === true && $phpcsFile->fixer->enabled === true) {
             for ($i = $tokens[$stackPtr]['parenthesis_closer'] + 1; $i < $openingBrace; $i++) {
                 if ($tokens[$i]['line'] === $braceLine) {
                     $phpcsFile->fixer->addNewLineBefore($i);
                     break;
                 }
                 $phpcsFile->fixer->replaceToken($i, '');
             }
         }
         return;
     }
     // We need to actually find the first piece of content on this line,
     // as if this is a method with tokens before it (public, static etc)
     // or an if with an else before it, then we need to start the scope
     // checking from there, rather than the current token.
     $lineStart = $stackPtr;
     while (($lineStart = $phpcsFile->findPrevious(array(T_WHITESPACE), $lineStart - 1, null, false)) !== false) {
         if (strpos($tokens[$lineStart]['content'], $phpcsFile->eolChar) !== false) {
             break;
         }
     }
     // We found a new line, now go forward and find the first non-whitespace
     // token.
     $lineStart = $phpcsFile->findNext(array(T_WHITESPACE), $lineStart, null, true);
     // The opening brace is on the correct line, now it needs to be
     // checked to be correctly indented.
     $startColumn = $tokens[$lineStart]['column'];
     $braceIndent = $tokens[$openingBrace]['column'];
     if ($braceIndent !== $startColumn) {
         $expected = $startColumn - 1;
         $found = $braceIndent - 1;
         $error = 'Opening brace indented incorrectly; expected %s spaces, found %s';
         $data = array($expected, $found);
         $fix = $phpcsFile->addFixableError($error, $openingBrace, 'BraceIndent', $data);
         if ($fix === true && $phpcsFile->fixer->enabled === true) {
             $indent = str_repeat(' ', $expected);
             if ($found === 0) {
                 $phpcsFile->fixer->addContentBefore($openingBrace, $indent);
             } else {
                 $phpcsFile->fixer->replaceToken($openingBrace - 1, $indent);
             }
         }
     }
     //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(PHP_CodeSniffer_File $phpcsFile, $stackPtr)
 {
     $tokens = $phpcsFile->getTokens();
     if (isset($tokens[$stackPtr]['scope_opener']) === false) {
         return;
     }
     if ($tokens[$stackPtr]['code'] === T_FUNCTION && (bool) $this->checkFunctions === false || $tokens[$stackPtr]['code'] === T_CLOSURE && (bool) $this->checkClosures === false) {
         return;
     }
     $openingBrace = $tokens[$stackPtr]['scope_opener'];
     $closeBracket = $tokens[$stackPtr]['parenthesis_closer'];
     if ($tokens[$stackPtr]['code'] === T_CLOSURE) {
         $use = $phpcsFile->findNext(T_USE, $closeBracket + 1, $tokens[$stackPtr]['scope_opener']);
         if ($use !== false) {
             $openBracket = $phpcsFile->findNext(T_OPEN_PARENTHESIS, $use + 1);
             $closeBracket = $tokens[$openBracket]['parenthesis_closer'];
         }
     }
     $functionLine = $tokens[$closeBracket]['line'];
     $braceLine = $tokens[$openingBrace]['line'];
     $lineDifference = $braceLine - $functionLine;
     if ($lineDifference === 0) {
         $error = 'Opening brace should be on a new line';
         $fix = $phpcsFile->addFixableError($error, $openingBrace, 'BraceOnSameLine');
         if ($fix === true) {
             $phpcsFile->fixer->beginChangeset();
             $indent = $phpcsFile->findFirstOnLine(array(), $openingBrace);
             if ($tokens[$indent]['code'] === T_WHITESPACE) {
                 $phpcsFile->fixer->addContentBefore($openingBrace, $tokens[$indent]['content']);
             }
             $phpcsFile->fixer->addNewlineBefore($openingBrace);
             $phpcsFile->fixer->endChangeset();
         }
         $phpcsFile->recordMetric($stackPtr, 'Function opening brace placement', 'same line');
     } else {
         if ($lineDifference > 1) {
             $error = 'Opening brace should be on the line after the declaration; found %s blank line(s)';
             $data = array($lineDifference - 1);
             $fix = $phpcsFile->addFixableError($error, $openingBrace, 'BraceSpacing', $data);
             if ($fix === true) {
                 for ($i = $tokens[$stackPtr]['parenthesis_closer'] + 1; $i < $openingBrace; $i++) {
                     if ($tokens[$i]['line'] === $braceLine) {
                         $phpcsFile->fixer->addNewLineBefore($i);
                         break;
                     }
                     $phpcsFile->fixer->replaceToken($i, '');
                 }
             }
         }
     }
     //end if
     $next = $phpcsFile->findNext(T_WHITESPACE, $openingBrace + 1, null, true);
     if ($tokens[$next]['line'] === $tokens[$openingBrace]['line']) {
         if ($next === $tokens[$stackPtr]['scope_closer']) {
             // Ignore empty functions.
             return;
         }
         $error = 'Opening brace must be the last content on the line';
         $fix = $phpcsFile->addFixableError($error, $openingBrace, 'ContentAfterBrace');
         if ($fix === true) {
             $phpcsFile->fixer->addNewline($openingBrace);
         }
     }
     // Only continue checking if the opening brace looks good.
     if ($lineDifference !== 1) {
         return;
     }
     // We need to actually find the first piece of content on this line,
     // as if this is a method with tokens before it (public, static etc)
     // or an if with an else before it, then we need to start the scope
     // checking from there, rather than the current token.
     $lineStart = $phpcsFile->findFirstOnLine(T_WHITESPACE, $stackPtr, true);
     // The opening brace is on the correct line, now it needs to be
     // checked to be correctly indented.
     $startColumn = $tokens[$lineStart]['column'];
     $braceIndent = $tokens[$openingBrace]['column'];
     if ($braceIndent !== $startColumn) {
         $expected = $startColumn - 1;
         $found = $braceIndent - 1;
         $error = 'Opening brace indented incorrectly; expected %s spaces, found %s';
         $data = array($expected, $found);
         $fix = $phpcsFile->addFixableError($error, $openingBrace, 'BraceIndent', $data);
         if ($fix === true) {
             $indent = str_repeat(' ', $expected);
             if ($found === 0) {
                 $phpcsFile->fixer->addContentBefore($openingBrace, $indent);
             } else {
                 $phpcsFile->fixer->replaceToken($openingBrace - 1, $indent);
             }
         }
     }
     //end if
     $phpcsFile->recordMetric($stackPtr, 'Function opening brace placement', 'new line');
 }
 /**
  * Processes this test, when one of its tokens is encountered.
  *
  * @param PHP_CodeSniffer_File $phpcsFile All the tokens found in the document.
  * @param int                  $stackPtr  The position of the current token
  *                                        in the stack passed in $tokens.
  *
  * @return void
  */
 public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr)
 {
     $currentIndent = 0;
     $lastOpenTag = $stackPtr;
     $lastOpener = null;
     $adjustments = array();
     $tokens = $phpcsFile->getTokens();
     $currentIndent = $tokens[$stackPtr]['column'] - 1;
     if (empty($this->_ignoreIndentationTokens) === true) {
         $this->_ignoreIndentationTokens = array(T_OPEN_TAG => true, T_OPEN_TAG_WITH_ECHO => true, T_CLOSE_TAG => true, T_INLINE_HTML => true);
         foreach ($this->ignoreIndentationTokens as $token) {
             if (is_int($token) === false) {
                 if (defined($token) === false) {
                     continue;
                 }
                 $token = constant($token);
             }
             $this->_ignoreIndentationTokens[$token] = true;
         }
     }
     //end if
     for ($i = $stackPtr + 1; $i < $phpcsFile->numTokens; $i++) {
         $checkToken = null;
         $exact = (bool) $this->exact;
         // Detect line changes and figure out where the indent is.
         if ($tokens[$i]['column'] === 1) {
             $trimmed = ltrim($tokens[$i]['content']);
             if ($trimmed === '') {
                 if (isset($tokens[$i + 1]) !== false && $tokens[$i]['line'] === $tokens[$i + 1]['line']) {
                     $checkToken = $i + 1;
                     $tokenIndent = $tokens[$i + 1]['column'] - 1;
                 }
             } else {
                 $checkToken = $i;
                 $tokenIndent = strlen($tokens[$i]['content']) - strlen($trimmed);
             }
         }
         if ($checkToken !== null && isset($tokens[$checkToken]['conditions']) === true && empty($tokens[$checkToken]['conditions']) === false && $exact === false) {
             end($tokens[$checkToken]['conditions']);
             $condition = key($tokens[$checkToken]['conditions']);
             $first = $phpcsFile->findFirstOnLine(T_WHITESPACE, $condition, true);
             if (isset($adjustments[$first]) === true && ($adjustments[$first] < 0 && $tokenIndent > $currentIndent || $adjustments[$first] > 0 && $tokenIndent < $currentIndent)) {
                 $padding = $tokenIndent + $adjustments[$first];
                 if ($padding > 0) {
                     $padding = str_repeat(' ', $padding);
                 } else {
                     $padding = '';
                 }
                 if ($checkToken === $i) {
                     $phpcsFile->fixer->replaceToken($checkToken, $padding . $trimmed);
                 } else {
                     // Easier to just replace the entire indent.
                     $phpcsFile->fixer->replaceToken($checkToken - 1, $padding);
                 }
                 $adjustments[$checkToken] = $adjustments[$first];
             }
         }
         //end if
         // Scope closers reset the required indent to the same level as the opening condition.
         if ($checkToken !== null && isset($tokens[$checkToken]['scope_condition']) === true && isset($tokens[$checkToken]['scope_closer']) === true && $tokens[$checkToken]['scope_closer'] === $checkToken || $checkToken === null && isset($tokens[$i]['scope_condition']) === true && isset($tokens[$i]['scope_closer']) === true && $tokens[$i]['scope_closer'] === $i) {
             $scopeCloser = $checkToken;
             if ($scopeCloser === null) {
                 $scopeCloser = $i;
             }
             $first = $phpcsFile->findFirstOnLine(T_WHITESPACE, $tokens[$scopeCloser]['scope_condition'], true);
             $currentIndent = $tokens[$first]['column'] - 1;
             if (isset($adjustments[$tokens[$scopeCloser]['scope_condition']]) === true) {
                 $currentIndent += $adjustments[$tokens[$scopeCloser]['scope_condition']];
             }
             // Make sure it is divisable by our expected indent.
             $currentIndent = (int) (ceil($currentIndent / $this->indent) * $this->indent);
             // We only check the indent of scope closers if they are
             // curly braces because other constructs tend to have different rules.
             if ($tokens[$scopeCloser]['code'] === T_CLOSE_CURLY_BRACKET) {
                 $exact = true;
             } else {
                 $checkToken = null;
             }
         }
         //end if
         if ($checkToken !== null && isset(PHP_CodeSniffer_Tokens::$scopeOpeners[$tokens[$checkToken]['code']]) === true && in_array($tokens[$checkToken]['code'], $this->nonIndentingScopes) === false && isset($tokens[$checkToken]['scope_opener']) === true) {
             $exact = true;
             // A scope opener that shares a closer with another token (like multiple
             // CASEs using the same BREAK) needs to reduce the indent level so its
             // indent is checked correctly. It will then increase the indent again
             // (as all openers do) after being checked.
             if ($lastOpener !== null && $tokens[$lastOpener]['level'] === $tokens[$checkToken]['level'] && $tokens[$lastOpener]['scope_closer'] === $tokens[$checkToken]['scope_closer']) {
                 $currentIndent -= $this->indent;
             }
             if ($tokens[$checkToken]['code'] === T_CLOSURE && $tokenIndent > $currentIndent) {
                 // The opener is indented more than needed, whcih is fine.
                 // But just check that it is divisble by our expected indent.
                 $currentIndent = (int) (ceil($tokenIndent / $this->indent) * $this->indent);
                 $exact = false;
             }
         }
         //end if
         // Check the line indent.
         $adjusted = false;
         if ($checkToken !== null && isset($this->_ignoreIndentationTokens[$tokens[$checkToken]['code']]) === false && ($tokenIndent !== $currentIndent && $exact === true || $tokenIndent < $currentIndent && $exact === false)) {
             $type = 'IncorrectExact';
             $error = 'Line indented incorrectly; expected ';
             if ($exact === false) {
                 $error .= 'at least ';
                 $type = 'Incorrect';
             }
             $error .= '%s spaces, found %s';
             $data = array($currentIndent, $tokenIndent);
             $fix = $phpcsFile->addFixableError($error, $checkToken, $type, $data);
             if ($fix === true) {
                 $padding = str_repeat(' ', $currentIndent);
                 if ($checkToken === $i) {
                     $accepted = $phpcsFile->fixer->replaceToken($checkToken, $padding . $trimmed);
                 } else {
                     // Easier to just replace the entire indent.
                     $accepted = $phpcsFile->fixer->replaceToken($checkToken - 1, $padding);
                 }
                 if ($accepted === true) {
                     $adjustments[$checkToken] = $currentIndent - $tokenIndent;
                 }
             }
         }
         //end if
         if ($checkToken !== null) {
             $i = $checkToken;
         }
         // Completely skip here/now docs as the indent is a part of the
         // content itself.
         if ($tokens[$i]['code'] === T_START_HEREDOC || $tokens[$i]['code'] === T_START_NOWDOC) {
             $i = $phpcsFile->findNext(array(T_END_HEREDOC, T_END_NOWDOC), $i + 1);
             continue;
         }
         // Completely skip multi-line strings as the indent is a part of the
         // content itself.
         if ($tokens[$i]['code'] === T_CONSTANT_ENCAPSED_STRING || $tokens[$i]['code'] === T_DOUBLE_QUOTED_STRING) {
             $i = $phpcsFile->findNext($tokens[$i]['code'], $i + 1, null, true);
             continue;
         }
         // Completely skip doc comments as they tend to have complex
         // indentation rules.
         if ($tokens[$i]['code'] === T_DOC_COMMENT_OPEN_TAG) {
             $i = $tokens[$i]['comment_closer'];
             continue;
         }
         // Open tags reset the indent level.
         if ($tokens[$i]['code'] == T_OPEN_TAG || $tokens[$i]['code'] == T_OPEN_TAG_WITH_ECHO) {
             if ($checkToken === null) {
                 $first = $phpcsFile->findFirstOnLine(T_WHITESPACE, $i, true);
                 $currentIndent = strlen($tokens[$first]['content']) - strlen(ltrim($tokens[$first]['content']));
             } else {
                 $currentIndent = $tokens[$i]['column'] - 1;
             }
             $lastOpenTag = $i;
             if (isset($adjustments[$i]) === true) {
                 $currentIndent += $adjustments[$i];
             }
             // Make sure it is divisable by our expected indent.
             $currentIndent = (int) (ceil($currentIndent / $this->indent) * $this->indent);
             continue;
         }
         // Close tags reset the indent level, unless they are closing a tag
         // opened on the same line.
         if ($tokens[$i]['code'] == T_CLOSE_TAG) {
             if ($tokens[$lastOpenTag]['line'] !== $tokens[$i]['line']) {
                 $currentIndent = $tokens[$i]['column'] - 1;
                 $this->_lastClose = $i;
             } else {
                 $currentIndent = $tokens[$this->_lastClose]['column'] - 1;
             }
             if (isset($adjustments[$i]) === true) {
                 $currentIndent += $adjustments[$i];
             }
             // Make sure it is divisable by our expected indent.
             $currentIndent = (int) (ceil($currentIndent / $this->indent) * $this->indent);
             continue;
         }
         // Closures set the indent based on their own indent level.
         if ($tokens[$i]['code'] === T_CLOSURE) {
             $first = $phpcsFile->findFirstOnLine(T_WHITESPACE, $i, true);
             $currentIndent = $tokens[$first]['column'] - 1 + $this->indent;
             // Make sure it is divisable by our expected indent.
             $currentIndent = (int) (ceil($currentIndent / $this->indent) * $this->indent);
             $i = $tokens[$i]['scope_opener'];
             continue;
         }
         // Scope openers increase the indent level.
         if (isset(PHP_CodeSniffer_Tokens::$scopeOpeners[$tokens[$i]['code']]) === true && in_array($tokens[$i]['code'], $this->nonIndentingScopes) === false && isset($tokens[$i]['scope_opener']) === true) {
             $currentIndent += $this->indent;
             $lastOpener = $i;
             $i = $tokens[$i]['scope_opener'];
             continue;
         }
         // Closing a closure.
         if (isset($tokens[$i]['scope_condition']) === true && $tokens[$i]['scope_closer'] === $i && $tokens[$tokens[$i]['scope_condition']]['code'] === T_CLOSURE) {
             if (isset($tokens[$i]['nested_parenthesis']) === true) {
                 reset($tokens[$i]['nested_parenthesis']);
                 $parens = key($tokens[$i]['nested_parenthesis']);
                 $prev = $phpcsFile->findPrevious(PHP_CodeSniffer_Tokens::$emptyTokens, $parens - 1, null, true);
             } else {
                 $prev = $phpcsFile->findPrevious(T_EQUAL, $tokens[$i]['scope_condition'] - 1);
             }
             $first = $phpcsFile->findFirstOnLine(T_WHITESPACE, $prev, true);
             $currentIndent = $tokens[$first]['column'] - 1;
             // Make sure it is divisable by our expected indent.
             $currentIndent = (int) (ceil($currentIndent / $this->indent) * $this->indent);
         }
     }
     //end for
     // Don't process the rest of the file.
     return $phpcsFile->numTokens - 1;
 }
 /**
  * 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();
     // Before even checking the docblocks above the current var/const,
     // check if we have a single line comment after it on the same line,
     // and if that one is OK.
     $postComment = $phpcsFile->findNext(array(T_DOC_COMMENT_OPEN_TAG), $stackPtr);
     if ($postComment !== false && $tokens[$postComment]['line'] === $tokens[$stackPtr]['line']) {
         if ($tokens[$postComment]['content'] === '/**') {
             // That's an error already.
             $phpcsFile->addError('no doc blocks are allowed after declaration', $stackPtr, 'NoDocBlockAllowed');
         } else {
             $postCommentEnd = $tokens[$postComment]['comment_closer'];
             if ($tokens[$postComment]['line'] !== $tokens[$postCommentEnd]['line']) {
                 $phpcsFile->addError('no multiline comments after declarations allowed', $stackPtr, 'MustBeOneLine');
             }
         }
     }
     // Don't do constants for now.
     if ($tokens[$stackPtr]['code'] === T_CONST) {
         return;
     }
     $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'];
         // Check if this comment is completely in one line, above the current line,
         // and has a variable preceding it in the same line. If yes, it doesn't count.
         if ($tokens[$commentStart]['line'] === $tokens[$commentEnd]['line'] && $tokens[$stackPtr]['line'] > $tokens[$commentEnd]['line'] && $phpcsFile->findFirstOnLine($this->_tokenTypes, $commentEnd) !== false) {
             return;
         }
         $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) {
             // It seems that when we are in here, then we have a line comment at $commentEnd.
             // Now, check if the same comment has a variable definition on the same line.
             // If yes, it doesn't count.
             $firstOnLine = $phpcsFile->findFirstOnLine($this->_tokenTypes, $commentEnd);
             if ($firstOnLine === false) {
                 $commentStart = $phpcsFile->findPrevious(T_COMMENT, $commentEnd, null, true);
                 $phpcsFile->addError('property doc comment must begin with /**', $commentStart + 1, 'NotADocBlock');
             }
         }
     }
     //end if
 }
Example #18
0
 /**
  * Processes a multi-line array definition.
  *
  * @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.
  * @param int                  $arrayStart The token that starts the array definition.
  * @param int                  $arrayEnd   The token that ends the array definition.
  *
  * @return void
  */
 public function processMultiLineArray(PHP_CodeSniffer_File $phpcsFile, $stackPtr, $arrayStart, $arrayEnd)
 {
     $tokens = $phpcsFile->getTokens();
     $keywordStart = $tokens[$stackPtr]['column'];
     // Check the closing bracket is on a new line.
     $lastContent = $phpcsFile->findPrevious(T_WHITESPACE, $arrayEnd - 1, $arrayStart, true);
     if ($tokens[$lastContent]['line'] === $tokens[$arrayEnd]['line']) {
         $error = 'Closing parenthesis of array declaration must be on a new line';
         $fix = $phpcsFile->addFixableError($error, $arrayEnd, 'CloseBraceNewLine');
         if ($fix === true) {
             $phpcsFile->fixer->addNewlineBefore($arrayEnd);
         }
     } else {
         if ($tokens[$arrayEnd]['column'] !== $keywordStart) {
             // Check the closing bracket is lined up under the a in array.
             $expected = $keywordStart - 1;
             $found = $tokens[$arrayEnd]['column'] - 1;
             $error = 'Closing parenthesis not aligned correctly; expected %s space(s) but found %s';
             $data = array($expected, $found);
             $fix = $phpcsFile->addFixableError($error, $arrayEnd, 'CloseBraceNotAligned', $data);
             if ($fix === true) {
                 if ($found === 0) {
                     $phpcsFile->fixer->addContent($arrayEnd - 1, str_repeat(' ', $expected));
                 } else {
                     $phpcsFile->fixer->replaceToken($arrayEnd - 1, str_repeat(' ', $expected));
                 }
             }
         }
     }
     //end if
     $nextToken = $stackPtr;
     $keyUsed = false;
     $singleUsed = false;
     $indices = array();
     $maxLength = 0;
     if ($tokens[$stackPtr]['code'] === T_ARRAY) {
         $lastToken = $tokens[$stackPtr]['parenthesis_opener'];
     } else {
         $lastToken = $stackPtr;
     }
     // Find all the double arrows that reside in this scope.
     for ($nextToken = $stackPtr + 1; $nextToken < $arrayEnd; $nextToken++) {
         // Skip bracketed statements, like function calls.
         if ($tokens[$nextToken]['code'] === T_OPEN_PARENTHESIS && (isset($tokens[$nextToken]['parenthesis_owner']) === false || $tokens[$nextToken]['parenthesis_owner'] !== $stackPtr)) {
             $nextToken = $tokens[$nextToken]['parenthesis_closer'];
             continue;
         }
         if ($tokens[$nextToken]['code'] === T_ARRAY) {
             // Let subsequent calls of this test handle nested arrays.
             $indices[] = array('value' => $nextToken);
             $nextToken = $tokens[$tokens[$nextToken]['parenthesis_opener']]['parenthesis_closer'];
             $nextToken = $phpcsFile->findNext(T_WHITESPACE, $nextToken + 1, null, true);
             continue;
         }
         if ($tokens[$nextToken]['code'] === T_OPEN_SHORT_ARRAY) {
             // Let subsequent calls of this test handle nested arrays.
             $indices[] = array('value' => $nextToken);
             $nextToken = $tokens[$nextToken]['bracket_closer'];
             $nextToken = $phpcsFile->findNext(T_WHITESPACE, $nextToken + 1, null, true);
             continue;
         }
         if ($tokens[$nextToken]['code'] !== T_DOUBLE_ARROW && $tokens[$nextToken]['code'] !== T_COMMA) {
             continue;
         }
         $currentEntry = array();
         if ($tokens[$nextToken]['code'] === T_COMMA) {
             $stackPtrCount = 0;
             if (isset($tokens[$stackPtr]['nested_parenthesis']) === true) {
                 $stackPtrCount = count($tokens[$stackPtr]['nested_parenthesis']);
             }
             $commaCount = 0;
             if (isset($tokens[$nextToken]['nested_parenthesis']) === true) {
                 $commaCount = count($tokens[$nextToken]['nested_parenthesis']);
                 if ($tokens[$stackPtr]['code'] === T_ARRAY) {
                     // Remove parenthesis that are used to define the array.
                     $commaCount--;
                 }
             }
             if ($commaCount > $stackPtrCount) {
                 // This comma is inside more parenthesis than the ARRAY keyword,
                 // then there it is actually a comma used to separate arguments
                 // in a function call.
                 continue;
             }
             if ($keyUsed === true && $tokens[$lastToken]['code'] === T_COMMA) {
                 $error = 'No key specified for array entry; first entry specifies key';
                 $phpcsFile->addError($error, $nextToken, 'NoKeySpecified');
                 return;
             }
             if ($keyUsed === false) {
                 if ($tokens[$nextToken - 1]['code'] === T_WHITESPACE) {
                     $content = $tokens[$nextToken - 2]['content'];
                     if ($tokens[$nextToken - 1]['content'] === $phpcsFile->eolChar) {
                         $spaceLength = 'newline';
                     } else {
                         $spaceLength = $tokens[$nextToken - 1]['length'];
                     }
                     $error = 'Expected 0 spaces between "%s" and comma; %s found';
                     $data = array($content, $spaceLength);
                     $fix = $phpcsFile->addFixableError($error, $nextToken, 'SpaceBeforeComma', $data);
                     if ($fix === true) {
                         $phpcsFile->fixer->replaceToken($nextToken - 1, '');
                     }
                 }
                 $valueContent = $phpcsFile->findNext(T_WHITESPACE, $lastToken + 1, $nextToken, true);
                 $indices[] = array('value' => $valueContent);
                 $singleUsed = true;
             }
             //end if
             $lastToken = $nextToken;
             continue;
         }
         //end if
         if ($tokens[$nextToken]['code'] === T_DOUBLE_ARROW) {
             if ($singleUsed === true) {
                 $error = 'Key specified for array entry; first entry has no key';
                 $phpcsFile->addError($error, $nextToken, 'KeySpecified');
                 return;
             }
             $currentEntry['arrow'] = $nextToken;
             $keyUsed = true;
             // Find the start of index that uses this double arrow.
             $indexEnd = $phpcsFile->findPrevious(T_WHITESPACE, $nextToken - 1, $arrayStart, true);
             $indexStart = $phpcsFile->findPrevious(T_WHITESPACE, $indexEnd, $arrayStart);
             if ($indexStart === false) {
                 $index = $indexEnd;
             } else {
                 $index = $indexStart + 1;
             }
             $currentEntry['index'] = $index;
             $currentEntry['index_content'] = $phpcsFile->getTokensAsString($index, $indexEnd - $index + 1);
             $indexLength = strlen($currentEntry['index_content']);
             if ($maxLength < $indexLength) {
                 $maxLength = $indexLength;
             }
             // Find the value of this index.
             $nextContent = $phpcsFile->findNext(array(T_WHITESPACE), $nextToken + 1, $arrayEnd, true);
             $currentEntry['value'] = $nextContent;
             $indices[] = $currentEntry;
             $lastToken = $nextToken;
         }
         //end if
     }
     //end for
     // Check for mutli-line arrays that should be single-line.
     $singleValue = false;
     if (empty($indices) === true) {
         $singleValue = true;
     } else {
         if (count($indices) === 1 && $tokens[$lastToken]['code'] === T_COMMA) {
             // There may be another array value without a comma.
             $exclude = PHP_CodeSniffer_Tokens::$emptyTokens;
             $exclude[] = T_COMMA;
             $nextContent = $phpcsFile->findNext($exclude, $indices[0]['value'] + 1, $arrayEnd, true);
             if ($nextContent === false) {
                 $singleValue = true;
             }
         }
     }
     if ($singleValue === true) {
         // Array cannot be empty, so this is a multi-line array with
         // a single value. It should be defined on single line.
         $error = 'Multi-line array contains a single value; use single-line array instead';
         $fix = $phpcsFile->addFixableError($error, $stackPtr, 'MultiLineNotAllowed');
         if ($fix === true) {
             $phpcsFile->fixer->beginChangeset();
             for ($i = $arrayStart + 1; $i < $arrayEnd; $i++) {
                 if ($tokens[$i]['code'] !== T_WHITESPACE) {
                     break;
                 }
                 $phpcsFile->fixer->replaceToken($i, '');
             }
             for ($i = $arrayEnd - 1; $i > $arrayStart; $i--) {
                 if ($tokens[$i]['code'] !== T_WHITESPACE) {
                     break;
                 }
                 $phpcsFile->fixer->replaceToken($i, '');
             }
             $phpcsFile->fixer->endChangeset();
         }
         return;
     }
     //end if
     /*
         This section checks for arrays that don't specify keys.
     
         Arrays such as:
            array(
             'aaa',
             'bbb',
             'd',
            );
     */
     if ($keyUsed === false && empty($indices) === false) {
         $count = count($indices);
         $lastIndex = $indices[$count - 1]['value'];
         $trailingContent = $phpcsFile->findPrevious(T_WHITESPACE, $arrayEnd - 1, $lastIndex, true);
         if ($tokens[$trailingContent]['code'] !== T_COMMA) {
             $phpcsFile->recordMetric($stackPtr, 'Array end comma', 'no');
             $error = 'Comma required after last value in array declaration';
             $fix = $phpcsFile->addFixableError($error, $trailingContent, 'NoCommaAfterLast');
             if ($fix === true) {
                 $phpcsFile->fixer->addContent($trailingContent, ',');
             }
         } else {
             $phpcsFile->recordMetric($stackPtr, 'Array end comma', 'yes');
         }
         $lastValueLine = false;
         foreach ($indices as $value) {
             if (empty($value['value']) === true) {
                 // Array was malformed and we couldn't figure out
                 // the array value correctly, so we have to ignore it.
                 // Other parts of this sniff will correct the error.
                 continue;
             }
             if ($lastValueLine !== false && $tokens[$value['value']]['line'] === $lastValueLine) {
                 $error = 'Each value in a multi-line array must be on a new line';
                 $fix = $phpcsFile->addFixableError($error, $value['value'], 'ValueNoNewline');
                 if ($fix === true) {
                     if ($tokens[$value['value'] - 1]['code'] === T_WHITESPACE) {
                         $phpcsFile->fixer->replaceToken($value['value'] - 1, '');
                     }
                     $phpcsFile->fixer->addNewlineBefore($value['value']);
                 }
             } else {
                 if ($tokens[$value['value'] - 1]['code'] === T_WHITESPACE) {
                     $expected = $keywordStart;
                     $first = $phpcsFile->findFirstOnLine(T_WHITESPACE, $value['value'], true);
                     $found = $tokens[$first]['column'] - 1;
                     if ($found !== $expected) {
                         $error = 'Array value not aligned correctly; expected %s spaces but found %s';
                         $data = array($expected, $found);
                         $fix = $phpcsFile->addFixableError($error, $value['value'], 'ValueNotAligned', $data);
                         if ($fix === true) {
                             if ($found === 0) {
                                 $phpcsFile->fixer->addContent($value['value'] - 1, str_repeat(' ', $expected));
                             } else {
                                 $phpcsFile->fixer->replaceToken($value['value'] - 1, str_repeat(' ', $expected));
                             }
                         }
                     }
                 }
             }
             //end if
             $lastValueLine = $tokens[$value['value']]['line'];
         }
         //end foreach
     }
     //end if
     /*
         Below the actual indentation of the array is checked.
         Errors will be thrown when a key is not aligned, when
         a double arrow is not aligned, and when a value is not
         aligned correctly.
         If an error is found in one of the above areas, then errors
         are not reported for the rest of the line to avoid reporting
         spaces and columns incorrectly. Often fixing the first
         problem will fix the other 2 anyway.
     
         For example:
     
         $a = array(
               'index'  => '2',
              );
     
         or
     
         $a = [
               'index'  => '2',
              ];
     
         In this array, the double arrow is indented too far, but this
         will also cause an error in the value's alignment. If the arrow were
         to be moved back one space however, then both errors would be fixed.
     */
     $numValues = count($indices);
     $indicesStart = $keywordStart + 1;
     $arrowStart = $indicesStart + $maxLength + 1;
     $valueStart = $arrowStart + 3;
     $indexLine = $tokens[$stackPtr]['line'];
     $lastIndexLine = null;
     foreach ($indices as $index) {
         if (isset($index['index']) === false) {
             // Array value only.
             if ($tokens[$index['value']]['line'] === $tokens[$stackPtr]['line'] && $numValues > 1) {
                 $error = 'The first value in a multi-value array must be on a new line';
                 $fix = $phpcsFile->addFixableError($error, $stackPtr, 'FirstValueNoNewline');
                 if ($fix === true) {
                     $phpcsFile->fixer->addNewlineBefore($index['value']);
                 }
             }
             continue;
         }
         $lastIndexLine = $indexLine;
         $indexLine = $tokens[$index['index']]['line'];
         if ($indexLine === $tokens[$stackPtr]['line']) {
             $error = 'The first index in a multi-value array must be on a new line';
             $fix = $phpcsFile->addFixableError($error, $index['index'], 'FirstIndexNoNewline');
             if ($fix === true) {
                 $phpcsFile->fixer->addNewlineBefore($index['index']);
             }
             continue;
         }
         if ($indexLine === $lastIndexLine) {
             $error = 'Each index in a multi-line array must be on a new line';
             $fix = $phpcsFile->addFixableError($error, $index['index'], 'IndexNoNewline');
             if ($fix === true) {
                 if ($tokens[$index['index'] - 1]['code'] === T_WHITESPACE) {
                     $phpcsFile->fixer->replaceToken($index['index'] - 1, '');
                 }
                 $phpcsFile->fixer->addNewlineBefore($index['index']);
             }
             continue;
         }
         if ($tokens[$index['index']]['column'] !== $indicesStart) {
             $expected = $indicesStart - 1;
             $found = $tokens[$index['index']]['column'] - 1;
             $error = 'Array key not aligned correctly; expected %s spaces but found %s';
             $data = array($expected, $found);
             $fix = $phpcsFile->addFixableError($error, $index['index'], 'KeyNotAligned', $data);
             if ($fix === true) {
                 if ($found === 0) {
                     $phpcsFile->fixer->addContent($index['index'] - 1, str_repeat(' ', $expected));
                 } else {
                     $phpcsFile->fixer->replaceToken($index['index'] - 1, str_repeat(' ', $expected));
                 }
             }
             continue;
         }
         if ($tokens[$index['arrow']]['column'] !== $arrowStart) {
             $expected = $arrowStart - (strlen($index['index_content']) + $tokens[$index['index']]['column']);
             $found = $tokens[$index['arrow']]['column'] - (strlen($index['index_content']) + $tokens[$index['index']]['column']);
             $error = 'Array double arrow not aligned correctly; expected %s space(s) but found %s';
             $data = array($expected, $found);
             $fix = $phpcsFile->addFixableError($error, $index['arrow'], 'DoubleArrowNotAligned', $data);
             if ($fix === true) {
                 if ($found === 0) {
                     $phpcsFile->fixer->addContent($index['arrow'] - 1, str_repeat(' ', $expected));
                 } else {
                     $phpcsFile->fixer->replaceToken($index['arrow'] - 1, str_repeat(' ', $expected));
                 }
             }
             continue;
         }
         if ($tokens[$index['value']]['column'] !== $valueStart) {
             $expected = $valueStart - ($tokens[$index['arrow']]['length'] + $tokens[$index['arrow']]['column']);
             $found = $tokens[$index['value']]['column'] - ($tokens[$index['arrow']]['length'] + $tokens[$index['arrow']]['column']);
             if ($found < 0) {
                 $found = 'newline';
             }
             $error = 'Array value not aligned correctly; expected %s space(s) but found %s';
             $data = array($expected, $found);
             $fix = $phpcsFile->addFixableError($error, $index['arrow'], 'ValueNotAligned', $data);
             if ($fix === true) {
                 if ($found === 'newline') {
                     $prev = $phpcsFile->findPrevious(T_WHITESPACE, $index['value'] - 1, null, true);
                     $phpcsFile->fixer->beginChangeset();
                     for ($i = $prev + 1; $i < $index['value']; $i++) {
                         $phpcsFile->fixer->replaceToken($i, '');
                     }
                     $phpcsFile->fixer->replaceToken($index['value'] - 1, str_repeat(' ', $expected));
                     $phpcsFile->fixer->endChangeset();
                 } else {
                     if ($found === 0) {
                         $phpcsFile->fixer->addContent($index['value'] - 1, str_repeat(' ', $expected));
                     } else {
                         $phpcsFile->fixer->replaceToken($index['value'] - 1, str_repeat(' ', $expected));
                     }
                 }
             }
         }
         //end if
         // Check each line ends in a comma.
         if ($tokens[$index['value']]['code'] !== T_ARRAY && $tokens[$index['value']]['code'] !== T_OPEN_SHORT_ARRAY) {
             $valueLine = $tokens[$index['value']]['line'];
             $nextComma = false;
             for ($i = $index['value'] + 1; $i < $arrayEnd; $i++) {
                 // Skip bracketed statements, like function calls.
                 if ($tokens[$i]['code'] === T_OPEN_PARENTHESIS) {
                     $i = $tokens[$i]['parenthesis_closer'];
                     $valueLine = $tokens[$i]['line'];
                     continue;
                 }
                 if ($tokens[$i]['code'] === T_COMMA) {
                     $nextComma = $i;
                     break;
                 }
             }
             if ($nextComma === false || $tokens[$nextComma]['line'] !== $valueLine) {
                 $error = 'Each line in an array declaration must end in a comma';
                 $fix = $phpcsFile->addFixableError($error, $index['value'], 'NoComma');
                 if ($fix === true) {
                     // Find the end of the line and put a comma there.
                     for ($i = $index['value'] + 1; $i < $phpcsFile->numTokens; $i++) {
                         if ($tokens[$i]['line'] > $tokens[$index['value']]['line']) {
                             break;
                         }
                     }
                     $phpcsFile->fixer->addContentBefore($i - 1, ',');
                 }
             }
             // Check that there is no space before the comma.
             if ($nextComma !== false && $tokens[$nextComma - 1]['code'] === T_WHITESPACE) {
                 $content = $tokens[$nextComma - 2]['content'];
                 $spaceLength = $tokens[$nextComma - 1]['length'];
                 $error = 'Expected 0 spaces between "%s" and comma; %s found';
                 $data = array($content, $spaceLength);
                 $fix = $phpcsFile->addFixableError($error, $nextComma, 'SpaceBeforeComma', $data);
                 if ($fix === true) {
                     $phpcsFile->fixer->replaceToken($nextComma - 1, '');
                 }
             }
         }
         //end if
     }
     //end foreach
 }
 /**
  * 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();
     // Skip default values in function declarations.
     if ($tokens[$stackPtr]['code'] === T_EQUAL || $tokens[$stackPtr]['code'] === T_MINUS) {
         if (isset($tokens[$stackPtr]['nested_parenthesis']) === true) {
             $parenthesis = array_keys($tokens[$stackPtr]['nested_parenthesis']);
             $bracket = array_pop($parenthesis);
             if (isset($tokens[$bracket]['parenthesis_owner']) === true) {
                 $function = $tokens[$bracket]['parenthesis_owner'];
                 if ($tokens[$function]['code'] === T_FUNCTION) {
                     return;
                 }
             }
         }
     }
     if ($tokens[$stackPtr]['code'] === T_EQUAL) {
         // Skip for '=&' case.
         if (isset($tokens[$stackPtr + 1]) === true && $tokens[$stackPtr + 1]['code'] === T_BITWISE_AND) {
             return;
         }
     }
     $not_first = $phpcsFile->findFirstOnLine(T_WHITESPACE, $stackPtr + 1, true) !== $stackPtr;
     if ($tokens[$stackPtr]['code'] === T_BITWISE_AND) {
         // If it's not a reference, then we expect one space either side of the
         // bitwise operator.
         if ($phpcsFile->isReference($stackPtr) === true) {
             return;
         }
         // Check there is one space before the & operator.
         if ($not_first && $tokens[$stackPtr - 1]['code'] !== T_WHITESPACE) {
             $error = 'Expected 1 space before "&" operator; 0 found';
             $phpcsFile->addError($error, $stackPtr, 'NoSpaceBeforeAmp');
         } else {
             if ($not_first && strlen($tokens[$stackPtr - 1]['content']) !== 1) {
                 $found = strlen($tokens[$stackPtr - 1]['content']);
                 $error = 'Expected 1 space before "&" operator; %s found';
                 $data = array($found);
                 $phpcsFile->addError($error, $stackPtr, 'SpacingBeforeAmp', $data);
             }
         }
         // Check there is one space after the & operator.
         if ($tokens[$stackPtr + 1]['code'] !== T_WHITESPACE) {
             $error = 'Expected 1 space after "&" operator; 0 found';
             $phpcsFile->addError($error, $stackPtr, 'NoSpaceAfterAmp');
         } else {
             if (strlen($tokens[$stackPtr + 1]['content']) !== 1) {
                 $found = strlen($tokens[$stackPtr + 1]['content']);
                 $error = 'Expected 1 space after "&" operator; %s found';
                 $data = array($found);
                 $phpcsFile->addError($error, $stackPtr, 'SpacingAfterAmp', $data);
             }
         }
         return;
     }
     //end if
     if ($tokens[$stackPtr]['code'] === T_MINUS) {
         // Check minus spacing, but make sure we aren't just assigning
         // a minus value or returning one.
         $prev = $phpcsFile->findPrevious(T_WHITESPACE, $stackPtr - 1, null, true);
         if ($tokens[$prev]['code'] === T_RETURN) {
             // Just returning a negative value; eg. return -1.
             return;
         }
         if (in_array($tokens[$prev]['code'], PHP_CodeSniffer_Tokens::$operators) === true) {
             // Just trying to operate on a negative value; eg. ($var * -1).
             return;
         }
         if (in_array($tokens[$prev]['code'], PHP_CodeSniffer_Tokens::$comparisonTokens) === true) {
             // Just trying to compare a negative value; eg. ($var === -1).
             return;
         }
         // A list of tokens that indicate that the token is not
         // part of an arithmetic operation.
         $invalidTokens = array(T_COMMA, T_OPEN_PARENTHESIS, T_OPEN_SQUARE_BRACKET, T_DOUBLE_ARROW, T_COLON);
         if (in_array($tokens[$prev]['code'], $invalidTokens) === true) {
             // Just trying to use a negative value; eg. myFunction($var, -2).
             return;
         }
         $number = $phpcsFile->findNext(T_WHITESPACE, $stackPtr + 1, null, true);
         if (in_array($tokens[$number]['code'], array(T_LNUMBER, T_VARIABLE)) === true) {
             $semi = $phpcsFile->findNext(T_WHITESPACE, $number + 1, null, true);
             if ($tokens[$semi]['code'] === T_SEMICOLON) {
                 if ($prev !== false && in_array($tokens[$prev]['code'], PHP_CodeSniffer_Tokens::$assignmentTokens) === true) {
                     // This is a negative assignment.
                     return;
                 }
             }
         }
     }
     //end if
     $operator = $tokens[$stackPtr]['content'];
     if ($not_first && $tokens[$stackPtr - 1]['code'] !== T_WHITESPACE) {
         $error = "Expected 1 space before foo \"{$operator}\"; 0 found";
         $phpcsFile->addError($error, $stackPtr, 'NoSpaceBefore');
     } else {
         if (strlen($tokens[$stackPtr - 1]['content']) !== 1) {
             // Don't throw an error for assignments, because other standards allow
             // multiple spaces there to align multiple assignments.
             if ($not_first && in_array($tokens[$stackPtr]['code'], PHP_CodeSniffer_Tokens::$assignmentTokens) === false) {
                 $found = strlen($tokens[$stackPtr - 1]['content']);
                 $error = 'Expected 1 space before bar "%s"; %s found';
                 $data = array($operator, $found);
                 $phpcsFile->addError($error, $stackPtr, 'SpacingBefore', $data);
             }
         }
     }
     if ($tokens[$stackPtr + 1]['code'] !== T_WHITESPACE) {
         $error = "Expected 1 space after \"{$operator}\"; 0 found";
         $phpcsFile->addError($error, $stackPtr, 'NoSpaceAfter');
     } else {
         if (strlen($tokens[$stackPtr + 1]['content']) !== 1) {
             $found = strlen($tokens[$stackPtr + 1]['content']);
             $error = 'Expected 1 space after "%s"; %s found';
             $data = array($operator, $found);
             $phpcsFile->addError($error, $stackPtr, 'SpacingAfter', $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();
     $functionName = $phpcsFile->findNext(array(T_STRING), $stackPtr);
     $openBracket = $tokens[$stackPtr]['parenthesis_opener'];
     $closeBracket = $tokens[$stackPtr]['parenthesis_closer'];
     $multiLine = $tokens[$openBracket]['line'] !== $tokens[$closeBracket]['line'];
     $nextParam = $openBracket;
     $params = array();
     while (($nextParam = $phpcsFile->findNext(T_VARIABLE, $nextParam + 1, $closeBracket)) !== false) {
         $nextToken = $phpcsFile->findNext(T_WHITESPACE, $nextParam + 1, $closeBracket + 1, true);
         if ($nextToken === false) {
             break;
         }
         $nextCode = $tokens[$nextToken]['code'];
         if ($nextCode === T_EQUAL) {
             if ($tokens[$nextToken + 1]['code'] === T_WHITESPACE) {
                 $gap = strlen($tokens[$nextToken + 1]['content']);
                 $arg = $tokens[$nextParam]['content'];
                 if ($gap != 1) {
                     $error = "Expected 1 space between default value and equals sign for argument \"{$arg}\"; {$gap} found";
                     $phpcsFile->addError($error, $nextToken);
                 }
             } else {
                 $error = "Expected 1 space between default value and equals sign for argument";
                 $phpcsFile->addError($error, $nextToken);
             }
         }
         // Find and check the comma (if there is one).
         $nextComma = $phpcsFile->findNext(T_COMMA, $nextParam + 1, $closeBracket);
         if ($nextComma !== false) {
             // Comma found.
             if ($tokens[$nextComma - 1]['code'] === T_WHITESPACE) {
                 $space = strlen($tokens[$nextComma - 1]['content']);
                 $arg = $tokens[$nextParam]['content'];
                 $error = "Expected 0 spaces between argument \"{$arg}\" and comma; {$space} found";
                 $phpcsFile->addError($error, $nextToken);
             }
         }
         // Take references into account when expecting the
         // location of whitespace.
         if ($phpcsFile->isReference($nextParam - 1) === true) {
             $whitespace = $tokens[$nextParam - 2];
         } else {
             $whitespace = $tokens[$nextParam - 1];
         }
         if (empty($params) === false) {
             // This is not the first argument in the function declaration.
             $arg = $tokens[$nextParam]['content'];
             if ($whitespace['code'] === T_WHITESPACE) {
                 $gap = strlen($whitespace['content']);
                 // Before we throw an error, make sure there is no type hint.
                 $comma = $phpcsFile->findPrevious(T_COMMA, $nextParam - 1);
                 $nextToken = $phpcsFile->findNext(T_WHITESPACE, $comma + 1, null, true);
                 if ($phpcsFile->isReference($nextToken) === true) {
                     $nextToken++;
                 }
                 if ($nextToken !== $nextParam) {
                     // There was a type hint, so check the spacing between
                     // the hint and the variable as well.
                     $hint = $tokens[$nextToken]['content'];
                     if ($gap !== 1 && $multiLine === false) {
                         $error = "Expected 1 space between type hint and argument \"{$arg}\"; {$gap} found";
                         $phpcsFile->addError($error, $nextToken);
                     }
                     if ($multiLine === false) {
                         if ($tokens[$comma + 1]['code'] !== T_WHITESPACE) {
                             $error = "Expected 1 space between comma and type hint \"{$hint}\"; 0 found";
                             $phpcsFile->addError($error, $nextToken);
                         } else {
                             $gap = strlen($tokens[$comma + 1]['content']);
                             if ($gap !== 1) {
                                 $error = "Expected 1 space between comma and type hint \"{$hint}\"; {$gap} found";
                                 $phpcsFile->addError($error, $nextToken);
                             }
                         }
                     }
                 } elseif ($multiLine === false && $gap !== 1) {
                     $error = "Expected 1 space between comma and argument \"{$arg}\"; {$gap} found";
                     $phpcsFile->addError($error, $nextToken);
                 }
                 //end if
             } else {
                 $error = "Expected 1 space between comma and argument \"{$arg}\"; 0 found";
                 $phpcsFile->addError($error, $nextToken);
             }
             //end if
         } else {
             // First argument in function declaration.
             if ($whitespace['code'] === T_WHITESPACE) {
                 $gap = strlen($whitespace['content']);
                 $arg = $tokens[$nextParam]['content'];
                 // Before we throw an error, make sure there is no type hint.
                 $bracket = $phpcsFile->findPrevious(T_OPEN_PARENTHESIS, $nextParam - 1);
                 $nextToken = $phpcsFile->findNext(T_WHITESPACE, $bracket + 1, null, true);
                 if ($phpcsFile->isReference($nextToken) === true) {
                     $nextToken++;
                 }
                 if ($nextToken !== $nextParam) {
                     // There was a type hint, so check the spacing between
                     // the hint and the variable as well.
                     $hint = $tokens[$nextToken]['content'];
                     if ($gap !== 1 && $multiLine === false) {
                         $error = "Expected 1 space between type hint and argument \"{$arg}\"; {$gap} found";
                         $phpcsFile->addError($error, $nextToken);
                     }
                     if ($multiLine === false && $tokens[$bracket + 1]['code'] === T_WHITESPACE) {
                         $gap = strlen($tokens[$bracket + 1]['content']);
                         if ($gap != 1) {
                             $error = "Expected 1 space between opening bracket and type hint \"{$hint}\"; {$gap} found";
                             $phpcsFile->addError($error, $nextToken);
                         }
                     }
                 } elseif ($multiLine === false) {
                     if ($gap != 1) {
                         $error = "Expected 1 space between opening bracket and argument \"{$arg}\"; {$gap} found";
                         $phpcsFile->addError($error, $nextToken);
                     }
                 }
             }
             //end if
         }
         //end if
         $params[] = $nextParam;
     }
     //end while
     if (empty($params) === true) {
         // There are no parameters for this function.
         if ($closeBracket - $openBracket !== 1) {
             $space = strlen($tokens[$closeBracket - 1]['content']);
             $error = "Expected 0 spaces between brackets of function declaration; {$space} found";
             $phpcsFile->addError($error, $stackPtr);
         }
     } else {
         // There should be exactly one space after the opening parenthesis
         if ($tokens[$openBracket + 1]['code'] !== T_WHITESPACE || strlen($tokens[$openBracket + 1]['content']) != 1) {
             // If the open bracket doesn't have a space after it and it's not the last thing on the line, throw an error
             if ($tokens[$openBracket + 1]['content'] != PHP_EOL) {
                 $error = "Expected 1 space between the opening parenthesis and first argument";
                 $phpcsFile->addError($error, $openBracket);
             }
         }
         // There should be exactly one space or a newline before the closing
         // parenthesis (todo: check for proper indentation if newline)
         if ($tokens[$closeBracket - 1]['code'] !== T_WHITESPACE || strlen($tokens[$closeBracket - 1]['content']) != 1 && $tokens[$closeBracket - 2]['content'] !== PHP_EOL) {
             $firstOnLine = $phpcsFile->findFirstOnLine(T_WHITESPACE, $closeBracket, true);
             // Don't throw an error if the closing parenthesis is the first thing on the line
             if ($firstOnLine != $closeBracket) {
                 $error = "Expected 1 space between the last argument and the closing parenthesis";
                 $phpcsFile->addError($error, $closeBracket);
             }
         }
     }
 }
 /**
  * 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(PHP_CodeSniffer_File $phpcsFile, $stackPtr)
 {
     $tokens = $phpcsFile->getTokens();
     $ignore = PHP_CodeSniffer_Tokens::$methodPrefixes;
     $ignore[] = T_VAR;
     $ignore[] = T_WHITESPACE;
     $start = $stackPtr;
     $prev = $phpcsFile->findPrevious($ignore, $stackPtr - 1, null, true);
     if (isset(PHP_CodeSniffer_Tokens::$commentTokens[$tokens[$prev]['code']]) === true) {
         // Assume the comment belongs to the member var if it is on a line by itself.
         $prevContent = $phpcsFile->findPrevious(PHP_CodeSniffer_Tokens::$emptyTokens, $prev - 1, null, true);
         if ($tokens[$prevContent]['line'] !== $tokens[$prev]['line']) {
             // Check the spacing, but then skip it.
             $foundLines = $tokens[$stackPtr]['line'] - $tokens[$prev]['line'] - 1;
             if ($foundLines > 0) {
                 $error = 'Expected 0 blank lines after member var comment; %s found';
                 $data = array($foundLines);
                 $fix = $phpcsFile->addFixableError($error, $prev, 'AfterComment', $data);
                 if ($fix === true) {
                     $phpcsFile->fixer->beginChangeset();
                     // Inline comments have the newline included in the content but
                     // docblock do not.
                     if ($tokens[$prev]['code'] === T_COMMENT) {
                         $phpcsFile->fixer->replaceToken($prev, rtrim($tokens[$prev]['content']));
                     }
                     for ($i = $prev + 1; $i <= $stackPtr; $i++) {
                         if ($tokens[$i]['line'] === $tokens[$stackPtr]['line']) {
                             break;
                         }
                         $phpcsFile->fixer->replaceToken($i, '');
                     }
                     $phpcsFile->fixer->addNewline($prev);
                     $phpcsFile->fixer->endChangeset();
                 }
             }
             //end if
             $start = $prev;
         }
         //end if
     }
     //end if
     // There needs to be 1 blank line before the var, not counting comments.
     if ($start === $stackPtr) {
         // No comment found.
         $first = $phpcsFile->findFirstOnLine(PHP_CodeSniffer_Tokens::$emptyTokens, $start, true);
         if ($first === false) {
             $first = $start;
         }
     } else {
         if ($tokens[$start]['code'] === T_DOC_COMMENT_CLOSE_TAG) {
             $first = $tokens[$start]['comment_opener'];
         } else {
             $first = $phpcsFile->findPrevious(PHP_CodeSniffer_Tokens::$emptyTokens, $start - 1, null, true);
             $first = $phpcsFile->findNext(PHP_CodeSniffer_Tokens::$commentTokens, $first + 1);
         }
     }
     $prev = $phpcsFile->findPrevious(PHP_CodeSniffer_Tokens::$emptyTokens, $first - 1, null, true);
     $foundLines = $tokens[$first]['line'] - $tokens[$prev]['line'] - 1;
     if ($foundLines === 1) {
         return;
     }
     $error = 'Expected 1 blank line before member var; %s found';
     $data = array($foundLines);
     $fix = $phpcsFile->addFixableError($error, $stackPtr, 'Incorrect', $data);
     if ($fix === true) {
         $phpcsFile->fixer->beginChangeset();
         for ($i = $prev + 1; $i < $first; $i++) {
             if ($tokens[$i]['line'] === $tokens[$prev]['line']) {
                 continue;
             }
             if ($tokens[$i]['line'] === $tokens[$first]['line']) {
                 $phpcsFile->fixer->addNewline($i - 1);
                 break;
             }
             $phpcsFile->fixer->replaceToken($i, '');
         }
         $phpcsFile->fixer->endChangeset();
     }
     //end if
 }