/** * {@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->getNextNonWhitespace($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, '/', '_')); } } }
/** * Replace all `else if` (T_ELSE T_IF) with `elseif` (T_ELSEIF). * * {@inheritdoc} */ public function fix(\SplFileInfo $file, Tokens $tokens) { foreach ($tokens as $index => $token) { if (!$token->isGivenKind(T_ELSE)) { continue; } $nextIndex = $tokens->getNextNonWhitespace($index); $nextToken = $tokens[$nextIndex]; // if next meaning token is not T_IF - continue searching, this is not the case for fixing if (!$nextToken->isGivenKind(T_IF)) { continue; } // now we have T_ELSE following by T_IF so we could fix this // 1. clear whitespaces between T_ELSE and T_IF $tokens[$index + 1]->clear(); // 2. change token from T_ELSE into T_ELSEIF $tokens->overrideAt($index, array(T_ELSEIF, 'elseif')); // 3. clear succeeding T_IF $nextToken->clear(); } # handle `T_ELSE T_WHITESPACE T_IF` treated as single `T_ELSEIF` by HHVM # see https://github.com/facebook/hhvm/issues/4796 if (defined('HHVM_VERSION')) { foreach ($tokens->findGivenKind(T_ELSEIF) as $token) { $token->setContent('elseif'); } } }
private function clearIncludies(Tokens $tokens, array $includies) { foreach (array_reverse($includies) as $includy) { if ($includy['end']) { $tokens->removeLeadingWhitespace($includy['end']); } $braces = $includy['braces']; if ($braces) { $nextToken = $tokens[$tokens->getNextNonWhitespace($includy['braces']['close'])]; if ($nextToken->equals(';')) { $tokens->removeLeadingWhitespace($braces['open']); $tokens->removeTrailingWhitespace($braces['open']); $tokens->removeLeadingWhitespace($braces['close']); $tokens->removeTrailingWhitespace($braces['close']); $tokens[$braces['open']] = new Token(array(T_WHITESPACE, ' ')); $tokens[$braces['close']]->clear(); } } $nextIndex = $includy['begin'] + 1; $nextToken = $tokens[$nextIndex]; while ($nextToken->isEmpty()) { $nextToken = $tokens[++$nextIndex]; } if ($nextToken->isWhitespace()) { $nextToken->setContent(' '); } elseif ($braces) { $tokens->insertAt($includy['begin'] + 1, new Token(array(T_WHITESPACE, ' '))); } } }
/** * {@inheritdoc} */ public function fix(\SplFileInfo $file, Tokens $tokens) { for ($index = $tokens->count() - 1; $index >= 0; --$index) { $token = $tokens[$index]; if (!$token->isGivenKind(T_NEW)) { continue; } $nextIndex = $tokens->getNextTokenOfKind($index, array(':', ';', ',', '(', ')', '[', ']', 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->isGivenKind(T_WHITESPACE)) { $nextIndex = $tokens->getNextNonWhitespace($nextIndex); $nextToken = $tokens[$nextIndex]; } // new statement with () - nothing to do if ($nextToken->equals('(')) { continue; } $meaningBeforeNextIndex = $tokens->getPrevNonWhitespace($nextIndex); $tokens->insertAt($meaningBeforeNextIndex + 1, array(new Token('('), new Token(')'))); } }
private function findHeaderCommentInsertionIndex(Tokens $tokens) { $index = $tokens->getNextNonWhitespace(0); if (null === $index) { $index = $tokens->getSize(); } return $index; }
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->getNextNonWhitespace($sequenceIndexes[4]); $tokens[$sequenceIndexes[2]]->setContent($map[$firstParameterToken->getContent()]); $tokens->clearRange($sequenceIndexes[4], $tokens->getNextNonWhitespace($sequenceIndexes[5]) - 1); return $sequenceIndexes[5]; }
/** * Fix the line breaks per group. * * For each use token reach the nearest ; and ensure every * token after has one \n before next non empty token (next line). * It skips the first pass from the bottom. * * @param Tokens $tokens * @param array $uses */ private function fixLineBreaksPerImportGroup(Tokens $tokens, array $uses) { foreach ($uses as $index) { $endIndex = $tokens->getNextTokenOfKind($index, array(';')); $afterSemicolonIndex = $tokens->getNextNonWhitespace($endIndex); if (null !== $afterSemicolonIndex && !$tokens[$afterSemicolonIndex]->isGivenKind(T_USE)) { continue; } $nextToken = $tokens[$endIndex + 1]; if ($nextToken->isWhitespace()) { $nextToken->setContent(preg_replace('/\\n{2,}/', "\n", $nextToken->getContent())); } } }
/** * {@inheritdoc} */ public function fix(\SplFileInfo $file, Tokens $tokens) { foreach ($tokens as $index => $token) { if (!$token->equals('.')) { continue; } if (!$tokens[$tokens->getPrevNonWhitespace($index)]->isGivenKind(T_LNUMBER)) { $tokens->removeLeadingWhitespace($index, " \t"); } if (!$tokens[$tokens->getNextNonWhitespace($index)]->isGivenKind(T_LNUMBER)) { $tokens->removeTrailingWhitespace($index, " \t"); } } }
/** * @param Tokens $tokens * * @throws ExtractionException * * @return string */ public function extract(Tokens $tokens) { $classyName = null; foreach ($tokens as $index => $token) { if ($token->isClassy()) { $classyIndex = $tokens->getNextNonWhitespace($index); $classyName = $tokens[$classyIndex]->getContent(); } } if (null === $classyName) { throw new ExtractionException('No way to parse class name of this class'); } return $classyName; }
/** * {@inheritdoc} */ public function fix(\SplFileInfo $file, Tokens $tokens) { static $forbiddenSuccessors = array(T_DOC_COMMENT, T_COMMENT, T_WHITESPACE, T_RETURN, T_THROW, T_GOTO, T_CONTINUE, T_BREAK); foreach ($tokens as $index => $token) { if (!$token->isGivenKind(T_DOC_COMMENT)) { continue; } // get the next non-whitespace token inc comments, provided // that there is whitespace between it and the current token $next = $tokens->getNextNonWhitespace($index); if ($index + 2 === $next && false === $tokens[$next]->isGivenKind($forbiddenSuccessors)) { $this->fixWhitespace($tokens[$index + 1]); } } }
/** * @param Tokens $tokens * * @throws ExtractionException * * @return string */ public function extract(Tokens $tokens) { $namespace = null; foreach ($tokens as $index => $token) { if ($token->isGivenKind(T_NAMESPACE)) { $namespaceIndex = $tokens->getNextNonWhitespace($index); $namespaceEndIndex = $tokens->getNextTokenOfKind($index, array(';')); $namespace = trim($tokens->generatePartialCode($namespaceIndex, $namespaceEndIndex - 1)); } } if (null === $namespace) { throw new ExtractionException('No way to parse the namespace of this class'); } return $namespace; }
/** * {@inheritdoc} */ public function fix(\SplFileInfo $file, Tokens $tokens) { $tokensAnalyzer = new TokensAnalyzer($tokens); for ($index = $tokens->count() - 1; $index >= 0; --$index) { $token = $tokens[$index]; if (!$token->isGivenKind(T_FUNCTION)) { continue; } $startParenthesisIndex = $tokens->getNextTokenOfKind($index, array('(')); $endParenthesisIndex = $tokens->findBlockEnd(Tokens::BLOCK_TYPE_PARENTHESIS_BRACE, $startParenthesisIndex); $startBraceIndex = $tokens->getNextTokenOfKind($endParenthesisIndex, array(';', '{')); $startBraceToken = $tokens[$startBraceIndex]; if ($startBraceToken->equals('{')) { // fix single-line whitespace before { // eg: `function foo(){}` => `function foo() {}` // eg: `function foo() {}` => `function foo() {}` if (!$tokens[$startBraceIndex - 1]->isWhitespace() || $tokens[$startBraceIndex - 1]->isWhitespace($this->singleLineWhitespaceOptions)) { $tokens->ensureWhitespaceAtIndex($startBraceIndex - 1, 1, ' '); } } $afterParenthesisIndex = $tokens->getNextNonWhitespace($endParenthesisIndex); $afterParenthesisToken = $tokens[$afterParenthesisIndex]; if ($afterParenthesisToken->isGivenKind(CT_USE_LAMBDA)) { $useStartParenthesisIndex = $tokens->getNextTokenOfKind($afterParenthesisIndex, array('(')); $useEndParenthesisIndex = $tokens->findBlockEnd(Tokens::BLOCK_TYPE_PARENTHESIS_BRACE, $useStartParenthesisIndex); // fix whitespace after CT_USE_LAMBDA $tokens->ensureWhitespaceAtIndex($afterParenthesisIndex + 1, 0, ' '); // remove single-line edge whitespaces inside use parentheses $this->fixParenthesisInnerEdge($tokens, $useStartParenthesisIndex, $useEndParenthesisIndex); // fix whitespace before CT_USE_LAMBDA $tokens->ensureWhitespaceAtIndex($afterParenthesisIndex - 1, 1, ' '); } // remove single-line edge whitespaces inside parameters list parentheses $this->fixParenthesisInnerEdge($tokens, $startParenthesisIndex, $endParenthesisIndex); if (!$tokensAnalyzer->isLambda($index)) { // remove whitespace before ( // eg: `function foo () {}` => `function foo() {}` if ($tokens[$startParenthesisIndex - 1]->isWhitespace()) { $tokens[$startParenthesisIndex - 1]->clear(); } } // fix whitespace after T_FUNCTION // eg: `function foo() {}` => `function foo() {}` $tokens->ensureWhitespaceAtIndex($index + 1, 0, ' '); } }
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]; }
/** * {@inheritdoc} */ public function fix(\SplFileInfo $file, Tokens $tokens) { $foundNamespace = $tokens->findGivenKind(T_NAMESPACE); if (empty($foundNamespace)) { return; } $tokensAnalyzer = new TokensAnalyzer($tokens); $firstNamespaceIdx = key($foundNamespace); $usesIdxs = $tokensAnalyzer->getImportUseIndexes(); foreach ($usesIdxs as $idx) { if ($idx < $firstNamespaceIdx) { continue; } $nextTokenIdx = $tokens->getNextNonWhitespace($idx); $nextToken = $tokens[$nextTokenIdx]; if ($nextToken->isGivenKind(T_NS_SEPARATOR)) { $nextToken->clear(); } } }
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(';'))); // Don't remove when the statement is wrapped. include is also legal as function parameter // but requires being wrapped then if (!$tokens[$tokens->getPrevNonWhitespace($index)]->equals('(')) { $nextTokenIndex = $tokens->getNextNonWhitespace($index); $nextToken = $tokens[$nextTokenIndex]; if ($nextToken->equals('(')) { $includy['braces'] = array('open' => $nextTokenIndex, 'close' => $tokens->findBlockEnd(Tokens::BLOCK_TYPE_PARENTHESIS_BRACE, $nextTokenIndex)); } } $includies[] = $includy; } } return $includies; }
/** * Replace all `else if` (T_ELSE T_IF) with `elseif` (T_ELSEIF). * * {@inheritdoc} */ public function fix(\SplFileInfo $file, Tokens $tokens) { foreach ($tokens as $index => $token) { if (!$token->isGivenKind(T_ELSE)) { continue; } $nextIndex = $tokens->getNextNonWhitespace($index); $nextToken = $tokens[$nextIndex]; // if next meaning token is not T_IF - continue searching, this is not the case for fixing if (!$nextToken->isGivenKind(T_IF)) { continue; } // now we have T_ELSE following by T_IF so we could fix this // 1. clear whitespaces between T_ELSE and T_IF $tokens[$index + 1]->clear(); // 2. change token from T_ELSE into T_ELSEIF $tokens->overrideAt($index, array(T_ELSEIF, 'elseif')); // 3. clear succeeding T_IF $nextToken->clear(); } }
/** * Method to trim leading/trailing whitespace within single line arrays. * * @param Tokens $tokens * @param int $index */ private static function fixArray(Tokens $tokens, $index) { $startIndex = $index; if ($tokens[$startIndex]->isGivenKind(T_ARRAY)) { $startIndex = $tokens->getNextMeaningfulToken($startIndex); $endIndex = $tokens->findBlockEnd(Tokens::BLOCK_TYPE_PARENTHESIS_BRACE, $startIndex); } else { $endIndex = $tokens->findBlockEnd(Tokens::BLOCK_TYPE_ARRAY_SQUARE_BRACE, $startIndex); } $nextToken = $tokens[$startIndex + 1]; $nextNonWhitespaceIndex = $tokens->getNextNonWhitespace($startIndex); $nextNonWhitespaceToken = $tokens[$nextNonWhitespaceIndex]; $tokenAfterNextNonWhitespaceToken = $tokens[$nextNonWhitespaceIndex + 1]; $prevToken = $tokens[$endIndex - 1]; $prevNonWhitespaceIndex = $tokens->getPrevNonWhitespace($endIndex); $prevNonWhitespaceToken = $tokens[$prevNonWhitespaceIndex]; if ($nextToken->isWhitespace(" \t") && (!$nextNonWhitespaceToken->isComment() || $nextNonWhitespaceIndex === $prevNonWhitespaceIndex || $tokenAfterNextNonWhitespaceToken->isWhitespace(" \t") || '/*' === substr($nextNonWhitespaceToken->getContent(), 0, 2))) { $nextToken->clear(); } if ($prevToken->isWhitespace(" \t") && !$prevNonWhitespaceToken->equals(',')) { $prevToken->clear(); } }
private static function fixArray(Tokens $tokens, $index) { static $whitespaceOptions = array('whitespaces' => " \t"); $startIndex = $index; if ($tokens[$startIndex]->isGivenKind(T_ARRAY)) { $startIndex = $tokens->getNextMeaningfulToken($startIndex); $endIndex = $tokens->findBlockEnd(Tokens::BLOCK_TYPE_PARENTHESIS_BRACE, $startIndex); } else { $endIndex = $tokens->findBlockEnd(Tokens::BLOCK_TYPE_SQUARE_BRACE, $startIndex); } $nextToken = $tokens[$startIndex + 1]; $nextNonWhitespaceIndex = $tokens->getNextNonWhitespace($startIndex); $nextNonWhitespaceToken = $tokens[$nextNonWhitespaceIndex]; $prevToken = $tokens[$endIndex - 1]; $prevNonWhitespaceIndex = $tokens->getPrevNonWhitespace($endIndex); $prevNonWhitespaceToken = $tokens[$prevNonWhitespaceIndex]; if ($nextToken->isWhitespace($whitespaceOptions) && (!$nextNonWhitespaceToken->isComment() || $nextNonWhitespaceIndex === $prevNonWhitespaceIndex || false === strpos($nextNonWhitespaceToken->getContent(), "\n"))) { $nextToken->clear(); } if ($prevToken->isWhitespace($whitespaceOptions) && !$prevNonWhitespaceToken->equals(',') && !($prevNonWhitespaceToken->isComment() && $prevNonWhitespaceToken->getContent() !== rtrim($prevNonWhitespaceToken->getContent()))) { $prevToken->clear(); } }
private function fixWhiteSpaceAroundOperator(Tokens $tokens, $index) { // do not change the alignment of `=>` or `=`, see `(un)align_double_arrow`, `(un)align_equals` $preserveAlignment = $tokens[$index]->isGivenKind(T_DOUBLE_ARROW) || $tokens[$index]->equals('='); // fix white space after operator if ($tokens[$index + 1]->isWhitespace()) { $content = $tokens[$index + 1]->getContent(); if (!$preserveAlignment && ' ' !== $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 (!$preserveAlignment && ' ' !== $content && false === strpos($content, "\n") && !$tokens[$tokens->getPrevNonWhitespace($index - 1)]->isComment()) { $tokens[$index - 1]->setContent(' '); } } else { $tokens->insertAt($index, new Token(array(T_WHITESPACE, ' '))); } }
/** * {@inheritdoc} */ public function fix(\SplFileInfo $file, Tokens $tokens) { $ternaryLevel = 0; foreach ($tokens as $index => $token) { if ($token->isArray()) { continue; } if ($token->equals('?')) { ++$ternaryLevel; $nextNonWhitespaceIndex = $tokens->getNextNonWhitespace($index); $nextNonWhitespaceToken = $tokens[$nextNonWhitespaceIndex]; if ($nextNonWhitespaceToken->equals(':')) { // for `$a ?: $b` remove spaces between `?` and `:` if ($tokens[$index + 1]->isWhitespace()) { $tokens[$index + 1]->clear(); } } else { // for `$a ? $b : $c` ensure space after `?` $this->ensureWhitespaceExistance($tokens, $index + 1, true); } // for `$a ? $b : $c` ensure space before `?` $this->ensureWhitespaceExistance($tokens, $index - 1, false); continue; } if ($ternaryLevel && $token->equals(':')) { // for `$a ? $b : $c` ensure space after `:` $this->ensureWhitespaceExistance($tokens, $index + 1, true); $prevNonWhitespaceToken = $tokens[$tokens->getPrevNonWhitespace($index)]; if (!$prevNonWhitespaceToken->equals('?')) { // for `$a ? $b : $c` ensure space before `:` $this->ensureWhitespaceExistance($tokens, $index - 1, false); } --$ternaryLevel; } } }
private function findParenthesisEnd(Tokens $tokens, $structureTokenIndex) { $nextIndex = $tokens->getNextNonWhitespace($structureTokenIndex); $nextToken = $tokens[$nextIndex]; // return if next token is not opening parenthesis if (!$nextToken->equals('(')) { return $structureTokenIndex; } return $tokens->findBlockEnd(Tokens::BLOCK_TYPE_PARENTHESIS_BRACE, $nextIndex); }
/** * @param Tokens $tokens * @param int $classEnd * @param int $methodEnd */ private function fixSpaceBelowMethod(Tokens $tokens, $classEnd, $methodEnd) { $nextNotWhite = $tokens->getNextNonWhitespace($methodEnd); $this->correctLineBreaks($tokens, $methodEnd, $nextNotWhite, $nextNotWhite === $classEnd ? 1 : 2); }
private function findStatementEnd(Tokens $tokens, $parenthesisEndIndex) { $nextIndex = $tokens->getNextNonWhitespace($parenthesisEndIndex); $nextToken = $tokens[$nextIndex]; if (!$nextToken) { return $parenthesisEndIndex; } if ($nextToken->equals('{')) { return $tokens->findBlockEnd(Tokens::BLOCK_TYPE_CURLY_BRACE, $nextIndex); } if ($nextToken->isGivenKind($this->getControlTokens())) { $parenthesisEndIndex = $this->findParenthesisEnd($tokens, $nextIndex); $endIndex = $this->findStatementEnd($tokens, $parenthesisEndIndex); if ($nextToken->isGivenKind(T_IF)) { $nextIndex = $tokens->getNextNonWhitespace($endIndex); $nextToken = $tokens[$nextIndex]; if ($nextToken && $nextToken->isGivenKind($this->getControlContinuationTokens())) { $parenthesisEndIndex = $this->findParenthesisEnd($tokens, $nextIndex); return $this->findStatementEnd($tokens, $parenthesisEndIndex); } } return $endIndex; } $index = $parenthesisEndIndex; while (true) { $token = $tokens[++$index]; if ($token->equals(';')) { break; } } return $index; }
private function findStatementEnd(Tokens $tokens, $parenthesisEndIndex) { $nextIndex = $tokens->getNextNonWhitespace($parenthesisEndIndex); $nextToken = $tokens[$nextIndex]; if (!$nextToken) { return $parenthesisEndIndex; } if ($nextToken->equals('{')) { return $tokens->findBlockEnd(Tokens::BLOCK_TYPE_CURLY_BRACE, $nextIndex); } if ($nextToken->isGivenKind($this->getControlTokens())) { $parenthesisEndIndex = $this->findParenthesisEnd($tokens, $nextIndex); $endIndex = $this->findStatementEnd($tokens, $parenthesisEndIndex); if ($nextToken->isGivenKind(array(T_IF, T_TRY))) { $openingTokenKind = $nextToken->getId(); while (true) { $nextIndex = $tokens->getNextNonWhitespace($endIndex); $nextToken = $tokens[$nextIndex]; if ($nextToken && $nextToken->isGivenKind($this->getControlContinuationTokensForOpeningToken($openingTokenKind))) { $parenthesisEndIndex = $this->findParenthesisEnd($tokens, $nextIndex); $endIndex = $this->findStatementEnd($tokens, $parenthesisEndIndex); if ($nextToken->isGivenKind($this->getFinalControlContinuationTokensForOpeningToken($openingTokenKind))) { return $endIndex; } } else { break; } } } return $endIndex; } $index = $parenthesisEndIndex; while (true) { $token = $tokens[++$index]; // if there is some block in statement (eg lambda function) we need to skip it if ($token->equals('{')) { $index = $tokens->findBlockEnd(Tokens::BLOCK_TYPE_CURLY_BRACE, $index); continue; } if ($token->equals(';')) { return $index; } if ($token->isGivenKind(T_CLOSE_TAG)) { return $tokens->getPrevNonWhitespace($index); } } throw new \RuntimeException('Statement end not found'); }
/** * {@inheritdoc} */ public function fix(\SplFileInfo $file, Tokens $tokens) { $namespace = false; $namespaceIndex = 0; $namespaceEndIndex = 0; $classyName = null; $classyIndex = 0; foreach ($tokens as $index => $token) { if ($token->isGivenKind(T_NAMESPACE)) { if (false !== $namespace) { return; } $namespaceIndex = $tokens->getNextNonWhitespace($index); $namespaceEndIndex = $tokens->getNextTokenOfKind($index, array(';')); $namespace = trim($tokens->generatePartialCode($namespaceIndex, $namespaceEndIndex - 1)); } elseif ($token->isClassy()) { if (null !== $classyName) { return; } $classyIndex = $tokens->getNextNonWhitespace($index); $classyName = $tokens[$classyIndex]->getContent(); } } if (null === $classyName) { return; } if (false !== $namespace) { $normNamespace = strtr($namespace, '\\', '/'); $path = strtr($file->getRealPath(), '\\', '/'); $dir = dirname($path); if ($this->config) { $dir = substr($dir, strlen(realpath($this->config->getDir())) + 1); if (strlen($normNamespace) > strlen($dir)) { if ('' !== $dir) { $normNamespace = substr($normNamespace, -strlen($dir)); } else { $normNamespace = ''; } } } $dir = substr($dir, -strlen($normNamespace)); if (false === $dir) { $dir = ''; } $filename = basename($path, '.php'); if ($classyName !== $filename) { $tokens[$classyIndex]->setContent($filename); } if ($normNamespace !== $dir && strtolower($normNamespace) === strtolower($dir)) { for ($i = $namespaceIndex; $i <= $namespaceEndIndex; ++$i) { $tokens[$i]->clear(); } $namespace = substr($namespace, 0, -strlen($dir)) . strtr($dir, '/', '\\'); $newNamespace = Tokens::fromCode('<?php namespace ' . $namespace . ';'); $newNamespace[0]->clear(); $newNamespace[1]->clear(); $newNamespace[2]->clear(); $newNamespace->clearEmptyTokens(); $tokens->insertAt($namespaceIndex, $newNamespace); } } else { $normClass = strtr($classyName, '_', '/'); $path = strtr($file->getRealPath(), '\\', '/'); $filename = substr($path, -strlen($normClass) - 4, -4); if ($normClass !== $filename && strtolower($normClass) === strtolower($filename)) { $tokens[$classyIndex]->setContent(strtr($filename, '/', '_')); } } }