Get indexes of namespace uses.
public getImportUseIndexes ( boolean $perNamespace = false ) : array | array[] | ||
$perNamespace | boolean | Return namespace uses per namespace |
return | array | array[] |
/** * {@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))); } } }
/** * {@inheritdoc} */ public function fix(\SplFileInfo $file, Tokens $tokens) { $tokensAnalyzer = new TokensAnalyzer($tokens); $namespacesImports = $tokensAnalyzer->getImportUseIndexes(true); $usesOrder = array(); if (!count($namespacesImports)) { return; } foreach ($namespacesImports as $uses) { $uses = array_reverse($uses); $usesOrder = array_replace($usesOrder, $this->getNewOrder($uses, $tokens)); } $usesOrder = array_reverse($usesOrder, true); $mapStartToEnd = array(); foreach ($usesOrder as $use) { $mapStartToEnd[$use[1]] = $use[2]; } // Now insert the new tokens, starting from the end foreach ($usesOrder as $index => $use) { $declarationTokens = Tokens::fromCode('<?php use ' . $use[0] . ';'); $declarationTokens->clearRange(0, 2); // clear `<?php use ` $declarationTokens[count($declarationTokens) - 1]->clear(); // clear `;` $declarationTokens->clearEmptyTokens(); $tokens->overrideRange($index, $mapStartToEnd[$index], $declarationTokens); } }
/** * {@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(';')); $declarationContent = $tokens->generatePartialCode($index + 1, $endIndex - 1); $declarationParts = explode(',', $declarationContent); if (1 === count($declarationParts)) { continue; } $declarationContent = array(); foreach ($declarationParts as $declarationPart) { $declarationContent[] = 'use ' . trim($declarationPart) . ';'; } $declarationContent = implode("\n" . $this->detectIndent($tokens, $index), $declarationContent); for ($i = $index; $i <= $endIndex; ++$i) { $tokens[$i]->clear(); } $declarationTokens = Tokens::fromCode('<?php ' . $declarationContent); $declarationTokens[0]->clear(); $declarationTokens->clearEmptyTokens(); $tokens->insertAt($index, $declarationTokens); } }
/** * {@inheritdoc} */ public function fix(\SplFileInfo $file, Tokens $tokens) { $tokensAnalyzer = new TokensAnalyzer($tokens); $namespaceDeclarations = $this->getNamespaceDeclarations($tokens); $useDeclarationsIndexes = $tokensAnalyzer->getImportUseIndexes(); $useDeclarations = $this->getNamespaceUseDeclarations($tokens, $useDeclarationsIndexes); $contentWithoutUseDeclarations = $this->generateCodeWithoutPartials($tokens, array_merge($namespaceDeclarations, $useDeclarations)); $useUsages = $this->detectUseUsages($contentWithoutUseDeclarations, $useDeclarations); $this->removeUnusedUseDeclarations($tokens, $useDeclarations, $useUsages); $this->removeUsesInSameNamespace($tokens, $useDeclarations, $namespaceDeclarations); }
/** * {@inheritdoc} */ public function fix(\SplFileInfo $file, Tokens $tokens) { $ending = $this->whitespacesConfig->getLineEnding(); $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]); } $semicolonIndex = $tokens->getNextTokenOfKind($index, array(';', array(T_CLOSE_TAG))); // Handle insert index for inline T_COMMENT with whitespace after semicolon $insertIndex = $semicolonIndex; if ($tokens[$semicolonIndex]->isGivenKind(T_CLOSE_TAG)) { if ($tokens[$insertIndex - 1]->isWhitespace()) { --$insertIndex; } $tokens->insertAt($insertIndex, new Token(';')); } if ($semicolonIndex === count($tokens) - 1) { $tokens->insertAt($insertIndex + 1, new Token(array(T_WHITESPACE, $ending . $ending . $indent))); } else { $newline = $ending; $tokens[$semicolonIndex]->isGivenKind(T_CLOSE_TAG) ? --$insertIndex : ++$insertIndex; 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 (null === $afterSemicolon || !$tokens[$afterSemicolon]->isGivenKind(T_USE)) { $newline .= $ending; } if ($tokens[$insertIndex]->isWhitespace()) { $nextToken = $tokens[$insertIndex]; $nextMeaningfulAfterUseIndex = $tokens->getNextMeaningfulToken($insertIndex); if (null !== $nextMeaningfulAfterUseIndex && $tokens[$nextMeaningfulAfterUseIndex]->isGivenKind(T_USE)) { if (substr_count($nextToken->getContent(), "\n") < 2) { $nextToken->setContent($newline . $indent . ltrim($nextToken->getContent())); } } else { $nextToken->setContent($newline . $indent . ltrim($nextToken->getContent())); } } else { $tokens->insertAt($insertIndex, new Token(array(T_WHITESPACE, $newline . $indent))); } } } }
/** * {@inheritdoc} */ public function fix(\SplFileInfo $file, Tokens $tokens) { $tokensAnalyzer = new TokensAnalyzer($tokens); $namespacesImports = $tokensAnalyzer->getImportUseIndexes(true); if (!count($namespacesImports)) { return; } foreach ($namespacesImports as $uses) { $uses = array_reverse($uses); $this->fixLineBreaksPerImportGroup($tokens, $uses); } }
/** * {@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) { $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(); } } }
/** * {@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); } }
/** * {@inheritdoc} */ public function fix(\SplFileInfo $file, Tokens $tokens) { $tokensAnalyzer = new TokensAnalyzer($tokens); $namespacesImports = $tokensAnalyzer->getImportUseIndexes(true); if (0 === count($namespacesImports)) { return; } $usesOrder = array(); foreach ($namespacesImports as $uses) { $usesOrder = array_replace($usesOrder, $this->getNewOrder(array_reverse($uses), $tokens)); } $usesOrder = array_reverse($usesOrder, true); $mapStartToEnd = array(); foreach ($usesOrder as $use) { $mapStartToEnd[$use['startIndex']] = $use['endIndex']; } // Now insert the new tokens, starting from the end foreach ($usesOrder as $index => $use) { $declarationTokens = Tokens::fromCode('<?php use ' . $use['namespace'] . ';'); $declarationTokens->clearRange(0, 2); // clear `<?php use ` $declarationTokens[count($declarationTokens) - 1]->clear(); // clear `;` $declarationTokens->clearEmptyTokens(); $tokens->overrideRange($index, $mapStartToEnd[$index], $declarationTokens); if ($use['group']) { // a group import must start with `use` and cannot be part of comma separated import list $prev = $tokens->getPrevMeaningfulToken($index); if ($tokens[$prev]->equals(',')) { $tokens[$prev]->setContent(';'); $tokens->insertAt($prev + 1, new Token(array(T_USE, 'use'))); if (!$tokens[$prev + 2]->isWhitespace()) { $tokens->insertAt($prev + 2, new Token(array(T_WHITESPACE, ' '))); } } } } }
/** * @param Tokens $tokens */ private function storeImports(Tokens $tokens, $startIndex, $endIndex) { $tokensAnalyzer = new TokensAnalyzer($tokens); $this->imports = array(); foreach ($tokensAnalyzer->getImportUseIndexes() as $index) { if ($index < $startIndex || $index > $endIndex) { continue; } $import = ''; while ($index = $tokens->getNextMeaningfulToken($index)) { if ($tokens[$index]->equalsAny(array(';', array(CT::T_GROUP_IMPORT_BRACE_OPEN))) || $tokens[$index]->isGivenKind(T_AS)) { break; } $import .= $tokens[$index]->getContent(); } // Imports group (PHP 7 spec) if ($tokens[$index]->isGivenKind(CT::T_GROUP_IMPORT_BRACE_OPEN)) { $groupEndIndex = $tokens->findBlockEnd(Tokens::BLOCK_TYPE_GROUP_IMPORT_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; } } }
/** * @dataProvider getImportUseIndexesCasesPHP70 * @requires PHP 7.0 */ public function testGetImportUseIndexesPHP70(array $expected, $input, $perNamespace = false) { $tokens = Tokens::fromCode($input); $tokensAnalyzer = new TokensAnalyzer($tokens); $this->assertSame($expected, $tokensAnalyzer->getImportUseIndexes($perNamespace)); }