getPrevMeaningfulToken() public method

Get index for closest previous token that is not a whitespace or comment.
public getPrevMeaningfulToken ( integer $index ) : integer | null
$index integer token index
return integer | null
Esempio n. 1
0
 /**
  * @param Tokens $tokens
  * @param int    $index
  *
  * @return int
  */
 private function findStart(Tokens $tokens, $index)
 {
     do {
         $index = $tokens->getPrevMeaningfulToken($index);
         $token = $tokens[$index];
         $blockType = $tokens->detectBlockType($token);
         if (null !== $blockType && !$blockType['isStart']) {
             $index = $tokens->findBlockEnd($blockType['type'], $index, false);
             $token = $tokens[$index];
         }
     } while (!$token->equalsAny(array('$', array(T_VARIABLE))));
     $prevIndex = $tokens->getPrevMeaningfulToken($index);
     $prevToken = $tokens[$prevIndex];
     if ($prevToken->equals('$')) {
         $index = $prevIndex;
         $prevIndex = $tokens->getPrevMeaningfulToken($index);
         $prevToken = $tokens[$prevIndex];
     }
     if ($prevToken->isGivenKind(T_OBJECT_OPERATOR)) {
         return $this->findStart($tokens, $prevIndex);
     }
     if ($prevToken->isGivenKind(T_PAAMAYIM_NEKUDOTAYIM)) {
         $prevPrevIndex = $tokens->getPrevMeaningfulToken($prevIndex);
         if (!$tokens[$prevPrevIndex]->isGivenKind(T_STRING)) {
             return $this->findStart($tokens, $prevIndex);
         }
         $index = $tokens->getTokenNotOfKindSibling($prevIndex, -1, array(array(T_NS_SEPARATOR), array(T_STRING)));
         $index = $tokens->getNextMeaningfulToken($index);
     }
     return $index;
 }
 /**
  * {@inheritdoc}
  */
 public function fix(\SplFileInfo $file, Tokens $tokens)
 {
     /** @var $token \PhpCsFixer\Tokenizer\Token */
     foreach ($tokens->findGivenKind(T_STRING) as $index => $token) {
         // skip expressions without parameters list
         $nextToken = $tokens[$tokens->getNextMeaningfulToken($index)];
         if (!$nextToken->equals('(')) {
             continue;
         }
         // skip expressions which are not function reference
         $prevTokenIndex = $tokens->getPrevMeaningfulToken($index);
         $prevToken = $tokens[$prevTokenIndex];
         if ($prevToken->isGivenKind(array(T_DOUBLE_COLON, T_NEW, T_OBJECT_OPERATOR, T_FUNCTION))) {
             continue;
         }
         // handle function reference with namespaces
         if ($prevToken->isGivenKind(array(T_NS_SEPARATOR))) {
             $twicePrevTokenIndex = $tokens->getPrevMeaningfulToken($prevTokenIndex);
             $twicePrevToken = $tokens[$twicePrevTokenIndex];
             if ($twicePrevToken->isGivenKind(array(T_DOUBLE_COLON, T_NEW, T_OBJECT_OPERATOR, T_FUNCTION, T_STRING, CT::T_NAMESPACE_OPERATOR))) {
                 continue;
             }
         }
         // check mapping hit
         $tokenContent = strtolower($token->getContent());
         if (!isset(self::$aliases[$tokenContent])) {
             continue;
         }
         $token->setContent(self::$aliases[$tokenContent]);
     }
 }
Esempio n. 3
0
 /**
  * {@inheritdoc}
  */
 public function fix(\SplFileInfo $file, Tokens $tokens)
 {
     static $nativeFunctionNames = null;
     if (null === $nativeFunctionNames) {
         $nativeFunctionNames = $this->getNativeFunctionNames();
     }
     for ($index = 0, $count = $tokens->count(); $index < $count; ++$index) {
         // test if we are at a function all
         if (!$tokens[$index]->isGivenKind(T_STRING)) {
             continue;
         }
         $next = $tokens->getNextMeaningfulToken($index);
         if (!$tokens[$next]->equals('(')) {
             $index = $next;
             continue;
         }
         $functionNamePrefix = $tokens->getPrevMeaningfulToken($index);
         if ($tokens[$functionNamePrefix]->isGivenKind(array(T_DOUBLE_COLON, T_NEW, T_OBJECT_OPERATOR, T_FUNCTION))) {
             continue;
         }
         // do not though the function call if it is to a function in a namespace other than the default
         if ($tokens[$functionNamePrefix]->isGivenKind(T_NS_SEPARATOR) && $tokens[$tokens->getPrevMeaningfulToken($functionNamePrefix)]->isGivenKind(T_STRING)) {
             continue;
         }
         // test if the function call is to a native PHP function
         $lower = strtolower($tokens[$index]->getContent());
         if (!array_key_exists($lower, $nativeFunctionNames)) {
             continue;
         }
         $tokens[$index]->setContent($nativeFunctionNames[$lower]);
         $index = $next;
     }
 }
Esempio n. 4
0
 /**
  * Replace occurrences of the name of the classy element by "self" (if possible).
  *
  * @param Tokens $tokens
  * @param string $name
  * @param int    $startIndex
  * @param int    $endIndex
  */
 private function replaceNameOccurrences(Tokens $tokens, $name, $startIndex, $endIndex)
 {
     $tokensAnalyzer = new TokensAnalyzer($tokens);
     for ($i = $startIndex; $i < $endIndex; ++$i) {
         $token = $tokens[$i];
         // skip lambda functions (PHP < 5.4 compatibility)
         if ($token->isGivenKind(T_FUNCTION) && $tokensAnalyzer->isLambda($i)) {
             $i = $tokens->getNextTokenOfKind($i, array('{'));
             $i = $tokens->findBlockEnd(Tokens::BLOCK_TYPE_CURLY_BRACE, $i);
             continue;
         }
         if (!$token->equals(array(T_STRING, $name), false)) {
             continue;
         }
         $prevToken = $tokens[$tokens->getPrevMeaningfulToken($i)];
         $nextToken = $tokens[$tokens->getNextMeaningfulToken($i)];
         // skip tokens that are part of a fully qualified name
         if ($prevToken->isGivenKind(T_NS_SEPARATOR) || $nextToken->isGivenKind(T_NS_SEPARATOR)) {
             continue;
         }
         if ($prevToken->isGivenKind(array(T_INSTANCEOF, T_NEW)) || $nextToken->isGivenKind(T_PAAMAYIM_NEKUDOTAYIM)) {
             $token->setContent('self');
         }
     }
 }
 /**
  * Looks up Tokens sequence for suitable candidates and delivers boundaries information,
  * which can be supplied by other methods in this abstract class.
  *
  * @param string   $functionNameToSearch
  * @param Tokens   $tokens
  * @param int      $start
  * @param int|null $end
  *
  * @return int[]|null returns $functionName, $openParenthesis, $closeParenthesis packed into array
  */
 protected function find($functionNameToSearch, Tokens $tokens, $start = 0, $end = null)
 {
     // make interface consistent with findSequence
     $end = null === $end ? $tokens->count() : $end;
     // find raw sequence which we can analyse for context
     $candidateSequence = array(array(T_STRING, $functionNameToSearch), '(');
     $matches = $tokens->findSequence($candidateSequence, $start, $end, false);
     if (null === $matches) {
         // not found, simply return without further attempts
         return;
     }
     // translate results for humans
     list($functionName, $openParenthesis) = array_keys($matches);
     // first criteria check: shall look like function call
     $functionNamePrefix = $tokens->getPrevMeaningfulToken($functionName);
     $functionNamePrecedingToken = $tokens[$functionNamePrefix];
     if ($functionNamePrecedingToken->isGivenKind(array(T_DOUBLE_COLON, T_NEW, T_OBJECT_OPERATOR, T_FUNCTION))) {
         // this expression is differs from expected, resume
         return $this->find($functionNameToSearch, $tokens, $openParenthesis, $end);
     }
     // second criteria check: ensure namespace is the root one
     if ($functionNamePrecedingToken->isGivenKind(T_NS_SEPARATOR)) {
         $namespaceCandidate = $tokens->getPrevMeaningfulToken($functionNamePrefix);
         $namespaceCandidateToken = $tokens[$namespaceCandidate];
         if ($namespaceCandidateToken->isGivenKind(array(T_NEW, T_STRING, CT::T_NAMESPACE_OPERATOR))) {
             // here can be added complete namespace scan
             // this expression is differs from expected, resume
             return $this->find($functionNameToSearch, $tokens, $openParenthesis, $end);
         }
     }
     // final step: find closing parenthesis
     $closeParenthesis = $tokens->findBlockEnd(Tokens::BLOCK_TYPE_PARENTHESIS_BRACE, $openParenthesis);
     return array($functionName, $openParenthesis, $closeParenthesis);
 }
 /**
  * {@inheritdoc}
  */
 public function fix(\SplFileInfo $file, Tokens $tokens)
 {
     for ($index = $tokens->count() - 3; $index > 0; --$index) {
         $token = $tokens[$index];
         if (!$token->isGivenKind(T_NEW)) {
             continue;
         }
         $nextIndex = $tokens->getNextTokenOfKind($index, array(':', ';', ',', '(', ')', '[', ']', array(T_CLOSE_TAG), array(CT_ARRAY_SQUARE_BRACE_OPEN), array(CT_ARRAY_SQUARE_BRACE_CLOSE), array(CT_BRACE_CLASS_INSTANTIATION_OPEN), array(CT_BRACE_CLASS_INSTANTIATION_CLOSE)));
         $nextToken = $tokens[$nextIndex];
         // entrance into array index syntax - need to look for exit
         while ($nextToken->equals('[')) {
             $nextIndex = $tokens->findBlockEnd(Tokens::BLOCK_TYPE_INDEX_SQUARE_BRACE, $nextIndex) + 1;
             $nextToken = $tokens[$nextIndex];
         }
         // new statement has a gap in it - advance to the next token
         if ($nextToken->isWhitespace()) {
             $nextIndex = $tokens->getNextNonWhitespace($nextIndex);
             $nextToken = $tokens[$nextIndex];
         }
         // new statement with () - nothing to do
         if ($nextToken->equals('(')) {
             continue;
         }
         $meaningBeforeNextIndex = $tokens->getPrevMeaningfulToken($nextIndex);
         $tokens->insertAt($meaningBeforeNextIndex + 1, array(new Token('('), new Token(')')));
     }
 }
 /**
  * {@inheritdoc}
  */
 public function fix(\SplFileInfo $file, Tokens $tokens)
 {
     // Checks if specific statements are set and uses them in this case.
     $loops = array_intersect_key(self::$loops, array_flip($this->controlStatements));
     foreach ($tokens as $index => $token) {
         if (!$token->equals('(')) {
             continue;
         }
         $blockStartIndex = $index;
         $index = $tokens->getPrevMeaningfulToken($index);
         $token = $tokens[$index];
         foreach ($loops as $loop) {
             if (!$token->isGivenKind($loop['lookupTokens'])) {
                 continue;
             }
             $blockEndIndex = $tokens->findBlockEnd(Tokens::BLOCK_TYPE_PARENTHESIS_BRACE, $blockStartIndex);
             $blockEndNextIndex = $tokens->getNextMeaningfulToken($blockEndIndex);
             if (!$tokens[$blockEndNextIndex]->equalsAny($loop['neededSuccessors'])) {
                 continue;
             }
             if ($tokens[$blockStartIndex - 1]->isWhitespace() || $tokens[$blockStartIndex - 1]->isComment()) {
                 $this->clearParenthesis($tokens, $blockStartIndex);
             } else {
                 // Adds a space to prevent broken code like `return2`.
                 $tokens->overrideAt($blockStartIndex, array(T_WHITESPACE, ' '));
             }
             $this->clearParenthesis($tokens, $blockEndIndex);
         }
     }
 }
 /**
  * {@inheritdoc}
  */
 public function process(Tokens $tokens, Token $token, $index)
 {
     if (!$token->equals('|')) {
         return;
     }
     $prevIndex = $tokens->getPrevMeaningfulToken($index);
     $prevToken = $tokens[$prevIndex];
     if (!$prevToken->isGivenKind(T_STRING)) {
         return;
     }
     $prevIndex = $tokens->getPrevMeaningfulToken($prevIndex);
     $prevToken = $tokens[$prevIndex];
     if (!$prevToken->equalsAny(array('(', array(CT::T_TYPE_ALTERNATION)))) {
         return;
     }
     $token->override(array(CT::T_TYPE_ALTERNATION, '|'));
 }
 /**
  * {@inheritdoc}
  */
 public function process(Tokens $tokens, Token $token, $index)
 {
     if (!$token->isGivenKind(array(T_CONST, T_FUNCTION))) {
         return;
     }
     $prevToken = $tokens[$tokens->getPrevMeaningfulToken($index)];
     if ($prevToken->isGivenKind(T_USE)) {
         $token->override(array($token->isGivenKind(T_FUNCTION) ? CT_FUNCTION_IMPORT : CT_CONST_IMPORT, $token->getContent()));
     }
 }
 /**
  * {@inheritdoc}
  */
 public function fix(\SplFileInfo $file, Tokens $tokens)
 {
     foreach ($tokens as $index => $token) {
         if (!$token->equals('(')) {
             continue;
         }
         $prevIndex = $tokens->getPrevMeaningfulToken($index);
         // ignore parenthesis for T_ARRAY
         if (null !== $prevIndex && $tokens[$prevIndex]->isGivenKind(T_ARRAY)) {
             continue;
         }
         $endIndex = $tokens->findBlockEnd(Tokens::BLOCK_TYPE_PARENTHESIS_BRACE, $index);
         // remove space after opening `(`
         $this->removeSpaceAroundToken($tokens[$index + 1]);
         // remove space before closing `)` if it is not `list($a, $b, )` case
         if (!$tokens[$tokens->getPrevMeaningfulToken($endIndex)]->equals(',')) {
             $this->removeSpaceAroundToken($tokens[$endIndex - 1]);
         }
     }
 }
 /**
  * {@inheritdoc}
  */
 public function process(Tokens $tokens, Token $token, $index)
 {
     if (!$token->isGivenKind(T_CLASS)) {
         return;
     }
     $prevIndex = $tokens->getPrevMeaningfulToken($index);
     $prevToken = $tokens[$prevIndex];
     if ($prevToken->isGivenKind(T_DOUBLE_COLON)) {
         $token->override(array(CT_CLASS_CONSTANT, $token->getContent()));
     }
 }
 /**
  * {@inheritdoc}
  */
 public function process(Tokens $tokens, Token $token, $index)
 {
     if (!$token->equalsAny(array(array(T_CLASS, 'class'), array(T_STRING, 'class')), false)) {
         return;
     }
     $prevIndex = $tokens->getPrevMeaningfulToken($index);
     $prevToken = $tokens[$prevIndex];
     if ($prevToken->isGivenKind(T_DOUBLE_COLON)) {
         $token->override(array(CT::T_CLASS_CONSTANT, $token->getContent()));
     }
 }
 /**
  * {@inheritdoc}
  */
 public function process(Tokens $tokens, Token $token, $index)
 {
     if (!$token->equals('?')) {
         return;
     }
     $prevIndex = $tokens->getPrevMeaningfulToken($index);
     $prevToken = $tokens[$prevIndex];
     if ($prevToken->equalsAny(array('(', ',', array(CT::T_TYPE_COLON)))) {
         $token->override(array(CT::T_NULLABLE_TYPE, '?'));
     }
 }
Esempio n. 14
0
 /**
  * {@inheritdoc}
  */
 public function process(Tokens $tokens, Token $token, $index)
 {
     if (!$token->equals(':')) {
         return;
     }
     $endIndex = $tokens->getPrevMeaningfulToken($index);
     if (!$tokens[$endIndex]->equals(')')) {
         return;
     }
     $startIndex = $tokens->findBlockEnd(Tokens::BLOCK_TYPE_PARENTHESIS_BRACE, $endIndex, false);
     $prevIndex = $tokens->getPrevMeaningfulToken($startIndex);
     $prevToken = $tokens[$prevIndex];
     // if this could be a function name we need to take one more step
     if ($prevToken->isGivenKind(T_STRING)) {
         $prevIndex = $tokens->getPrevMeaningfulToken($prevIndex);
         $prevToken = $tokens[$prevIndex];
     }
     if ($prevToken->isGivenKind(array(T_FUNCTION, CT::T_RETURN_REF, CT::T_USE_LAMBDA))) {
         $token->override(array(CT::T_TYPE_COLON, ':'));
     }
 }
 /**
  * {@inheritdoc}
  */
 public function fix(\SplFileInfo $file, Tokens $tokens)
 {
     $tokensAnalyzer = new TokensAnalyzer($tokens);
     for ($index = $tokens->count() - 1; $index >= 0; --$index) {
         if (!$tokensAnalyzer->isBinaryOperator($index)) {
             continue;
         }
         // skip `declare(foo ==bar)`
         $prevMeaningfulIndex = $tokens->getPrevMeaningfulToken($index);
         if ($tokens[$prevMeaningfulIndex]->isGivenKind(T_STRING)) {
             $prevMeaningfulIndex = $tokens->getPrevMeaningfulToken($prevMeaningfulIndex);
             if ($tokens[$prevMeaningfulIndex]->equals('(')) {
                 $prevMeaningfulIndex = $tokens->getPrevMeaningfulToken($prevMeaningfulIndex);
                 if ($tokens[$prevMeaningfulIndex]->isGivenKind(T_DECLARE)) {
                     continue;
                 }
             }
         }
         // fix white space after operator
         if ($tokens[$index + 1]->isWhitespace()) {
             $content = $tokens[$index + 1]->getContent();
             if (' ' !== $content && false === strpos($content, "\n") && !$tokens[$tokens->getNextNonWhitespace($index + 1)]->isComment()) {
                 $tokens[$index + 1]->setContent(' ');
             }
         } else {
             $tokens->insertAt($index + 1, new Token(array(T_WHITESPACE, ' ')));
         }
         // fix white space before operator
         if ($tokens[$index - 1]->isWhitespace()) {
             $content = $tokens[$index - 1]->getContent();
             if (' ' !== $content && false === strpos($content, "\n") && !$tokens[$tokens->getPrevNonWhitespace($index - 1)]->isComment()) {
                 $tokens[$index - 1]->setContent(' ');
             }
         } else {
             $tokens->insertAt($index, new Token(array(T_WHITESPACE, ' ')));
         }
         --$index;
         // skip check for binary operator on the whitespace token that is fixed.
     }
 }
 /**
  * Check if token under given index is short array opening.
  *
  * @param Tokens $tokens
  * @param int    $index
  *
  * @return bool
  */
 private function isShortArray(Tokens $tokens, $index)
 {
     static $disallowedPrevTokens = array(')', ']', '}', '"', array(T_CONSTANT_ENCAPSED_STRING), array(T_STRING), array(T_STRING_VARNAME), array(T_VARIABLE), array(CT_ARRAY_SQUARE_BRACE_CLOSE), array(CT_DYNAMIC_PROP_BRACE_CLOSE), array(CT_DYNAMIC_VAR_BRACE_CLOSE));
     $token = $tokens[$index];
     if (!$token->equals('[')) {
         return false;
     }
     $prevToken = $tokens[$tokens->getPrevMeaningfulToken($index)];
     if (!$prevToken->equalsAny($disallowedPrevTokens)) {
         return true;
     }
     return false;
 }
Esempio n. 17
0
 /**
  * {@inheritdoc}
  */
 public function fix(\SplFileInfo $file, Tokens $tokens)
 {
     foreach ($tokens as $index => $token) {
         if (!$token->isGivenKind(T_PRINT)) {
             continue;
         }
         $prevToken = $tokens[$tokens->getPrevMeaningfulToken($index)];
         if (!$prevToken->equalsAny(array(';', '{', '}', array(T_OPEN_TAG)))) {
             continue;
         }
         $tokens->overrideAt($index, array(T_ECHO, 'echo'));
     }
 }
 /**
  * {@inheritdoc}
  */
 public function fix(\SplFileInfo $file, Tokens $tokens)
 {
     for ($index = $tokens->count() - 1; $index >= 0; --$index) {
         $token = $tokens[$index];
         if (!$token->equals(array(T_STRING, 'trigger_error'), false)) {
             continue;
         }
         $start = $index;
         $prev = $tokens->getPrevMeaningfulToken($start);
         if ($tokens[$prev]->isGivenKind(T_NS_SEPARATOR)) {
             $start = $prev;
             $prev = $tokens->getPrevMeaningfulToken($start);
         }
         if ($tokens[$prev]->isGivenKind(T_STRING) || $tokens[$prev]->equals('@')) {
             continue;
         }
         $end = $tokens->findBlockEnd(Tokens::BLOCK_TYPE_PARENTHESIS_BRACE, $tokens->getNextTokenOfKind($index, array(T_STRING, '(')));
         if ($tokens[$tokens->getPrevMeaningfulToken($end)]->equals(array(T_STRING, 'E_USER_DEPRECATED'))) {
             $tokens->insertAt($start, new Token('@'));
         }
     }
 }
 /**
  * Method to move index over the non-array elements like function calls or function declarations.
  *
  * @param int    $index
  * @param Tokens $tokens
  *
  * @return int New index
  */
 private function skipNonArrayElements($index, Tokens $tokens)
 {
     if ($tokens[$index]->equals('}')) {
         return $tokens->findBlockEnd(Tokens::BLOCK_TYPE_CURLY_BRACE, $index, false);
     }
     if ($tokens[$index]->equals(')')) {
         $startIndex = $tokens->findBlockEnd(Tokens::BLOCK_TYPE_PARENTHESIS_BRACE, $index, false);
         $startIndex = $tokens->getPrevMeaningfulToken($startIndex);
         if (!$tokens[$startIndex]->isGivenKind(array(T_ARRAY, CT::T_ARRAY_SQUARE_BRACE_OPEN))) {
             return $startIndex;
         }
     }
     return $index;
 }
 /**
  * {@inheritdoc}
  */
 public function fix(\SplFileInfo $file, Tokens $tokens)
 {
     $tokensAnalyzer = new TokensAnalyzer($tokens);
     $uses = array_reverse($tokensAnalyzer->getImportUseIndexes());
     foreach ($uses as $index) {
         $endIndex = $tokens->getNextTokenOfKind($index, array(';', array(T_CLOSE_TAG)));
         $groupClose = $tokens->getPrevMeaningfulToken($endIndex);
         if ($tokens[$groupClose]->isGivenKind(CT::T_GROUP_IMPORT_BRACE_CLOSE)) {
             $this->fixGroupUse($tokens, $index, $endIndex);
         } else {
             $this->fixMultipleUse($tokens, $index, $endIndex);
         }
     }
 }
 /**
  * {@inheritdoc}
  */
 public function fix(\SplFileInfo $file, Tokens $tokens)
 {
     $limit = $tokens->count();
     for ($index = 0; $index < $limit; ++$index) {
         $token = $tokens[$index];
         // skip T_FOR parenthesis to ignore duplicated `;` like `for ($i = 1; ; ++$i) {...}`
         if ($token->isGivenKind(T_FOR)) {
             $index = $tokens->findBlockEnd(Tokens::BLOCK_TYPE_PARENTHESIS_BRACE, $tokens->getNextMeaningfulToken($index)) + 1;
             continue;
         }
         if (!$token->equals(';') || !$tokens[$tokens->getPrevMeaningfulToken($index)]->equals(';')) {
             continue;
         }
         $tokens->removeLeadingWhitespace($index);
         $token->clear();
     }
 }
 /**
  * {@inheritdoc}
  */
 public function fix(\SplFileInfo $file, Tokens $tokens)
 {
     $end = $tokens->count() - 1;
     foreach (self::$functions as $map) {
         // the sequence is the function name, followed by "(" and a quoted string
         $seq = array(array(T_STRING, $map[0]), '(', array(T_CONSTANT_ENCAPSED_STRING));
         $currIndex = 0;
         while (null !== $currIndex) {
             $match = $tokens->findSequence($seq, $currIndex, $end, false);
             // did we find a match?
             if (null === $match) {
                 break;
             }
             // findSequence also returns the tokens, but we're only interested in the indexes, i.e.:
             // 0 => function name,
             // 1 => bracket "("
             // 2 => quoted string passed as 1st parameter
             $match = array_keys($match);
             // advance tokenizer cursor
             $currIndex = $match[2];
             // ensure it's a function call (not a method / static call)
             $prev = $tokens->getPrevMeaningfulToken($match[0]);
             if (null === $prev || $tokens[$prev]->isGivenKind(array(T_OBJECT_OPERATOR, T_DOUBLE_COLON))) {
                 continue;
             }
             // ensure the first parameter is just a string (e.g. has nothing appended)
             $next = $tokens->getNextMeaningfulToken($match[2]);
             if (null === $next || !$tokens[$next]->equalsAny(array(',', ')'))) {
                 continue;
             }
             // convert to PCRE
             $string = substr($tokens[$match[2]]->getContent(), 1, -1);
             $quote = substr($tokens[$match[2]]->getContent(), 0, 1);
             $delim = $this->getBestDelimiter($string);
             $preg = $delim . addcslashes($string, $delim) . $delim . 'D' . $map[2];
             // check if the preg is valid
             if (!$this->checkPreg($preg)) {
                 continue;
             }
             // modify function and argument
             $tokens[$match[2]]->setContent($quote . $preg . $quote);
             $tokens[$match[0]]->setContent($map[1]);
         }
     }
 }
 private function fixArray(Tokens $tokens, $index)
 {
     $tokensAnalyzer = new TokensAnalyzer($tokens);
     if ($tokensAnalyzer->isArrayMultiLine($index)) {
         return;
     }
     $startIndex = $index;
     if ($tokens[$startIndex]->isGivenKind(T_ARRAY)) {
         $startIndex = $tokens->getNextTokenOfKind($startIndex, array('('));
         $endIndex = $tokens->findBlockEnd(Tokens::BLOCK_TYPE_PARENTHESIS_BRACE, $startIndex);
     } else {
         $endIndex = $tokens->findBlockEnd(Tokens::BLOCK_TYPE_ARRAY_SQUARE_BRACE, $startIndex);
     }
     $beforeEndIndex = $tokens->getPrevMeaningfulToken($endIndex);
     $beforeEndToken = $tokens[$beforeEndIndex];
     if ($beforeEndToken->equals(',')) {
         $tokens->removeTrailingWhitespace($beforeEndIndex);
         $beforeEndToken->clear();
     }
 }
Esempio n. 24
0
 /**
  * @param Tokens $tokens
  * @param int    $start  Token index of the opening brace token of the function
  * @param int    $end    Token index of the closing brace token of the function
  */
 private function fixFunction(Tokens $tokens, $start, $end)
 {
     for ($index = $end; $index > $start; --$index) {
         if (!$tokens[$index]->isGivenKind(T_RETURN)) {
             continue;
         }
         $nextAt = $tokens->getNextMeaningfulToken($index);
         if (!$tokens[$nextAt]->equals(';')) {
             continue;
         }
         if ($tokens->getNextMeaningfulToken($nextAt) !== $end) {
             continue;
         }
         $previous = $tokens->getPrevMeaningfulToken($index);
         if ($tokens[$previous]->equalsAny(array(array(T_ELSE), ')'))) {
             continue;
         }
         $tokens->clearTokenAndMergeSurroundingWhitespace($index);
         $tokens->clearTokenAndMergeSurroundingWhitespace($nextAt);
     }
 }
 /**
  * {@inheritdoc}
  */
 public function fix(\SplFileInfo $file, Tokens $tokens)
 {
     $tokensAnalyzer = new TokensAnalyzer($tokens);
     $uses = array_reverse($tokensAnalyzer->getImportUseIndexes());
     foreach ($uses as $index) {
         $endIndex = $tokens->getNextTokenOfKind($index, array(';', array(T_CLOSE_TAG)));
         $previous = $tokens->getPrevMeaningfulToken($endIndex);
         if ($tokens[$previous]->equals('}')) {
             $start = $tokens->findBlockEnd(Tokens::BLOCK_TYPE_CURLY_BRACE, $previous, false);
             $declarationContent = $tokens->generatePartialCode($start + 1, $previous - 1);
             $prefix = '';
             for ($i = $index + 1; $i < $start; ++$i) {
                 $prefix .= $tokens[$i]->getContent();
             }
             $prefix = ' ' . ltrim($prefix);
         } else {
             $declarationContent = $tokens->generatePartialCode($index + 1, $endIndex - 1);
             $prefix = ' ';
         }
         $declarationParts = explode(',', $declarationContent);
         if (1 === count($declarationParts)) {
             continue;
         }
         $declarationContent = array();
         foreach ($declarationParts as $declarationPart) {
             $declarationContent[] = 'use' . $prefix . trim($declarationPart) . ';';
         }
         $declarationContent = implode("\n" . $this->detectIndent($tokens, $index), $declarationContent);
         for ($i = $index; $i < $endIndex; ++$i) {
             $tokens[$i]->clear();
         }
         if ($tokens[$endIndex]->equals(';')) {
             $tokens[$endIndex]->clear();
         }
         $declarationTokens = Tokens::fromCode('<?php ' . $declarationContent);
         $declarationTokens[0]->clear();
         $declarationTokens->clearEmptyTokens();
         $tokens->insertAt($index, $declarationTokens);
     }
 }
Esempio n. 26
0
 /**
  * {@inheritdoc}
  */
 public function fix(\SplFileInfo $file, Tokens $tokens)
 {
     static $nextTokenKinds = null;
     if (null === $nextTokenKinds) {
         $nextTokenKinds = array('?', ';', ',', '(', ')', '[', ']', ':', '<', '>', '+', '-', '*', '/', '%', '&', '^', '|', array(T_IS_SMALLER_OR_EQUAL), array(T_IS_GREATER_OR_EQUAL), array(T_IS_EQUAL), array(T_IS_NOT_EQUAL), array(T_IS_IDENTICAL), array(T_IS_NOT_IDENTICAL), array(T_CLOSE_TAG), array(T_LOGICAL_AND), array(T_LOGICAL_OR), array(T_LOGICAL_XOR), array(T_BOOLEAN_AND), array(T_BOOLEAN_OR), array(T_INC), array(T_DEC), array(T_SL), array(T_SR), array(T_INSTANCEOF), array(T_AS), array(T_DOUBLE_ARROW), array(CT_ARRAY_SQUARE_BRACE_OPEN), array(CT_ARRAY_SQUARE_BRACE_CLOSE), array(CT_BRACE_CLASS_INSTANTIATION_OPEN), array(CT_BRACE_CLASS_INSTANTIATION_CLOSE));
         if (defined('T_POW')) {
             $nextTokenKinds[] = array(T_POW);
         }
         if (defined('T_SPACESHIP')) {
             $nextTokenKinds[] = array(T_SPACESHIP);
         }
     }
     for ($index = $tokens->count() - 3; $index > 0; --$index) {
         $token = $tokens[$index];
         if (!$token->isGivenKind(T_NEW)) {
             continue;
         }
         $nextIndex = $tokens->getNextTokenOfKind($index, $nextTokenKinds);
         $nextToken = $tokens[$nextIndex];
         // entrance into array index syntax - need to look for exit
         while ($nextToken->equals('[')) {
             $nextIndex = $tokens->findBlockEnd(Tokens::BLOCK_TYPE_INDEX_SQUARE_BRACE, $nextIndex) + 1;
             $nextToken = $tokens[$nextIndex];
         }
         // new statement has a gap in it - advance to the next token
         if ($nextToken->isWhitespace()) {
             $nextIndex = $tokens->getNextNonWhitespace($nextIndex);
             $nextToken = $tokens[$nextIndex];
         }
         // new statement with () - nothing to do
         if ($nextToken->equals('(')) {
             continue;
         }
         $meaningBeforeNextIndex = $tokens->getPrevMeaningfulToken($nextIndex);
         $tokens->insertAt($meaningBeforeNextIndex + 1, array(new Token('('), new Token(')')));
     }
 }
 private function fixArray(Tokens $tokens, $index)
 {
     $tokensAnalyzer = new TokensAnalyzer($tokens);
     if (!$tokensAnalyzer->isArrayMultiLine($index)) {
         return;
     }
     $startIndex = $index;
     if ($tokens[$startIndex]->isGivenKind(T_ARRAY)) {
         $startIndex = $tokens->getNextTokenOfKind($startIndex, array('('));
         $endIndex = $tokens->findBlockEnd(Tokens::BLOCK_TYPE_PARENTHESIS_BRACE, $startIndex);
     } else {
         $endIndex = $tokens->findBlockEnd(Tokens::BLOCK_TYPE_ARRAY_SQUARE_BRACE, $startIndex);
     }
     $beforeEndIndex = $tokens->getPrevMeaningfulToken($endIndex);
     $beforeEndToken = $tokens[$beforeEndIndex];
     // if there is some item between braces then add `,` after it
     if ($startIndex !== $beforeEndIndex && !$beforeEndToken->equalsAny(array(',', array(T_END_HEREDOC)))) {
         $tokens->insertAt($beforeEndIndex + 1, new Token(','));
         $endToken = $tokens[$endIndex];
         if (!$endToken->isComment() && !$endToken->isWhitespace()) {
             $tokens->ensureWhitespaceAtIndex($endIndex, 1, ' ');
         }
     }
 }
 /**
  * @param Tokens $tokens
  * @param int    $index  Index of "="
  *
  * @return bool
  */
 private function isTypehintedNullableVariable(Tokens $tokens, $index)
 {
     $nextToken = $tokens[$tokens->getNextMeaningfulToken($index)];
     if (!$nextToken->equals(array(T_STRING, 'null'), false)) {
         return false;
     }
     $variableIndex = $tokens->getPrevMeaningfulToken($index);
     $searchTokens = array(',', '(', array(T_STRING), array(CT::T_ARRAY_TYPEHINT));
     $typehintKinds = array(T_STRING, CT::T_ARRAY_TYPEHINT);
     if (defined('T_CALLABLE')) {
         $searchTokens[] = array(T_CALLABLE);
         $typehintKinds[] = T_CALLABLE;
     }
     $prevIndex = $tokens->getPrevTokenOfKind($variableIndex, $searchTokens);
     return $tokens[$prevIndex]->isGivenKind($typehintKinds);
 }
 /**
  * Decide whether or not skip the fix for given class.
  *
  * @param Tokens $tokens
  * @param int    $classIndex
  * @param int    $classOpenIndex
  * @param int    $classCloseIndex
  *
  * @return bool
  */
 private function skipClass(Tokens $tokens, $classIndex, $classOpenIndex, $classCloseIndex)
 {
     $prevToken = $tokens[$tokens->getPrevMeaningfulToken($classIndex)];
     if (!$prevToken->isGivenKind(T_FINAL)) {
         return true;
     }
     for ($index = $classIndex; $index < $classOpenIndex; ++$index) {
         if ($tokens[$index]->isGivenKind(T_EXTENDS)) {
             return true;
         }
     }
     $useIndex = $tokens->getNextTokenOfKind($classIndex, array(array(CT::T_USE_TRAIT)));
     return $useIndex && $useIndex < $classCloseIndex;
 }
 /**
  * Find a function or method matching a given name within certain bounds.
  *
  * @param Tokens $tokens     the Tokens instance
  * @param string $name       the function/Method name
  * @param int    $startIndex the search start index
  * @param int    $endIndex   the search end index
  *
  * @return array|null An associative array, if a match is found:
  *
  *     - nameIndex (int): The index of the function/method name.
  *     - startIndex (int): The index of the function/method start.
  *     - endIndex (int): The index of the function/method end.
  *     - bodyIndex (int): The index of the function/method body.
  *     - modifiers (array): The modifiers as array keys and their index as
  *       the values, e.g. array(T_PUBLIC => 10).
  */
 private function findFunction(Tokens $tokens, $name, $startIndex, $endIndex)
 {
     $function = $tokens->findSequence(array(array(T_FUNCTION), array(T_STRING, $name), '('), $startIndex, $endIndex, false);
     if (null === $function) {
         return;
     }
     // keep only the indexes
     $function = array_keys($function);
     // find previous block, saving method modifiers for later use
     $possibleModifiers = array(T_PUBLIC, T_PROTECTED, T_PRIVATE, T_STATIC, T_ABSTRACT, T_FINAL);
     $modifiers = array();
     $prevBlock = $tokens->getPrevMeaningfulToken($function[0]);
     while (null !== $prevBlock && $tokens[$prevBlock]->isGivenKind($possibleModifiers)) {
         $modifiers[$tokens[$prevBlock]->getId()] = $prevBlock;
         $prevBlock = $tokens->getPrevMeaningfulToken($prevBlock);
     }
     if (isset($modifiers[T_ABSTRACT])) {
         // abstract methods have no body
         $bodyStart = null;
         $funcEnd = $tokens->getNextTokenOfKind($function[2], array(';'));
     } else {
         // find method body start and the end of the function definition
         $bodyStart = $tokens->getNextTokenOfKind($function[2], array('{'));
         $funcEnd = $bodyStart !== null ? $tokens->findBlockEnd(Tokens::BLOCK_TYPE_CURLY_BRACE, $bodyStart) : null;
     }
     return array('nameIndex' => $function[1], 'startIndex' => $prevBlock + 1, 'endIndex' => $funcEnd, 'bodyIndex' => $bodyStart, 'modifiers' => $modifiers);
 }