|
@@ -37,7 +37,13 @@ final class NoUnusedImportsFixer extends AbstractFixer
|
|
$tokensAnalyzer = new TokensAnalyzer($tokens);
|
|
$tokensAnalyzer = new TokensAnalyzer($tokens);
|
|
$namespaceDeclarations = $this->getNamespaceDeclarations($tokens);
|
|
$namespaceDeclarations = $this->getNamespaceDeclarations($tokens);
|
|
$useDeclarationsIndexes = $tokensAnalyzer->getImportUseIndexes();
|
|
$useDeclarationsIndexes = $tokensAnalyzer->getImportUseIndexes();
|
|
|
|
+
|
|
|
|
+ if (0 === count($useDeclarationsIndexes)) {
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+
|
|
$useDeclarations = $this->getNamespaceUseDeclarations($tokens, $useDeclarationsIndexes);
|
|
$useDeclarations = $this->getNamespaceUseDeclarations($tokens, $useDeclarationsIndexes);
|
|
|
|
+ $namespaceDeclarations = $this->getNamespaceDeclarations($tokens);
|
|
$contentWithoutUseDeclarations = $this->generateCodeWithoutPartials($tokens, array_merge($namespaceDeclarations, $useDeclarations));
|
|
$contentWithoutUseDeclarations = $this->generateCodeWithoutPartials($tokens, array_merge($namespaceDeclarations, $useDeclarations));
|
|
$useUsages = $this->detectUseUsages($contentWithoutUseDeclarations, $useDeclarations);
|
|
$useUsages = $this->detectUseUsages($contentWithoutUseDeclarations, $useDeclarations);
|
|
|
|
|
|
@@ -45,6 +51,14 @@ final class NoUnusedImportsFixer extends AbstractFixer
|
|
$this->removeUsesInSameNamespace($tokens, $useDeclarations, $namespaceDeclarations);
|
|
$this->removeUsesInSameNamespace($tokens, $useDeclarations, $namespaceDeclarations);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ /**
|
|
|
|
+ * {@inheritdoc}
|
|
|
|
+ */
|
|
|
|
+ public function getDescription()
|
|
|
|
+ {
|
|
|
|
+ return 'Unused use statements must be removed.';
|
|
|
|
+ }
|
|
|
|
+
|
|
/**
|
|
/**
|
|
* {@inheritdoc}
|
|
* {@inheritdoc}
|
|
*/
|
|
*/
|
|
@@ -70,13 +84,11 @@ final class NoUnusedImportsFixer extends AbstractFixer
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
/**
|
|
- * {@inheritdoc}
|
|
|
|
|
|
+ * @param string $content
|
|
|
|
+ * @param array $useDeclarations
|
|
|
|
+ *
|
|
|
|
+ * @return array
|
|
*/
|
|
*/
|
|
- public function getDescription()
|
|
|
|
- {
|
|
|
|
- return 'Unused use statements must be removed.';
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
private function detectUseUsages($content, array $useDeclarations)
|
|
private function detectUseUsages($content, array $useDeclarations)
|
|
{
|
|
{
|
|
$usages = array();
|
|
$usages = array();
|
|
@@ -88,6 +100,12 @@ final class NoUnusedImportsFixer extends AbstractFixer
|
|
return $usages;
|
|
return $usages;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ /**
|
|
|
|
+ * @param Tokens $tokens
|
|
|
|
+ * @param array $partials
|
|
|
|
+ *
|
|
|
|
+ * @return string
|
|
|
|
+ */
|
|
private function generateCodeWithoutPartials(Tokens $tokens, array $partials)
|
|
private function generateCodeWithoutPartials(Tokens $tokens, array $partials)
|
|
{
|
|
{
|
|
$content = '';
|
|
$content = '';
|
|
@@ -122,9 +140,9 @@ final class NoUnusedImportsFixer extends AbstractFixer
|
|
$declarationEndIndex = $tokens->getNextTokenOfKind($index, array(';', '{'));
|
|
$declarationEndIndex = $tokens->getNextTokenOfKind($index, array(';', '{'));
|
|
|
|
|
|
$namespaces[] = array(
|
|
$namespaces[] = array(
|
|
- 'end' => $declarationEndIndex,
|
|
|
|
'name' => trim($tokens->generatePartialCode($index + 1, $declarationEndIndex - 1)),
|
|
'name' => trim($tokens->generatePartialCode($index + 1, $declarationEndIndex - 1)),
|
|
'start' => $index,
|
|
'start' => $index,
|
|
|
|
+ 'end' => $declarationEndIndex,
|
|
);
|
|
);
|
|
}
|
|
}
|
|
|
|
|
|
@@ -136,12 +154,12 @@ final class NoUnusedImportsFixer extends AbstractFixer
|
|
$uses = array();
|
|
$uses = array();
|
|
|
|
|
|
foreach ($useIndexes as $index) {
|
|
foreach ($useIndexes as $index) {
|
|
- $declarationEndIndex = $tokens->getNextTokenOfKind($index, array(';'));
|
|
|
|
|
|
+ $declarationEndIndex = $tokens->getNextTokenOfKind($index, array(';', array(T_CLOSE_TAG)));
|
|
$declarationContent = $tokens->generatePartialCode($index + 1, $declarationEndIndex - 1);
|
|
$declarationContent = $tokens->generatePartialCode($index + 1, $declarationEndIndex - 1);
|
|
-
|
|
|
|
- // ignore multiple use statements like: `use BarB, BarC as C, BarD;`
|
|
|
|
- // that should be split into few separate statements
|
|
|
|
- if (false !== strpos($declarationContent, ',')) {
|
|
|
|
|
|
+ if (
|
|
|
|
+ false !== strpos($declarationContent, ',') // ignore multiple use statements that should be split into few separate statements (for example: `use BarB, BarC as C;`)
|
|
|
|
+ || false !== strpos($declarationContent, '{') // do not touch group use declarations until the logic of this is added (for example: `use some\a\{ClassD};`)
|
|
|
|
+ ) {
|
|
continue;
|
|
continue;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -153,8 +171,7 @@ final class NoUnusedImportsFixer extends AbstractFixer
|
|
$shortName = end($declarationParts);
|
|
$shortName = end($declarationParts);
|
|
$aliased = false;
|
|
$aliased = false;
|
|
} else {
|
|
} else {
|
|
- $fullName = $declarationParts[0];
|
|
|
|
- $shortName = $declarationParts[1];
|
|
|
|
|
|
+ list($fullName, $shortName) = $declarationParts;
|
|
$declarationParts = explode('\\', $fullName);
|
|
$declarationParts = explode('\\', $fullName);
|
|
$aliased = $shortName !== end($declarationParts);
|
|
$aliased = $shortName !== end($declarationParts);
|
|
}
|
|
}
|
|
@@ -162,11 +179,11 @@ final class NoUnusedImportsFixer extends AbstractFixer
|
|
$shortName = trim($shortName);
|
|
$shortName = trim($shortName);
|
|
|
|
|
|
$uses[$shortName] = array(
|
|
$uses[$shortName] = array(
|
|
- 'aliased' => $aliased,
|
|
|
|
- 'end' => $declarationEndIndex,
|
|
|
|
'fullName' => trim($fullName),
|
|
'fullName' => trim($fullName),
|
|
'shortName' => $shortName,
|
|
'shortName' => $shortName,
|
|
|
|
+ 'aliased' => $aliased,
|
|
'start' => $index,
|
|
'start' => $index,
|
|
|
|
+ 'end' => $declarationEndIndex,
|
|
);
|
|
);
|
|
}
|
|
}
|
|
|
|
|
|
@@ -184,10 +201,14 @@ final class NoUnusedImportsFixer extends AbstractFixer
|
|
|
|
|
|
private function removeUseDeclaration(Tokens $tokens, array $useDeclaration)
|
|
private function removeUseDeclaration(Tokens $tokens, array $useDeclaration)
|
|
{
|
|
{
|
|
- for ($index = $useDeclaration['start']; $index <= $useDeclaration['end']; ++$index) {
|
|
|
|
|
|
+ for ($index = $useDeclaration['start']; $index < $useDeclaration['end']; ++$index) {
|
|
$tokens[$index]->clear();
|
|
$tokens[$index]->clear();
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ if ($tokens[$useDeclaration['end']]->equals(';')) {
|
|
|
|
+ $tokens[$useDeclaration['end']]->clear();
|
|
|
|
+ }
|
|
|
|
+
|
|
$prevToken = $tokens[$useDeclaration['start'] - 1];
|
|
$prevToken = $tokens[$useDeclaration['start'] - 1];
|
|
|
|
|
|
if ($prevToken->isWhitespace()) {
|
|
if ($prevToken->isWhitespace()) {
|
|
@@ -219,12 +240,8 @@ final class NoUnusedImportsFixer extends AbstractFixer
|
|
|
|
|
|
private function removeUsesInSameNamespace(Tokens $tokens, array $useDeclarations, array $namespaceDeclarations)
|
|
private function removeUsesInSameNamespace(Tokens $tokens, array $useDeclarations, array $namespaceDeclarations)
|
|
{
|
|
{
|
|
- if (empty($namespaceDeclarations)) {
|
|
|
|
- return;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
// safeguard for files with multiple namespaces to avoid breaking them until we support this case
|
|
// safeguard for files with multiple namespaces to avoid breaking them until we support this case
|
|
- if (count($namespaceDeclarations) > 1) {
|
|
|
|
|
|
+ if (1 !== count($namespaceDeclarations)) {
|
|
return;
|
|
return;
|
|
}
|
|
}
|
|
|
|
|