/** * @param Tokens|Token[] $tokens * * @return void */ protected function fixContent(Tokens $tokens) { $wrongTokens = [T_FUNCTION, T_OBJECT_OPERATOR, T_NEW]; foreach ($tokens as $index => $token) { $tokenContent = strtolower($token->getContent()); if (strtolower($tokenContent) !== 'php_sapi_name') { continue; } $openingBrace = $tokens->getNextMeaningfulToken($index); if ($openingBrace === null || $tokens[$openingBrace]->getContent() !== '(') { continue; } $closingBrace = $tokens->getNextMeaningfulToken($openingBrace); if ($closingBrace === null || $tokens[$closingBrace]->getContent() !== ')') { continue; } $prevIndex = $tokens->getPrevNonWhitespace($index); if ($prevIndex === null || in_array($tokens[$prevIndex]->getId(), $wrongTokens, true)) { continue; } $tokens[$index]->setContent('PHP_SAPI'); for ($i = $openingBrace; $i <= $closingBrace; ++$i) { $tokens[$i]->clear(); } } }
/** * {@inheritdoc} */ public function process(Tokens $tokens, Token $token, $index) { if (!$tokens[$index]->equals('(') || !$tokens[$tokens->getNextMeaningfulToken($index)]->equals(array(T_NEW))) { return; } $closeIndex = $tokens->findBlockEnd(Tokens::BLOCK_TYPE_PARENTHESIS_BRACE, $index); if (!$tokens[$tokens->getNextMeaningfulToken($closeIndex)]->isGivenKind(array(T_OBJECT_OPERATOR, T_DOUBLE_COLON))) { return; } $tokens[$index]->override(array(CT_BRACE_CLASS_INSTANTIATION_OPEN, '(')); $tokens[$closeIndex]->override(array(CT_BRACE_CLASS_INSTANTIATION_CLOSE, ')')); }
/** * {@inheritdoc} */ public function fix(\SplFileInfo $file, Tokens $tokens) { $functionyTokens = $this->getFunctionyTokenKinds(); $languageConstructionTokens = $this->getLanguageConstructionTokenKinds(); foreach ($tokens as $index => $token) { // looking for start brace if (!$token->equals('(')) { continue; } // last non-whitespace token $lastTokenIndex = $tokens->getPrevNonWhitespace($index); if (null === $lastTokenIndex) { continue; } // check for ternary operator $endParenthesisIndex = $tokens->findBlockEnd(Tokens::BLOCK_TYPE_PARENTHESIS_BRACE, $index); $nextNonWhiteSpace = $tokens->getNextMeaningfulToken($endParenthesisIndex); if (!empty($nextNonWhiteSpace) && $tokens[$nextNonWhiteSpace]->equals('?') && $tokens[$lastTokenIndex]->isGivenKind($languageConstructionTokens)) { continue; } // check if it is a function call if ($tokens[$lastTokenIndex]->isGivenKind($functionyTokens)) { $this->fixFunctionCall($tokens, $index); } } }
/** * 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'); } } }
/** * Inject into the text placeholders of candidates of vertical alignment. * * @param Tokens $tokens * @param int $startAt * @param int $endAt * * @return array($code, $context_counter) */ private function injectAlignmentPlaceholders(Tokens $tokens, $startAt, $endAt) { for ($index = $startAt; $index < $endAt; ++$index) { $token = $tokens[$index]; if ($token->isGivenKind(array(T_FOREACH, T_FOR, T_WHILE, T_IF, T_SWITCH))) { $index = $tokens->getNextMeaningfulToken($index); $index = $tokens->findBlockEnd(Tokens::BLOCK_TYPE_PARENTHESIS_BRACE, $index); continue; } if ($token->isGivenKind(T_ARRAY)) { // don't use "$tokens->isArray()" here, short arrays are handled in the next case $from = $tokens->getNextMeaningfulToken($index); $until = $tokens->findBlockEnd(Tokens::BLOCK_TYPE_PARENTHESIS_BRACE, $from); $index = $until; ++$this->deepestLevel; ++$this->currentLevel; $this->injectAlignmentPlaceholders($tokens, $from, $until); --$this->currentLevel; continue; } if ($token->isGivenKind(CT_ARRAY_SQUARE_BRACE_OPEN)) { $prevToken = $tokens[$tokens->getPrevMeaningfulToken($index)]; if ($prevToken->isGivenKind(array(T_STRING, T_VARIABLE))) { continue; } $from = $index; $until = $tokens->findBlockEnd(Tokens::BLOCK_TYPE_ARRAY_SQUARE_BRACE, $from); $index = $until; ++$this->deepestLevel; ++$this->currentLevel; $this->injectAlignmentPlaceholders($tokens, $from + 1, $until - 1); --$this->currentLevel; continue; } if ($token->isGivenKind(T_DOUBLE_ARROW)) { $tokenContent = sprintf(self::ALIGNABLE_PLACEHOLDER, $this->currentLevel) . $token->getContent(); $nextToken = $tokens[$index + 1]; if (!$nextToken->isWhitespace()) { $tokenContent .= ' '; } elseif ($nextToken->isWhitespace(" \t")) { $nextToken->setContent(' '); } $token->setContent($tokenContent); continue; } if ($token->equals(';')) { ++$this->deepestLevel; ++$this->currentLevel; continue; } if ($token->equals(',')) { for ($i = $index; $i < $endAt - 1; ++$i) { if ($tokens[$i + 1]->isGivenKind(array(T_ARRAY, CT_ARRAY_SQUARE_BRACE_OPEN)) || false !== strpos($tokens[$i - 1]->getContent(), "\n")) { break; } ++$index; } } } }
/** * {@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; } }
/** * {@inheritdoc} */ public function fix(\SplFileInfo $file, Tokens $tokens) { $namespace = false; $classyName = null; $classyIndex = 0; foreach ($tokens as $index => $token) { if ($token->isGivenKind(T_NAMESPACE)) { if (false !== $namespace) { return; } $namespace = true; } elseif ($token->isClassy()) { if (null !== $classyName) { return; } $classyIndex = $tokens->getNextMeaningfulToken($index); $classyName = $tokens[$classyIndex]->getContent(); } } if (null === $classyName) { return; } if (false !== $namespace) { $filename = basename(strtr($file->getRealPath(), '\\', '/'), '.php'); if ($classyName !== $filename) { $tokens[$classyIndex]->setContent($filename); } } else { $normClass = strtr($classyName, '_', '/'); $filename = substr(strtr($file->getRealPath(), '\\', '/'), -strlen($normClass) - 4, -4); if ($normClass !== $filename && strtolower($normClass) === strtolower($filename)) { $tokens[$classyIndex]->setContent(strtr($filename, '/', '_')); } } }
/** * @param Tokens|Token[] $tokens * * @return void */ protected function fixContent(Tokens $tokens) { foreach ($tokens as $index => $token) { if ($token->isGivenKind([T_FUNCTION])) { $openingBraceIndex = $tokens->getNextTokenOfKind($index, ['{']); if ($openingBraceIndex === null) { $openingBracketIndex = $tokens->getNextTokenOfKind($index, ['(']); $closingBracketIndex = $tokens->getNextTokenOfKind($index, [')']); $nextIndex = $tokens->getNextMeaningfulToken($closingBracketIndex); if (!$this->isEmptyLineAfterIndex($tokens, $nextIndex)) { $tokens[$nextIndex + 1]->setContent("\n" . $tokens[$nextIndex + 1]->getContent()); } continue; } $closingBraceIndex = $tokens->findBlockEnd(Tokens::BLOCK_TYPE_CURLY_BRACE, $openingBraceIndex); // Ignore closures $nextIndex = $tokens->getNextMeaningfulToken($closingBraceIndex); if ($tokens[$nextIndex]->equals(';') || $tokens[$nextIndex]->equals(',') || $tokens[$nextIndex]->equals(')')) { continue; } if (!$this->isEmptyLineAfterIndex($tokens, $closingBraceIndex)) { $tokens[$closingBraceIndex + 1]->setContent("\n" . $tokens[$closingBraceIndex + 1]->getContent()); } } } }
/** * @param Tokens|Token[] $tokens * * @return void */ protected function fixContent(Tokens $tokens) { $wrongTokens = [T_FUNCTION, T_OBJECT_OPERATOR, T_NEW]; foreach ($tokens as $index => $token) { $tokenContent = strtolower($token->getContent()); if (empty($tokenContent) || !isset(self::$matching[$tokenContent])) { continue; } $prevIndex = $tokens->getPrevNonWhitespace($index); if (in_array($tokens[$prevIndex]->getId(), $wrongTokens, true)) { continue; } $openingBrace = $tokens->getNextMeaningfulToken($index); if ($tokens[$openingBrace]->getContent() !== '(') { continue; } $closingBrace = $tokens->findBlockEnd(Tokens::BLOCK_TYPE_PARENTHESIS_BRACE, $openingBrace); // Skip for non-trivial cases for ($i = $openingBrace + 1; $i < $closingBrace; ++$i) { if ($tokens[$i]->equals(',')) { continue 2; } } $cast = '(' . self::$matching[$tokenContent] . ')'; $tokens[$index]->setContent($cast); $tokens[$openingBrace]->setContent(''); $tokens[$closingBrace]->setContent(''); } }
/** * @param Tokens $tokens */ private function storeImports(Tokens $tokens, $startIndex, $endIndex) { $this->imports = array(); foreach ($tokens->getImportUseIndexes() as $index) { if ($index < $startIndex || $index > $endIndex) { continue; } $import = ''; while ($index = $tokens->getNextMeaningfulToken($index)) { if ($tokens[$index]->equalsAny(array(';', '{')) || $tokens[$index]->isGivenKind(T_AS)) { break; } $import .= $tokens[$index]->getContent(); } // Imports group (PHP 7 spec) if ($tokens[$index]->equals('{')) { $groupEndIndex = $tokens->findBlockEnd(Tokens::BLOCK_TYPE_CURLY_BRACE, $index); $groupImports = array_map('trim', explode(',', $tokens->generatePartialCode($index + 1, $groupEndIndex - 1))); foreach ($groupImports as $groupImport) { $groupImportParts = array_map('trim', explode(' as ', $groupImport)); if (2 === count($groupImportParts)) { $this->imports[$groupImportParts[1]] = $import . $groupImportParts[0]; } else { $this->imports[] = $import . $groupImport; } } } elseif ($tokens[$index]->isGivenKind(T_AS)) { $aliasIndex = $tokens->getNextMeaningfulToken($index); $alias = $tokens[$aliasIndex]->getContent(); $this->imports[$alias] = $import; } else { $this->imports[] = $import; } } }
/** * {@inheritdoc} */ public function fix(\SplFileInfo $file, Tokens $tokens) { /** @var $token \Symfony\CS\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_NAMESPACE_OPERATOR))) { continue; } } // check mapping hit $tokenContent = strtolower($token->getContent()); if (!isset(self::$aliases[$tokenContent])) { continue; } $token->setContent(self::$aliases[$tokenContent]); } }
public function process(Tokens $tokens) { foreach ($tokens as $index => $token) { if (!$token->equals('$')) { continue; } $openIndex = $tokens->getNextMeaningfulToken($index); if (null === $openIndex) { continue; } $openToken = $tokens[$openIndex]; if (!$openToken->equals('{')) { continue; } $closeIndex = $tokens->findBlockEnd(Tokens::BLOCK_TYPE_CURLY_BRACE, $openIndex); $closeToken = $tokens[$closeIndex]; $openToken->override(array(CT_DYNAMIC_VAR_BRACE_OPEN, '{', $openToken->getLine())); $closeToken->override(array(CT_DYNAMIC_VAR_BRACE_CLOSE, '}', $closeToken->getLine())); } }
/** * {@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 fix(\SplFileInfo $file, Tokens $tokens) { foreach ($tokens as $index => $token) { if (!$token->isGivenKind(T_ECHO)) { continue; } $nextTokenIndex = $tokens->getNextMeaningfulToken($index); $endTokenIndex = $tokens->getNextTokenOfKind($index, array(';', array(T_CLOSE_TAG))); $canBeConverted = true; for ($i = $nextTokenIndex; $i < $endTokenIndex; ++$i) { if ($tokens[$i]->equalsAny(array('(', array(CT_ARRAY_SQUARE_BRACE_OPEN)))) { $blockType = $tokens->detectBlockType($tokens[$i]); $i = $tokens->findBlockEnd($blockType['type'], $i); } if ($tokens[$i]->equals(',')) { $canBeConverted = false; break; } } if (false === $canBeConverted) { continue; } $tokens->overrideAt($index, array(T_PRINT, 'print')); } }
/** * {@inheritdoc} */ public function fix(\SplFileInfo $file, Tokens $tokens) { $tokensAnalyzer = new TokensAnalyzer($tokens); foreach ($tokensAnalyzer->getImportUseIndexes() as $index) { $indent = ''; // if previous line ends with comment and current line starts with whitespace, use current indent if ($tokens[$index - 1]->isWhitespace(" \t") && $tokens[$index - 2]->isGivenKind(T_COMMENT)) { $indent = $tokens[$index - 1]->getContent(); } elseif ($tokens[$index - 1]->isWhitespace()) { $indent = Utils::calculateTrailingWhitespaceIndent($tokens[$index - 1]); } $newline = "\n"; // Handle insert index for inline T_COMMENT with whitespace after semicolon $semicolonIndex = $tokens->getNextTokenOfKind($index, array(';', '{')); $insertIndex = $semicolonIndex + 1; if ($tokens[$insertIndex]->isWhitespace(" \t") && $tokens[$insertIndex + 1]->isComment()) { ++$insertIndex; } // Increment insert index for inline T_COMMENT or T_DOC_COMMENT if ($tokens[$insertIndex]->isComment()) { ++$insertIndex; } $afterSemicolon = $tokens->getNextMeaningfulToken($semicolonIndex); if (!$tokens[$afterSemicolon]->isGivenKind(T_USE)) { $newline .= "\n"; } if ($tokens[$insertIndex]->isWhitespace()) { $nextToken = $tokens[$insertIndex]; $nextToken->setContent($newline . $indent . ltrim($nextToken->getContent())); } elseif ($newline && $indent) { $tokens->insertAt($insertIndex, new Token(array(T_WHITESPACE, $newline . $indent))); } } }
private function isValidVariable(Tokens $tokens, Token $docsToken, $variableIndex) { $nextIndex = $tokens->getNextMeaningfulToken($variableIndex); if (!$tokens[$nextIndex]->equals('=')) { return false; } return false !== strpos($docsToken->getContent(), $tokens[$variableIndex]->getContent()); }
public function process(Tokens $tokens) { foreach ($tokens->findGivenKind(T_ARRAY) as $index => $token) { $nextIndex = $tokens->getNextMeaningfulToken($index); $nextToken = $tokens[$nextIndex]; if (!$nextToken->equals('(')) { $token->override(array(CT_ARRAY_TYPEHINT, $token->getContent(), $token->getLine())); } } }
/** * {@inheritdoc} */ public function process(Tokens $tokens, Token $token, $index) { if (!$token->isGivenKind(T_ARRAY)) { return; } $nextIndex = $tokens->getNextMeaningfulToken($index); $nextToken = $tokens[$nextIndex]; if (!$nextToken->equals('(')) { $token->override(array(CT_ARRAY_TYPEHINT, $token->getContent())); } }
private function fixAssert(array $map, Tokens $tokens, $index, $method) { $sequence = $tokens->findSequence(array(array(T_VARIABLE, '$this'), array(T_OBJECT_OPERATOR, '->'), array(T_STRING, $method), '('), $index); if (null === $sequence) { return; } $sequenceIndexes = array_keys($sequence); $sequenceIndexes[4] = $tokens->getNextMeaningfulToken($sequenceIndexes[3]); $firstParameterToken = $tokens[$sequenceIndexes[4]]; if (!$firstParameterToken->isNativeConstant()) { return; } $sequenceIndexes[5] = $tokens->getNextMeaningfulToken($sequenceIndexes[4]); if (!$tokens[$sequenceIndexes[5]]->equals(',')) { return; } $tokens[$sequenceIndexes[2]]->setContent($map[$firstParameterToken->getContent()]); $tokens->clearRange($sequenceIndexes[4], $tokens->getNextNonWhitespace($sequenceIndexes[5]) - 1); return $sequenceIndexes[5]; }
private function findIncludies(Tokens $tokens) { static $includyTokenKinds = array(T_REQUIRE, T_REQUIRE_ONCE, T_INCLUDE, T_INCLUDE_ONCE); $includies = array(); foreach ($tokens->findGivenKind($includyTokenKinds) as $includyTokens) { foreach ($includyTokens as $index => $token) { $includy = array('begin' => $index, 'braces' => null, 'end' => $tokens->getNextTokenOfKind($index, array(';'))); $nextTokenIndex = $tokens->getNextMeaningfulToken($index); $nextToken = $tokens[$nextTokenIndex]; if ($nextToken->equals('(')) { $braceCloseIndex = $tokens->findBlockEnd(Tokens::BLOCK_TYPE_PARENTHESIS_BRACE, $nextTokenIndex); if ($tokens[$tokens->getNextMeaningfulToken($braceCloseIndex)]->equals(';')) { $includy['braces'] = array('open' => $nextTokenIndex, 'close' => $braceCloseIndex); } } $includies[] = $includy; } } return $includies; }
/** * {@inheritdoc} */ public function process(Tokens $tokens, Token $token, $index) { if (!$token->isGivenKind(T_NAMESPACE)) { return; } $nextIndex = $tokens->getNextMeaningfulToken($index); $nextToken = $tokens[$nextIndex]; if ($nextToken->equals(array(T_NS_SEPARATOR))) { $token->override(array(CT_NAMESPACE_OPERATOR, $token->getContent())); } }
/** * Does the return statement located at a given index need fixing? * * @param Tokens $tokens * @param int $index * * @return bool */ private function needFixing(Tokens $tokens, $index) { $content = ''; while (!$tokens[$index]->equals(';')) { $index = $tokens->getNextMeaningfulToken($index); $content .= $tokens[$index]->getContent(); } $content = rtrim($content, ';'); $content = ltrim($content, '('); $content = rtrim($content, ')'); return 'null' === $content; }
/** * @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); } }
private function findIncludies(Tokens $tokens) { static $includyTokenKinds = array(T_REQUIRE, T_REQUIRE_ONCE, T_INCLUDE, T_INCLUDE_ONCE); $includies = array(); foreach ($tokens->findGivenKind($includyTokenKinds) as $includyTokens) { foreach ($includyTokens as $index => $token) { $includy = array('begin' => $index, 'braces' => null, 'end' => $tokens->getNextTokenOfKind($index, array(';'))); $nextTokenIndex = $tokens->getNextMeaningfulToken($index); $nextToken = $tokens[$nextTokenIndex]; if ($nextToken->equals('(')) { // Don't remove braces when the statement is wrapped. // Include is also legal as function parameter or condition statement but requires being wrapped then. $braceCloseIndex = $tokens->findBlockEnd(Tokens::BLOCK_TYPE_PARENTHESIS_BRACE, $nextTokenIndex); if ($tokens[$tokens->getNextMeaningfulToken($braceCloseIndex)]->equals(';')) { $includy['braces'] = array('open' => $nextTokenIndex, 'close' => $braceCloseIndex); } } $includies[] = $includy; } } return $includies; }
private function fixAssertSame(Tokens $tokens, $index) { static $map = array('false' => 'assertFalse', 'null' => 'assertNull', 'true' => 'assertTrue'); $sequence = $tokens->findSequence(array(array(T_VARIABLE, '$this'), array(T_OBJECT_OPERATOR, '->'), array(T_STRING, 'assertSame'), '('), $index); if (null === $sequence) { return; } $sequenceIndexes = array_keys($sequence); $sequenceIndexes[4] = $tokens->getNextMeaningfulToken($sequenceIndexes[3]); $firstParameterToken = $tokens[$sequenceIndexes[4]]; if (!$firstParameterToken->isNativeConstant()) { return; } $sequenceIndexes[5] = $tokens->getNextMeaningfulToken($sequenceIndexes[4]); // return if first method argument is an expression, not value if (!$tokens[$sequenceIndexes[5]]->equals(',')) { return; } $tokens[$sequenceIndexes[2]]->setContent($map[$firstParameterToken->getContent()]); $tokens->clearRange($sequenceIndexes[4], $tokens->getNextNonWhitespace($sequenceIndexes[5]) - 1); return $sequenceIndexes[5]; }
private function fixOptionNames(Tokens $tokens, $fieldNameTokens, $oldName, $newName, $start = 0) { $matchedTokens = $tokens->findSequence(array_merge([[T_OBJECT_OPERATOR], [T_STRING, 'add'], '(', [T_CONSTANT_ENCAPSED_STRING], ','], $fieldNameTokens, [',']), $start); if (null === $matchedTokens) { return; } $matchedTokenIndexes = array_keys($matchedTokens); $isArray = $tokens->isArray($index = $tokens->getNextMeaningfulToken(end($matchedTokenIndexes))); if (!$isArray) { return; } do { $index = $tokens->getNextMeaningfulToken($index); $token = $tokens[$index]; if (!$token->isGivenKind(T_CONSTANT_ENCAPSED_STRING)) { continue; } if ("'{$oldName}'" === $token->getContent()) { $token->setContent("'{$newName}'"); } } while (!in_array($token->getContent(), [')', ']'])); $this->fixOptionNames($tokens, $fieldNameTokens, $oldName, $newName, $index); }
/** * @param Tokens|Token[] $tokens * * @return void */ protected function fixWhitespaceAfterReturnToken(Tokens $tokens) { foreach ($tokens as $index => $token) { if (!$token->isGivenKind([T_RETURN])) { continue; } $nextIndex = $tokens->getNextMeaningfulToken($index); if ($nextIndex <= $index + 1) { continue; } $whitespace = $tokens[$index + 1]; $cleaned = preg_replace('/^[ ]+/', ' ', $whitespace->getContent()); $whitespace->setContent($cleaned); } }
/** * @param Tokens $tokens * @param int $index * * @return int|null */ private function getLastNonDefaultArgumentIndex(Tokens $tokens, $index) { $nextRelevantTokenIndex = $tokens->getNextTokenOfKind($index, $this->variableOrTerminatorTokens); if (null === $nextRelevantTokenIndex) { return; } $lastNonDefaultArgumentIndex = null; while ($tokens[$nextRelevantTokenIndex]->isGivenKind(T_VARIABLE)) { if (!$tokens[$tokens->getNextMeaningfulToken($nextRelevantTokenIndex)]->equals('=') && !$this->isEllipsis($tokens, $nextRelevantTokenIndex)) { $lastNonDefaultArgumentIndex = $nextRelevantTokenIndex; } $nextRelevantTokenIndex = $tokens->getNextTokenOfKind($nextRelevantTokenIndex, $this->variableOrTerminatorTokens); } return $lastNonDefaultArgumentIndex; }
/** * {@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]); } } }