public function testGetLineSwaps2() { $useStatements = [$this->getMockUseStatement("a\\b\\AClass", 5), $this->getMockUseStatement("a\\b\\BClass", 6), $this->getMockUseStatement("a\\b\\CClass", 8), $this->getMockUseStatement("a\\b\\DClass", 9), $this->getMockUseStatement("a\\b\\c\\d\\DClass", 11), $this->getMockUseStatement("a\\b\\c\\d\\CClass", 12), $this->getMockUseStatement("a\\b\\EClass", 14), $this->getMockUseStatement("a\\b\\c\\AClass", 16), $this->getMockUseStatement("a\\b\\c\\BClass", 17)]; $useStatementOrganizer = new UseStatementOrganizer($useStatements); $lineSwaps = $useStatementOrganizer->getLineSwaps(); $this->assertEquals(3, count($lineSwaps)); $this->assertEquals(11, $lineSwaps[17]); $this->assertEquals(12, $lineSwaps[16]); $this->assertEquals(11, $lineSwaps[14]); $mapping = [5 => 5, 6 => 6, 8 => 8, 9 => 9, 11 => 17, 12 => 16, 14 => 11, 16 => 12, 17 => 14]; $this->assertEquals($mapping, $useStatementOrganizer->getLineNumberMovements()); }
/** * Called once after traversal. * * Return value semantics: * * null: $nodes stays as-is * * otherwise: $nodes is set to the return value * * @param Node[] $nodes Array of nodes * * @return null|Node[] Array of nodes */ public function afterTraverse(array $nodes) { if ($this->namespace == '') { $this->result->error(ErrorType::MISSING_NAMESPACE, null, 'Every source file should have a namespace'); } $autoFix = $this->result->getConfig()->autoFix; $useStatementOrganizer = new UseStatementOrganizer($this->useStatements); $lineNumberMovements = []; if (!$useStatementOrganizer->areOrganized()) { $errorMsg = "Uses are not organized"; if ($autoFix) { $lineSwaps = $useStatementOrganizer->getLineSwaps(); $lineNumberMovements = $useStatementOrganizer->getLineNumberMovements(); foreach ($lineSwaps as $currentLine => $newLine) { $fix = new SwapLineFix($currentLine, $newLine, $errorMsg); $this->result->fix($fix); } } else { $lineSwaps = $useStatementOrganizer->getLineSwaps(); foreach ($lineSwaps as $currentLine => $newLine) { $this->result->error(ErrorType::DISORGANIZED_USES, $currentLine, $errorMsg . ": this use should be on {$newLine}"); } } } $unusedFixes = []; foreach ($this->aliases as $use) { $errorMsg = ''; $name = $use->getName(); if ($use->getUseCount() == 0) { $errorMsg = "Use '{$name}' is not being used"; } elseif (str_replace("{$this->namespace}\\", '', "\\{$name}") === $use->getAlias()) { $errorMsg = "Use '{$name}' is automatically included as it is in the same namespace"; } if ($errorMsg) { if ($autoFix) { $line = $use->getNode()->getLine(); // if organization occurred the line may have moved if (isset($lineNumberMovements[$line])) { $line = $lineNumberMovements[$line]; } $fix = new RemoveLineFix($line, $errorMsg); $unusedFixes[$line] = $fix; } else { $this->result->error(ErrorType::UNUSED_USE, $use->getNode()->getLine(), $errorMsg); } } } if ($autoFix) { // removing must be done in reverse order krsort($unusedFixes); foreach ($unusedFixes as $fix) { $this->result->fix($fix); } } }