diff --git a/.github/workflows/annotated_checkstyle.yaml b/.github/workflows/annotated_checkstyle.yaml new file mode 100644 index 000000000000..caed2db3ff75 --- /dev/null +++ b/.github/workflows/annotated_checkstyle.yaml @@ -0,0 +1,22 @@ +# see https://github.com/staabm/annotate-pull-request-from-checkstyle +name: Anotate Checkstyle + +on: + pull_request: null + push: + branches: + - master + +jobs: + check_fixtures: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - uses: shivammathur/setup-php@v1 + with: + php-version: 7.2 + coverage: none # disable xdebug, pcov + tools: cs2pr + - run: composer install --no-progress + - run: | + bin/rector process --config rector-ci.yaml --no-progress-bar --ansi --dry-run --output-format=checkstyle | cs2pr diff --git a/composer.json b/composer.json index d6c5d7b7be55..9026b06d8ef9 100644 --- a/composer.json +++ b/composer.json @@ -61,6 +61,7 @@ "Rector\\CodeQuality\\": "rules/code-quality/src", "Rector\\CodingStyle\\": "rules/coding-style/src", "Rector\\ConsoleDiffer\\": "packages/console-differ/src", + "Rector\\ChangesReporting\\": "packages/changes-reporting/src", "Rector\\DeadCode\\": "rules/dead-code/src", "Rector\\DoctrineCodeQuality\\": "rules/doctrine-code-quality/src", "Rector\\DoctrineGedmoToKnplabs\\": "rules/doctrine-gedmo-to-knplabs/src", diff --git a/docs/AllRectorsOverview.md b/docs/AllRectorsOverview.md index 6977c9bae816..fe55f1bae18a 100644 --- a/docs/AllRectorsOverview.md +++ b/docs/AllRectorsOverview.md @@ -7015,9 +7015,9 @@ Changes heredoc/nowdoc that contains closing word to safe wrapper name
-### `SetcookieRector` +### `SetCookieRector` -- class: [`Rector\Php73\Rector\FuncCall\SetcookieRector`](/../master/rules/php-73/src/Rector/FuncCall/SetcookieRector.php) +- class: [`Rector\Php73\Rector\FuncCall\SetCookieRector`](/../master/rules/php-73/src/Rector/FuncCall/SetCookieRector.php) - [test fixtures](/../master/rules/php-73/tests/Rector/FuncCall/SetcookieRector/Fixture) Convert setcookie argument to PHP7.3 option array diff --git a/packages/changes-reporting/config/config.yaml b/packages/changes-reporting/config/config.yaml new file mode 100644 index 000000000000..5543cfd5d079 --- /dev/null +++ b/packages/changes-reporting/config/config.yaml @@ -0,0 +1,11 @@ +services: + _defaults: + autowire: true + autoconfigure: true + public: true + + Rector\ChangesReporting\: + resource: '../src' + exclude: + - '../src/Contract/*' + - '../src/ValueObject/*' diff --git a/src/Application/ErrorAndDiffCollector.php b/packages/changes-reporting/src/Application/ErrorAndDiffCollector.php similarity index 87% rename from src/Application/ErrorAndDiffCollector.php rename to packages/changes-reporting/src/Application/ErrorAndDiffCollector.php index ccf76f0e9b7f..ced7b1b115b9 100644 --- a/src/Application/ErrorAndDiffCollector.php +++ b/packages/changes-reporting/src/Application/ErrorAndDiffCollector.php @@ -2,10 +2,11 @@ declare(strict_types=1); -namespace Rector\Core\Application; +namespace Rector\ChangesReporting\Application; use PhpParser\Node; use PHPStan\AnalysedCodeException; +use Rector\ChangesReporting\Collector\RectorChangeCollector; use Rector\ConsoleDiffer\DifferAndFormatter; use Rector\Core\Application\FileSystem\RemovedAndAddedFilesCollector; use Rector\Core\Error\ExceptionCorrector; @@ -33,9 +34,9 @@ final class ErrorAndDiffCollector private $differAndFormatter; /** - * @var AppliedRectorCollector + * @var RectorChangeCollector */ - private $appliedRectorCollector; + private $rectorChangeCollector; /** * @var ExceptionCorrector @@ -54,13 +55,13 @@ final class ErrorAndDiffCollector public function __construct( DifferAndFormatter $differAndFormatter, - AppliedRectorCollector $appliedRectorCollector, + RectorChangeCollector $rectorChangeCollector, ExceptionCorrector $exceptionCorrector, RemovedAndAddedFilesCollector $removedAndAddedFilesCollector, NodeRemovingCommander $nodeRemovingCommander ) { $this->differAndFormatter = $differAndFormatter; - $this->appliedRectorCollector = $appliedRectorCollector; + $this->rectorChangeCollector = $rectorChangeCollector; $this->exceptionCorrector = $exceptionCorrector; $this->removedAndAddedFilesCollector = $removedAndAddedFilesCollector; $this->nodeRemovingCommander = $nodeRemovingCommander; @@ -103,14 +104,14 @@ public function addFileDiff(SmartFileInfo $smartFileInfo, string $newContent, st return; } - $appliedRectors = $this->appliedRectorCollector->getRectorClasses($smartFileInfo); + $rectorChanges = $this->rectorChangeCollector->getRectorChangesByFileInfo($smartFileInfo); // always keep the most recent diff $this->fileDiffs[$smartFileInfo->getRealPath()] = new FileDiff( $smartFileInfo, $this->differAndFormatter->diff($oldContent, $newContent), $this->differAndFormatter->diffAndFormat($oldContent, $newContent), - $appliedRectors + $rectorChanges ); } @@ -148,7 +149,8 @@ public function addThrowableWithFileInfo(Throwable $throwable, SmartFileInfo $fi if ($rectorClass) { $this->addErrorWithRectorClassMessageAndFileInfo($rectorClass, $throwable->getMessage(), $fileInfo); } else { - $this->addError(new Error($fileInfo, $throwable->getMessage(), $throwable->getCode())); + $error = new Error($fileInfo, $throwable->getMessage(), $throwable->getCode()); + $this->addError($error); } } } diff --git a/src/Report/AffectedFilesCollector.php b/packages/changes-reporting/src/Collector/AffectedFilesCollector.php similarity index 93% rename from src/Report/AffectedFilesCollector.php rename to packages/changes-reporting/src/Collector/AffectedFilesCollector.php index ef1522211646..2c9be12e611b 100644 --- a/src/Report/AffectedFilesCollector.php +++ b/packages/changes-reporting/src/Collector/AffectedFilesCollector.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace Rector\Core\Report; +namespace Rector\ChangesReporting\Collector; use Symplify\SmartFileSystem\SmartFileInfo; diff --git a/packages/changes-reporting/src/Collector/RectorChangeCollector.php b/packages/changes-reporting/src/Collector/RectorChangeCollector.php new file mode 100644 index 000000000000..022d67496869 --- /dev/null +++ b/packages/changes-reporting/src/Collector/RectorChangeCollector.php @@ -0,0 +1,70 @@ +currentRectorProvider = $currentRectorProvider; + } + + public function addRectorClassWithLine(RectorInterface $rector, SmartFileInfo $smartFileInfo, int $line): void + { + $this->rectorWithFileAndLineChanges[] = new RectorWithFileAndLineChange( + $rector, + $smartFileInfo->getRealPath(), + $line + ); + } + + /** + * @return RectorWithFileAndLineChange[] + */ + public function getRectorChangesByFileInfo(SmartFileInfo $smartFileInfo): array + { + return array_filter( + $this->rectorWithFileAndLineChanges, + function (RectorWithFileAndLineChange $rectorWithFileAndLineChange) use ($smartFileInfo) { + return $rectorWithFileAndLineChange->getRealPath() === $smartFileInfo->getRealPath(); + } + ); + } + + public function notifyNodeFileInfo(Node $node): void + { + $fileInfo = $node->getAttribute(AttributeKey::FILE_INFO); + if ($fileInfo === null) { + // this file was changed before and this is a sub-new node + // array Traverse to all new nodes would have to be used, but it's not worth the performance + return; + } + + $currentRector = $this->currentRectorProvider->getCurrentRector(); + if ($currentRector === null) { + throw new ShouldNotHappenException(); + } + + $this->addRectorClassWithLine($currentRector, $fileInfo, $node->getLine()); + } +} diff --git a/src/Contract/Console/Output/OutputFormatterInterface.php b/packages/changes-reporting/src/Contract/Output/OutputFormatterInterface.php similarity index 62% rename from src/Contract/Console/Output/OutputFormatterInterface.php rename to packages/changes-reporting/src/Contract/Output/OutputFormatterInterface.php index 7d9229011187..2ec41a0d5499 100644 --- a/src/Contract/Console/Output/OutputFormatterInterface.php +++ b/packages/changes-reporting/src/Contract/Output/OutputFormatterInterface.php @@ -2,9 +2,9 @@ declare(strict_types=1); -namespace Rector\Core\Contract\Console\Output; +namespace Rector\ChangesReporting\Contract\Output; -use Rector\Core\Application\ErrorAndDiffCollector; +use Rector\ChangesReporting\Application\ErrorAndDiffCollector; interface OutputFormatterInterface { diff --git a/packages/changes-reporting/src/NodeManipulator/NotifyingNodeRemover.php b/packages/changes-reporting/src/NodeManipulator/NotifyingNodeRemover.php new file mode 100644 index 000000000000..0b1bfb0a6361 --- /dev/null +++ b/packages/changes-reporting/src/NodeManipulator/NotifyingNodeRemover.php @@ -0,0 +1,83 @@ +rectorChangeCollector = $rectorChangeCollector; + } + + /** + * @param Closure|ClassMethod|Function_ $node + */ + public function removeStmt(Node $node, int $key): void + { + if ($node->stmts === null) { + throw new ShouldNotHappenException(); + } + + // notify about remove node + $this->rectorChangeCollector->notifyNodeFileInfo($node->stmts[$key]); + + unset($node->stmts[$key]); + } + + public function removeParam(ClassMethod $classMethod, int $key): void + { + if ($classMethod->params === null) { + throw new ShouldNotHappenException(); + } + + // notify about remove node + $this->rectorChangeCollector->notifyNodeFileInfo($classMethod->params[$key]); + + unset($classMethod->params[$key]); + } + + /** + * @param FuncCall|MethodCall|StaticCall $node + */ + public function removeArg(Node $node, int $key): void + { + if ($node->args === null) { + throw new ShouldNotHappenException(); + } + + // notify about remove node + $this->rectorChangeCollector->notifyNodeFileInfo($node->args[$key]); + + unset($node->args[$key]); + } + + public function removeImplements(Class_ $class, int $key): void + { + if ($class->implements === null) { + throw new ShouldNotHappenException(); + } + + // notify about remove node + $this->rectorChangeCollector->notifyNodeFileInfo($class->implements[$key]); + + unset($class->implements[$key]); + } +} diff --git a/packages/changes-reporting/src/Output/CheckstyleOutputFormatter.php b/packages/changes-reporting/src/Output/CheckstyleOutputFormatter.php new file mode 100644 index 000000000000..d77928076b65 --- /dev/null +++ b/packages/changes-reporting/src/Output/CheckstyleOutputFormatter.php @@ -0,0 +1,91 @@ +symfonyStyle = $symfonyStyle; + } + + public function getName(): string + { + return self::NAME; + } + + public function report(ErrorAndDiffCollector $errorAndDiffCollector): void + { + $this->symfonyStyle->writeln(''); + $this->symfonyStyle->writeln(''); + + foreach ($errorAndDiffCollector->getFileDiffs() as $fileDiff) { + $this->writeFileErrors($fileDiff); + } + + $this->writeNonFileErrors($errorAndDiffCollector); + + $this->symfonyStyle->writeln(''); + } + + private function escape(string $string): string + { + return htmlspecialchars($string, ENT_XML1 | ENT_COMPAT, 'UTF-8'); + } + + private function writeFileErrors(FileDiff $fileDiff): void + { + $this->symfonyStyle->writeln(sprintf('', $this->escape($fileDiff->getRelativeFilePath()))); + + foreach ($fileDiff->getRectorChanges() as $rectorChange) { + $message = $rectorChange->getRectorDefinitionsDescription() . ' (Reported by: ' . $rectorChange->getRectorClass() . ')'; + $message = $this->escape($message); + + $error = sprintf( + ' ', + $this->escape((string) $rectorChange->getLine()), + $message + ); + $this->symfonyStyle->writeln($error); + } + + $this->symfonyStyle->writeln(''); + } + + private function writeNonFileErrors(ErrorAndDiffCollector $errorAndDiffCollector): void + { + if ($errorAndDiffCollector->getErrors() !== []) { + $this->symfonyStyle->writeln(''); + + foreach ($errorAndDiffCollector->getErrors() as $error) { + $escapedMessage = $this->escape($error->getMessage()); + + $this->symfonyStyle->writeln( + sprintf(' ', $escapedMessage) + ); + } + + $this->symfonyStyle->writeln(''); + } + } +} diff --git a/src/Console/Output/ConsoleOutputFormatter.php b/packages/changes-reporting/src/Output/ConsoleOutputFormatter.php similarity index 95% rename from src/Console/Output/ConsoleOutputFormatter.php rename to packages/changes-reporting/src/Output/ConsoleOutputFormatter.php index 63620c2cb645..b7af98fa218c 100644 --- a/src/Console/Output/ConsoleOutputFormatter.php +++ b/packages/changes-reporting/src/Output/ConsoleOutputFormatter.php @@ -2,13 +2,13 @@ declare(strict_types=1); -namespace Rector\Core\Console\Output; +namespace Rector\ChangesReporting\Output; use Nette\Utils\Strings; -use Rector\Core\Application\ErrorAndDiffCollector; +use Rector\ChangesReporting\Application\ErrorAndDiffCollector; +use Rector\ChangesReporting\Contract\Output\OutputFormatterInterface; use Rector\Core\Configuration\Configuration; use Rector\Core\Configuration\Option; -use Rector\Core\Contract\Console\Output\OutputFormatterInterface; use Rector\Core\PhpParser\Printer\BetterStandardPrinter; use Rector\Core\ValueObject\Application\Error; use Rector\Core\ValueObject\Reporting\FileDiff; @@ -112,10 +112,10 @@ private function reportFileDiffs(array $fileDiffs): void $this->symfonyStyle->writeln($fileDiff->getDiffConsoleFormatted()); $this->symfonyStyle->newLine(); - if ($fileDiff->getAppliedRectorClasses() !== []) { + if ($fileDiff->getRectorChanges() !== []) { $this->symfonyStyle->writeln('Applied rules:'); $this->symfonyStyle->newLine(); - $this->symfonyStyle->listing($fileDiff->getAppliedRectorClasses()); + $this->symfonyStyle->listing($fileDiff->getRectorClasses()); $this->symfonyStyle->newLine(); } } diff --git a/src/Console/Output/JsonOutputFormatter.php b/packages/changes-reporting/src/Output/JsonOutputFormatter.php similarity index 91% rename from src/Console/Output/JsonOutputFormatter.php rename to packages/changes-reporting/src/Output/JsonOutputFormatter.php index 5fb635872bb7..79198cf92a2c 100644 --- a/src/Console/Output/JsonOutputFormatter.php +++ b/packages/changes-reporting/src/Output/JsonOutputFormatter.php @@ -2,13 +2,13 @@ declare(strict_types=1); -namespace Rector\Core\Console\Output; +namespace Rector\ChangesReporting\Output; use Nette\Utils\FileSystem; use Nette\Utils\Json; -use Rector\Core\Application\ErrorAndDiffCollector; +use Rector\ChangesReporting\Application\ErrorAndDiffCollector; +use Rector\ChangesReporting\Contract\Output\OutputFormatterInterface; use Rector\Core\Configuration\Configuration; -use Rector\Core\Contract\Console\Output\OutputFormatterInterface; use Symfony\Component\Console\Style\SymfonyStyle; final class JsonOutputFormatter implements OutputFormatterInterface @@ -61,7 +61,7 @@ public function report(ErrorAndDiffCollector $errorAndDiffCollector): void $errorsArray['file_diffs'][] = [ 'file' => $relativeFilePath, 'diff' => $fileDiff->getDiff(), - 'applied_rectors' => $fileDiff->getAppliedRectorClasses(), + 'applied_rectors' => $fileDiff->getRectorClasses(), ]; // for Rector CI diff --git a/packages/changes-reporting/src/Rector/AbstractRector/NotifyingRemovingNodeTrait.php b/packages/changes-reporting/src/Rector/AbstractRector/NotifyingRemovingNodeTrait.php new file mode 100644 index 000000000000..3c9258570d76 --- /dev/null +++ b/packages/changes-reporting/src/Rector/AbstractRector/NotifyingRemovingNodeTrait.php @@ -0,0 +1,57 @@ +notifyingNodeRemover = $notifyingNodeRemover; + } + + /** + * @param Closure|ClassMethod|Function_ $node + */ + protected function removeStmt(Node $node, int $key): void + { + $this->notifyingNodeRemover->removeStmt($node, $key); + } + + protected function removeParam(ClassMethod $classMethod, int $key): void + { + $this->notifyingNodeRemover->removeParam($classMethod, $key); + } + + /** + * @param FuncCall|MethodCall|StaticCall $node + */ + protected function removeArg(Node $node, int $key): void + { + $this->notifyingNodeRemover->removeArg($node, $key); + } + + protected function removeImplements(Class_ $class, int $key): void + { + $this->notifyingNodeRemover->removeImplements($class, $key); + } +} diff --git a/packages/changes-reporting/src/ValueObject/RectorWithFileAndLineChange.php b/packages/changes-reporting/src/ValueObject/RectorWithFileAndLineChange.php new file mode 100644 index 000000000000..affb851758df --- /dev/null +++ b/packages/changes-reporting/src/ValueObject/RectorWithFileAndLineChange.php @@ -0,0 +1,57 @@ +rector = $rector; + $this->line = $line; + $this->realPath = $realPath; + } + + public function getRector(): RectorInterface + { + return $this->rector; + } + + public function getRectorDefinitionsDescription(): string + { + return $this->rector->getDefinition()->getDescription(); + } + + public function getRectorClass(): string + { + return get_class($this->rector); + } + + public function getLine(): int + { + return $this->line; + } + + public function getRealPath(): string + { + return $this->realPath; + } +} diff --git a/rules/architecture/src/Rector/Class_/ConstructorInjectionToActionInjectionRector.php b/rules/architecture/src/Rector/Class_/ConstructorInjectionToActionInjectionRector.php index fa5b418366b4..d781511c1866 100644 --- a/rules/architecture/src/Rector/Class_/ConstructorInjectionToActionInjectionRector.php +++ b/rules/architecture/src/Rector/Class_/ConstructorInjectionToActionInjectionRector.php @@ -298,7 +298,7 @@ private function removeAssignsFromConstructor(ClassMethod $classMethod): void } // remove the assign - unset($classMethod->stmts[$key]); + $this->removeStmt($classMethod, $key); } } diff --git a/rules/coding-style/src/Rector/Namespace_/ImportFullyQualifiedNamesRector.php b/rules/coding-style/src/Rector/Namespace_/ImportFullyQualifiedNamesRector.php index 5e199c3ab8b4..da28d08a7a5a 100644 --- a/rules/coding-style/src/Rector/Namespace_/ImportFullyQualifiedNamesRector.php +++ b/rules/coding-style/src/Rector/Namespace_/ImportFullyQualifiedNamesRector.php @@ -124,10 +124,13 @@ public function refactor(Node $node): ?Node /** @var PhpDocInfo|null $phpDocInfo */ $phpDocInfo = $node->getAttribute(AttributeKey::PHP_DOC_INFO); if ($phpDocInfo === null) { - return $node; + return null; } - $this->docBlockNameImporter->importNames($phpDocInfo, $node); + $hasChanged = $this->docBlockNameImporter->importNames($phpDocInfo, $node); + if (! $hasChanged) { + return null; + } return $node; } diff --git a/rules/dead-code/src/Rector/FunctionLike/RemoveCodeAfterReturnRector.php b/rules/dead-code/src/Rector/FunctionLike/RemoveCodeAfterReturnRector.php index ce67f3f63df9..24408bfc14d3 100644 --- a/rules/dead-code/src/Rector/FunctionLike/RemoveCodeAfterReturnRector.php +++ b/rules/dead-code/src/Rector/FunctionLike/RemoveCodeAfterReturnRector.php @@ -66,8 +66,6 @@ public function refactor(Node $node): ?Node } $isDeadAfterReturn = false; - $isDeadAfterReturnRemoved = false; - foreach ($node->stmts as $key => $stmt) { if ($isDeadAfterReturn) { // keep comment @@ -75,8 +73,7 @@ public function refactor(Node $node): ?Node continue; } - unset($node->stmts[$key]); - $isDeadAfterReturnRemoved = true; + $this->removeStmt($node, $key); } if ($stmt instanceof Return_) { @@ -85,10 +82,6 @@ public function refactor(Node $node): ?Node } } - if (! $isDeadAfterReturnRemoved) { - return null; - } - - return $node; + return null; } } diff --git a/rules/dead-code/src/Rector/MethodCall/RemoveDefaultArgumentValueRector.php b/rules/dead-code/src/Rector/MethodCall/RemoveDefaultArgumentValueRector.php index 34c18fa05f35..f4a024521b8e 100644 --- a/rules/dead-code/src/Rector/MethodCall/RemoveDefaultArgumentValueRector.php +++ b/rules/dead-code/src/Rector/MethodCall/RemoveDefaultArgumentValueRector.php @@ -93,7 +93,7 @@ public function refactor(Node $node): ?Node $keysToRemove = $this->resolveKeysToRemove($node, $defaultValues); foreach ($keysToRemove as $keyToRemove) { - unset($node->args[$keyToRemove]); + $this->removeArg($node, $keyToRemove); } return $node; diff --git a/rules/php-73/src/Rector/FuncCall/SetcookieRector.php b/rules/php-73/src/Rector/FuncCall/SetCookieRector.php similarity index 95% rename from rules/php-73/src/Rector/FuncCall/SetcookieRector.php rename to rules/php-73/src/Rector/FuncCall/SetCookieRector.php index 224b79eb8062..54311602e5de 100644 --- a/rules/php-73/src/Rector/FuncCall/SetcookieRector.php +++ b/rules/php-73/src/Rector/FuncCall/SetCookieRector.php @@ -4,7 +4,6 @@ namespace Rector\Php73\Rector\FuncCall; -use function count; use PhpParser\Node; use PhpParser\Node\Arg; use PhpParser\Node\Expr\Array_; @@ -22,8 +21,10 @@ * * @see https://www.php.net/setcookie * @see https://wiki.php.net/rfc/same-site-cookie + * + * @see \Rector\Php73\Tests\Rector\FuncCall\SetcookieRector\SetcookieRectorTest */ -final class SetcookieRector extends AbstractRector +final class SetCookieRector extends AbstractRector { /** * Conversion table from argument index to options name diff --git a/rules/php-73/tests/Rector/FuncCall/SetcookieRector/SetcookieRectorTest.php b/rules/php-73/tests/Rector/FuncCall/SetcookieRector/SetCookieRectorTest.php similarity index 76% rename from rules/php-73/tests/Rector/FuncCall/SetcookieRector/SetcookieRectorTest.php rename to rules/php-73/tests/Rector/FuncCall/SetcookieRector/SetCookieRectorTest.php index f26656ade426..1978f5db2203 100644 --- a/rules/php-73/tests/Rector/FuncCall/SetcookieRector/SetcookieRectorTest.php +++ b/rules/php-73/tests/Rector/FuncCall/SetcookieRector/SetCookieRectorTest.php @@ -6,9 +6,9 @@ use Iterator; use Rector\Core\Testing\PHPUnit\AbstractRectorTestCase; -use Rector\Php73\Rector\FuncCall\SetcookieRector; +use Rector\Php73\Rector\FuncCall\SetCookieRector; -final class SetcookieRectorTest extends AbstractRectorTestCase +final class SetCookieRectorTest extends AbstractRectorTestCase { /** * @dataProvider provideData() @@ -25,6 +25,6 @@ public function provideData(): Iterator protected function getRectorClass(): string { - return SetcookieRector::class; + return SetCookieRector::class; } } diff --git a/rules/phpunit/src/Rector/TryCatchToExpectExceptionRector.php b/rules/phpunit/src/Rector/TryCatchToExpectExceptionRector.php index 7cb6fd87b09f..abebf97763bf 100644 --- a/rules/phpunit/src/Rector/TryCatchToExpectExceptionRector.php +++ b/rules/phpunit/src/Rector/TryCatchToExpectExceptionRector.php @@ -80,7 +80,8 @@ public function refactor(Node $node): ?Node continue; } - unset($node->stmts[$key]); + /** @var int $key */ + $this->removeStmt($node, $key); } $node->stmts = array_merge((array) $node->stmts, (array) $proccesed); diff --git a/rules/type-declaration/src/Rector/FunctionLike/ParamTypeDeclarationRector.php b/rules/type-declaration/src/Rector/FunctionLike/ParamTypeDeclarationRector.php index c06deac2f3b6..ecfa40cbbb12 100644 --- a/rules/type-declaration/src/Rector/FunctionLike/ParamTypeDeclarationRector.php +++ b/rules/type-declaration/src/Rector/FunctionLike/ParamTypeDeclarationRector.php @@ -193,7 +193,7 @@ private function addParamTypeToMethod( $paramNode->type = $resolvedChildType; $paramNode->type->setAttribute(self::HAS_NEW_INHERITED_TYPE, true); - $this->notifyNodeChangeFileInfo($paramNode); + $this->notifyNodeFileInfo($paramNode); } /** diff --git a/rules/type-declaration/src/Rector/FunctionLike/ReturnTypeDeclarationRector.php b/rules/type-declaration/src/Rector/FunctionLike/ReturnTypeDeclarationRector.php index f10950592748..c5e921839633 100644 --- a/rules/type-declaration/src/Rector/FunctionLike/ReturnTypeDeclarationRector.php +++ b/rules/type-declaration/src/Rector/FunctionLike/ReturnTypeDeclarationRector.php @@ -260,7 +260,7 @@ private function addReturnTypeToChildMethod( // make sure the type is not overridden $currentClassMethod->returnType->setAttribute(self::DO_NOT_CHANGE, true); - $this->notifyNodeChangeFileInfo($currentClassMethod); + $this->notifyNodeFileInfo($currentClassMethod); } /** diff --git a/src/Application/AppliedRectorCollector.php b/src/Application/AppliedRectorCollector.php deleted file mode 100644 index 63859834ce6d..000000000000 --- a/src/Application/AppliedRectorCollector.php +++ /dev/null @@ -1,32 +0,0 @@ -rectorClassesByFile[$smartFileInfo->getRealPath()][] = $rectorClass; - } - - /** - * @return string[] - */ - public function getRectorClasses(SmartFileInfo $smartFileInfo): array - { - if (! isset($this->rectorClassesByFile[$smartFileInfo->getRealPath()])) { - return []; - } - - return array_unique($this->rectorClassesByFile[$smartFileInfo->getRealPath()]); - } -} diff --git a/src/Application/FileProcessor.php b/src/Application/FileProcessor.php index 9fe90c40d606..9939ce75ae22 100644 --- a/src/Application/FileProcessor.php +++ b/src/Application/FileProcessor.php @@ -6,11 +6,11 @@ use PhpParser\Lexer; use PhpParser\Node; +use Rector\ChangesReporting\Collector\AffectedFilesCollector; use Rector\Core\Exception\ShouldNotHappenException; use Rector\Core\PhpParser\NodeTraverser\RectorNodeTraverser; use Rector\Core\PhpParser\Parser\Parser; use Rector\Core\PhpParser\Printer\FormatPerservingPrinter; -use Rector\Core\Report\AffectedFilesCollector; use Rector\Core\Stubs\StubLoader; use Rector\NodeTypeResolver\FileSystem\CurrentFileInfoProvider; use Rector\NodeTypeResolver\NodeScopeAndMetadataDecorator; diff --git a/src/Application/RectorApplication.php b/src/Application/RectorApplication.php index 4f113a4adb6e..ab0adc86afc9 100644 --- a/src/Application/RectorApplication.php +++ b/src/Application/RectorApplication.php @@ -7,6 +7,7 @@ use OndraM\CiDetector\CiDetector; use PHPStan\AnalysedCodeException; use PHPStan\Analyser\NodeScopeResolver; +use Rector\ChangesReporting\Application\ErrorAndDiffCollector; use Rector\Core\Application\FileSystem\RemovedAndAddedFilesCollector; use Rector\Core\Application\FileSystem\RemovedAndAddedFilesProcessor; use Rector\Core\Configuration\Configuration; diff --git a/src/Configuration/Configuration.php b/src/Configuration/Configuration.php index b8e2dce62943..4e9de73d89d1 100644 --- a/src/Configuration/Configuration.php +++ b/src/Configuration/Configuration.php @@ -6,7 +6,8 @@ use Jean85\PrettyVersions; use Nette\Utils\Strings; -use Rector\Core\Console\Output\JsonOutputFormatter; +use Rector\ChangesReporting\Output\CheckstyleOutputFormatter; +use Rector\ChangesReporting\Output\JsonOutputFormatter; use Rector\Core\Exception\Rector\RectorNotFoundOrNotValidRectorClassException; use Rector\Core\Rector\AbstractRector; use Rector\Core\Testing\PHPUnit\PHPUnitEnvironment; @@ -166,8 +167,14 @@ public function getSource(): array private function canShowProgressBar(InputInterface $input): bool { $noProgressBar = (bool) $input->getOption(Option::OPTION_NO_PROGRESS_BAR); + if ($noProgressBar) { + return false; + } - return ! $noProgressBar && $input->getOption(Option::OPTION_OUTPUT_FORMAT) !== JsonOutputFormatter::NAME; + if ($input->getOption(Option::OPTION_OUTPUT_FORMAT) === JsonOutputFormatter::NAME) { + return false; + } + return $input->getOption(Option::OPTION_OUTPUT_FORMAT) !== CheckstyleOutputFormatter::NAME; } private function setOnlyRector(?string $rector): void diff --git a/src/Console/Application.php b/src/Console/Application.php index cd6dff274f9f..becbf8f35156 100644 --- a/src/Console/Application.php +++ b/src/Console/Application.php @@ -6,8 +6,9 @@ use Composer\XdebugHandler\XdebugHandler; use Jean85\PrettyVersions; +use Rector\ChangesReporting\Output\CheckstyleOutputFormatter; +use Rector\ChangesReporting\Output\JsonOutputFormatter; use Rector\Core\Configuration\Configuration; -use Rector\Core\Console\Output\JsonOutputFormatter; use Rector\Core\Exception\Configuration\InvalidConfigurationException; use Rector\Utils\DocumentationGenerator\Command\DumpNodesCommand; use Rector\Utils\DocumentationGenerator\Command\DumpRectorsCommand; @@ -118,14 +119,28 @@ private function getNewWorkingDir(InputInterface $input): string private function shouldPrintMetaInformation(InputInterface $input): bool { $hasNoArguments = $input->getFirstArgument() === null; + if ($hasNoArguments) { + return false; + } + $hasVersionOption = $input->hasParameterOption('--version'); + if ($hasVersionOption) { + return false; + } $hasJsonOutput = ( $input->getParameterOption('--output-format') === JsonOutputFormatter::NAME || $input->getParameterOption('-o') === JsonOutputFormatter::NAME ); + if ($hasJsonOutput) { + return false; + } - return ! ($hasVersionOption || $hasNoArguments || $hasJsonOutput); + $hasCheckstyleOutput = ( + $input->getParameterOption('--output-format') === CheckstyleOutputFormatter::NAME || + $input->getParameterOption('-o') === CheckstyleOutputFormatter::NAME + ); + return ! $hasCheckstyleOutput; } private function removeUnusedOptions(InputDefinition $inputDefinition): void diff --git a/src/Console/Command/ProcessCommand.php b/src/Console/Command/ProcessCommand.php index e4260c027655..45d734541dbd 100644 --- a/src/Console/Command/ProcessCommand.php +++ b/src/Console/Command/ProcessCommand.php @@ -4,12 +4,12 @@ namespace Rector\Core\Console\Command; -use Rector\Core\Application\ErrorAndDiffCollector; +use Rector\ChangesReporting\Application\ErrorAndDiffCollector; +use Rector\ChangesReporting\Output\ConsoleOutputFormatter; use Rector\Core\Application\RectorApplication; use Rector\Core\Autoloading\AdditionalAutoloader; use Rector\Core\Configuration\Configuration; use Rector\Core\Configuration\Option; -use Rector\Core\Console\Output\ConsoleOutputFormatter; use Rector\Core\Console\Output\OutputFormatterCollector; use Rector\Core\Console\Shell; use Rector\Core\Extension\ReportingExtensionRunner; diff --git a/src/Console/Output/OutputFormatterCollector.php b/src/Console/Output/OutputFormatterCollector.php index cc8a987b1647..2f43e5961cde 100644 --- a/src/Console/Output/OutputFormatterCollector.php +++ b/src/Console/Output/OutputFormatterCollector.php @@ -4,7 +4,7 @@ namespace Rector\Core\Console\Output; -use Rector\Core\Contract\Console\Output\OutputFormatterInterface; +use Rector\ChangesReporting\Contract\Output\OutputFormatterInterface; use Rector\Core\Exception\Console\Output\MissingOutputFormatterException; final class OutputFormatterCollector diff --git a/src/Exception/NotRectorException.php b/src/Exception/NotRectorException.php new file mode 100644 index 000000000000..a162ff0410f4 --- /dev/null +++ b/src/Exception/NotRectorException.php @@ -0,0 +1,18 @@ +currentRector = $rector; + } + + public function getCurrentRector(): ?RectorInterface + { + return $this->currentRector; + } +} diff --git a/src/PhpParser/Node/Commander/NodeRemovingCommander.php b/src/PhpParser/Node/Commander/NodeRemovingCommander.php index b59bca62375d..f7854e3424cb 100644 --- a/src/PhpParser/Node/Commander/NodeRemovingCommander.php +++ b/src/PhpParser/Node/Commander/NodeRemovingCommander.php @@ -9,10 +9,10 @@ use PhpParser\Node\Stmt; use PhpParser\Node\Stmt\Expression; use PhpParser\NodeTraverser; +use Rector\ChangesReporting\Collector\AffectedFilesCollector; use Rector\Core\Contract\PhpParser\Node\CommanderInterface; use Rector\Core\Exception\ShouldNotHappenException; use Rector\Core\PhpParser\Node\NodeVisitorFactory\NodeRemovingNodeVisitorFactory; -use Rector\Core\Report\AffectedFilesCollector; use Rector\NodeTypeResolver\Node\AttributeKey; use Symplify\SmartFileSystem\SmartFileInfo; diff --git a/src/PhpParser/Node/Manipulator/ArrayManipulator.php b/src/PhpParser/Node/Manipulator/ArrayManipulator.php index d5ef77a2bedd..d6ad18a121f4 100644 --- a/src/PhpParser/Node/Manipulator/ArrayManipulator.php +++ b/src/PhpParser/Node/Manipulator/ArrayManipulator.php @@ -8,9 +8,20 @@ use PhpParser\Node\Expr\ArrayItem; use PhpParser\Node\Scalar; use PhpParser\Node\Scalar\String_; +use Rector\ChangesReporting\Collector\RectorChangeCollector; final class ArrayManipulator { + /** + * @var RectorChangeCollector + */ + private $rectorChangeCollector; + + public function __construct(RectorChangeCollector $rectorChangeCollector) + { + $this->rectorChangeCollector = $rectorChangeCollector; + } + public function isArrayOnlyScalarValues(Array_ $array): bool { foreach ($array->items as $arrayItem) { @@ -56,7 +67,9 @@ public function findItemInInArrayByKeyAndUnset(Array_ $arrayNode, string $keyNam } // remove + recount for the printer + $removedArrayItem = $arrayNode->items[$i]; unset($arrayNode->items[$i]); + $this->rectorChangeCollector->notifyNodeFileInfo($removedArrayItem); return $item; } diff --git a/src/Rector/AbstractRector.php b/src/Rector/AbstractRector.php index e70b9ab7761c..af0b1a619698 100644 --- a/src/Rector/AbstractRector.php +++ b/src/Rector/AbstractRector.php @@ -20,6 +20,7 @@ use Rector\Core\Configuration\Option; use Rector\Core\Contract\Rector\PhpRectorInterface; use Rector\Core\Exclusion\ExclusionManager; +use Rector\Core\Logging\CurrentRectorProvider; use Rector\NodeTypeResolver\FileSystem\CurrentFileInfoProvider; use Rector\NodeTypeResolver\Node\AttributeKey; use Rector\NodeTypeResolver\PhpDoc\NodeAnalyzer\DocBlockManipulator; @@ -85,6 +86,11 @@ abstract class AbstractRector extends NodeVisitorAbstract implements PhpRectorIn */ protected $staticTypeMapper; + /** + * @var CurrentRectorProvider + */ + private $currentRectorProvider; + /** * @var string[] */ @@ -122,7 +128,8 @@ public function autowireAbstractRectorDependencies( PhpDocInfoPrinter $phpDocInfoPrinter, DocBlockManipulator $docBlockManipulator, StaticTypeMapper $staticTypeMapper, - ParameterProvider $parameterProvider + ParameterProvider $parameterProvider, + CurrentRectorProvider $currentRectorProvider ): void { $this->symfonyStyle = $symfonyStyle; $this->phpVersionProvider = $phpVersionProvider; @@ -134,6 +141,7 @@ public function autowireAbstractRectorDependencies( $this->docBlockManipulator = $docBlockManipulator; $this->staticTypeMapper = $staticTypeMapper; $this->parameterProvider = $parameterProvider; + $this->currentRectorProvider = $currentRectorProvider; } /** @@ -145,6 +153,8 @@ final public function enterNode(Node $node) return null; } + $this->currentRectorProvider->changeCurrentRector($this); + // show current Rector class on --debug if ($this->symfonyStyle->isDebug()) { // indented on purpose to improve log nesting under [refactoring] @@ -174,7 +184,7 @@ final public function enterNode(Node $node) $this->mirrorAttributes($originalNodeWithAttributes, $node); $this->updateAttributes($node); $this->keepFileInfoAttribute($node, $originalNode); - $this->notifyNodeChangeFileInfo($node); + $this->notifyNodeFileInfo($node); } // if stmt ("$value;") was replaced by expr ("$value"), add the ending ";" (Expression) to prevent breaking the code diff --git a/src/Rector/AbstractRector/AbstractRectorTrait.php b/src/Rector/AbstractRector/AbstractRectorTrait.php index 3173f2ad685a..de992150ca20 100644 --- a/src/Rector/AbstractRector/AbstractRectorTrait.php +++ b/src/Rector/AbstractRector/AbstractRectorTrait.php @@ -7,11 +7,11 @@ use Nette\Utils\Strings; use PhpParser\Node; use PhpParser\Node\Stmt\Class_; +use Rector\ChangesReporting\Rector\AbstractRector\NotifyingRemovingNodeTrait; use Rector\Doctrine\AbstractRector\DoctrineTrait; trait AbstractRectorTrait { - use AppliedRectorCollectorTrait; use DoctrineTrait; use NodeTypeResolverTrait; use NameResolverTrait; @@ -24,6 +24,7 @@ trait AbstractRectorTrait use CallableNodeTraverserTrait; use ComplexRemovalTrait; use NodeCollectorTrait; + use NotifyingRemovingNodeTrait; protected function isNonAnonymousClass(?Node $node): bool { diff --git a/src/Rector/AbstractRector/AppliedRectorCollectorTrait.php b/src/Rector/AbstractRector/AppliedRectorCollectorTrait.php deleted file mode 100644 index e5ee70b1f164..000000000000 --- a/src/Rector/AbstractRector/AppliedRectorCollectorTrait.php +++ /dev/null @@ -1,41 +0,0 @@ -appliedRectorCollector = $appliedRectorCollector; - } - - protected function notifyNodeChangeFileInfo(Node $node): void - { - $fileInfo = $node->getAttribute(AttributeKey::FILE_INFO); - if ($fileInfo === null) { - // this file was changed before and this is a sub-new node - // array Traverse to all new nodes would have to be used, but it's not worth the performance - return; - } - - $this->appliedRectorCollector->addRectorClass(static::class, $fileInfo); - } -} diff --git a/src/Rector/AbstractRector/NodeCommandersTrait.php b/src/Rector/AbstractRector/NodeCommandersTrait.php index 253cb74ec454..9a341be02feb 100644 --- a/src/Rector/AbstractRector/NodeCommandersTrait.php +++ b/src/Rector/AbstractRector/NodeCommandersTrait.php @@ -11,9 +11,9 @@ use PhpParser\Node\Stmt\ClassLike; use PHPStan\Type\ObjectType; use PHPStan\Type\Type; +use Rector\ChangesReporting\Collector\RectorChangeCollector; use Rector\CodingStyle\Application\NameImportingCommander; use Rector\CodingStyle\Application\UseAddingCommander; -use Rector\Core\Application\AppliedRectorCollector; use Rector\Core\PhpParser\Node\Commander\NodeAddingCommander; use Rector\Core\PhpParser\Node\Commander\NodeRemovingCommander; use Rector\Core\PhpParser\Node\Commander\NodeReplacingCommander; @@ -24,8 +24,6 @@ /** * This could be part of @see AbstractRector, but decopuling to trait * makes clear what code has 1 purpose. - * - * @property-read AppliedRectorCollector $appliedRectorCollector */ trait NodeCommandersTrait { @@ -59,6 +57,11 @@ trait NodeCommandersTrait */ private $nodeReplacingCommander; + /** + * @var RectorChangeCollector + */ + private $rectorChangeCollector; + /** * @required */ @@ -68,7 +71,8 @@ public function autowireNodeCommandersTrait( PropertyAddingCommander $propertyAddingCommander, UseAddingCommander $useAddingCommander, NameImportingCommander $nameImportingCommander, - NodeReplacingCommander $nodeReplacingCommander + NodeReplacingCommander $nodeReplacingCommander, + RectorChangeCollector $rectorChangeCollector ): void { $this->nodeRemovingCommander = $nodeRemovingCommander; $this->nodeAddingCommander = $nodeAddingCommander; @@ -76,6 +80,7 @@ public function autowireNodeCommandersTrait( $this->useAddingCommander = $useAddingCommander; $this->nameImportingCommander = $nameImportingCommander; $this->nodeReplacingCommander = $nodeReplacingCommander; + $this->rectorChangeCollector = $rectorChangeCollector; } /** @@ -92,28 +97,26 @@ protected function addNodeAfterNode(Node $newNode, Node $positionNode): void { $this->nodeAddingCommander->addNodeAfterNode($newNode, $positionNode); - $this->notifyNodeChangeFileInfo($positionNode); + $this->rectorChangeCollector->notifyNodeFileInfo($positionNode); } protected function addNodeBeforeNode(Node $newNode, Node $positionNode): void { $this->nodeAddingCommander->addNodeBeforeNode($newNode, $positionNode); - $this->notifyNodeChangeFileInfo($positionNode); + $this->rectorChangeCollector->notifyNodeFileInfo($positionNode); } protected function addPropertyToClass(Class_ $class, ?Type $propertyType, string $propertyName): void { $this->propertyAddingCommander->addPropertyToClass($propertyName, $propertyType, $class); - - $this->notifyNodeChangeFileInfo($class); + $this->rectorChangeCollector->notifyNodeFileInfo($class); } protected function addConstantToClass(Class_ $class, ClassConst $classConst): void { $this->propertyAddingCommander->addConstantToClass($class, $classConst); - - $this->notifyNodeChangeFileInfo($class); + $this->rectorChangeCollector->notifyNodeFileInfo($class); } protected function addPropertyWithoutConstructorToClass( @@ -123,21 +126,21 @@ protected function addPropertyWithoutConstructorToClass( ): void { $this->propertyAddingCommander->addPropertyWithoutConstructorToClass($propertyName, $propertyType, $classNode); - $this->notifyNodeChangeFileInfo($classNode); + $this->rectorChangeCollector->notifyNodeFileInfo($classNode); } protected function removeNode(Node $node): void { $this->nodeRemovingCommander->addNode($node); - $this->notifyNodeChangeFileInfo($node); + $this->rectorChangeCollector->notifyNodeFileInfo($node); } protected function replaceNode(Node $node, Node $replaceWith): void { $this->nodeReplacingCommander->replaceNode($node, $replaceWith); - $this->notifyNodeChangeFileInfo($replaceWith); + $this->rectorChangeCollector->notifyNodeFileInfo($replaceWith); } /** @@ -169,4 +172,9 @@ protected function removeNodes(array $nodes): void $this->removeNode($node); } } + + protected function notifyNodeFileInfo(Node $node): void + { + $this->rectorChangeCollector->notifyNodeFileInfo($node); + } } diff --git a/src/Rector/Architecture/DependencyInjection/ActionInjectionToConstructorInjectionRector.php b/src/Rector/Architecture/DependencyInjection/ActionInjectionToConstructorInjectionRector.php index 960fe5eaa556..11c8876ffaa0 100644 --- a/src/Rector/Architecture/DependencyInjection/ActionInjectionToConstructorInjectionRector.php +++ b/src/Rector/Architecture/DependencyInjection/ActionInjectionToConstructorInjectionRector.php @@ -115,8 +115,7 @@ private function processClassMethod(Class_ $classNode, ClassMethod $classMethod) $paramName = $this->getName($paramNode->var); $this->addPropertyToClass($classNode, $paramNodeType, $paramName); - // remove arguments - unset($classMethod->params[$key]); + $this->removeParam($classMethod, $key); $this->variablesToPropertyFetchCollection->addVariableNameAndType($paramName, $paramNodeType); } diff --git a/src/Rector/Argument/ArgumentRemoverRector.php b/src/Rector/Argument/ArgumentRemoverRector.php index 06c237c831cd..9dc4eeffee33 100644 --- a/src/Rector/Argument/ArgumentRemoverRector.php +++ b/src/Rector/Argument/ArgumentRemoverRector.php @@ -131,7 +131,7 @@ private function removeByName(Node $node, int $position, string $name): void { if ($node instanceof MethodCall || $node instanceof StaticCall) { if (isset($node->args[$position]) && $this->isName($node->args[$position], $name)) { - unset($node->args[$position]); + $this->removeArg($node, $position); } return; @@ -139,7 +139,7 @@ private function removeByName(Node $node, int $position, string $name): void if ($node instanceof ClassMethod) { if (isset($node->params[$position]) && $this->isName($node->params[$position], $name)) { - unset($node->params[$position]); + $this->removeParam($node, $position); } return; diff --git a/src/Rector/Interface_/MergeInterfacesRector.php b/src/Rector/Interface_/MergeInterfacesRector.php index a8d8e231bb43..f5f585b71880 100644 --- a/src/Rector/Interface_/MergeInterfacesRector.php +++ b/src/Rector/Interface_/MergeInterfacesRector.php @@ -92,7 +92,7 @@ private function makeImplementsUnique(Class_ $classNode): void foreach ($classNode->implements as $key => $name) { $fqnName = $this->getName($name); if (in_array($fqnName, $alreadyAddedNames, true)) { - unset($classNode->implements[$key]); + $this->removeImplements($classNode, $key); continue; } diff --git a/src/Rector/Property/InjectAnnotationClassRector.php b/src/Rector/Property/InjectAnnotationClassRector.php index 63b1c4707ca8..5a2c0c9d69ec 100644 --- a/src/Rector/Property/InjectAnnotationClassRector.php +++ b/src/Rector/Property/InjectAnnotationClassRector.php @@ -17,7 +17,7 @@ use Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfo; use Rector\BetterPhpDocParser\PhpDocNode\JMS\JMSInjectTagValueNode; use Rector\BetterPhpDocParser\PhpDocNode\PHPDI\PHPDIInjectTagValueNode; -use Rector\Core\Application\ErrorAndDiffCollector; +use Rector\ChangesReporting\Application\ErrorAndDiffCollector; use Rector\Core\Exception\NotImplementedException; use Rector\Core\Exception\ShouldNotHappenException; use Rector\Core\Rector\AbstractRector; diff --git a/src/Standalone/RectorStandaloneRunner.php b/src/Standalone/RectorStandaloneRunner.php index 583d109613c6..3b09f7875757 100644 --- a/src/Standalone/RectorStandaloneRunner.php +++ b/src/Standalone/RectorStandaloneRunner.php @@ -5,13 +5,13 @@ namespace Rector\Core\Standalone; use Psr\Container\ContainerInterface; -use Rector\Core\Application\ErrorAndDiffCollector; +use Rector\ChangesReporting\Application\ErrorAndDiffCollector; +use Rector\ChangesReporting\Output\ConsoleOutputFormatter; use Rector\Core\Application\RectorApplication; use Rector\Core\Autoloading\AdditionalAutoloader; use Rector\Core\Configuration\Configuration; use Rector\Core\Configuration\Option; use Rector\Core\Console\Command\ProcessCommand; -use Rector\Core\Console\Output\ConsoleOutputFormatter; use Rector\Core\DependencyInjection\RectorContainerFactory; use Rector\Core\Exception\FileSystem\FileNotFoundException; use Rector\Core\Extension\FinishingExtensionRunner; diff --git a/src/ValueObject/Reporting/FileDiff.php b/src/ValueObject/Reporting/FileDiff.php index 73d80ab78e74..f74f054886e7 100644 --- a/src/ValueObject/Reporting/FileDiff.php +++ b/src/ValueObject/Reporting/FileDiff.php @@ -4,6 +4,7 @@ namespace Rector\Core\ValueObject\Reporting; +use Rector\ChangesReporting\ValueObject\RectorWithFileAndLineChange; use Symplify\SmartFileSystem\SmartFileInfo; final class FileDiff @@ -19,9 +20,9 @@ final class FileDiff private $diffConsoleFormatted; /** - * @var string[] + * @var RectorWithFileAndLineChange[] */ - private $appliedRectorClasses = []; + private $rectorWithFileAndLineChanges = []; /** * @var SmartFileInfo @@ -29,17 +30,17 @@ final class FileDiff private $smartFileInfo; /** - * @param string[] $appliedRectorClasses + * @param RectorWithFileAndLineChange[] $rectorWithFileAndLineChanges */ public function __construct( SmartFileInfo $smartFileInfo, string $diff, string $diffConsoleFormatted, - array $appliedRectorClasses = [] + array $rectorWithFileAndLineChanges = [] ) { $this->smartFileInfo = $smartFileInfo; $this->diff = $diff; - $this->appliedRectorClasses = $appliedRectorClasses; + $this->rectorWithFileAndLineChanges = $rectorWithFileAndLineChanges; $this->diffConsoleFormatted = $diffConsoleFormatted; } @@ -58,11 +59,28 @@ public function getRelativeFilePath(): string return $this->smartFileInfo->getRelativeFilePath(); } + /** + * @return RectorWithFileAndLineChange[] + */ + public function getRectorChanges(): array + { + return $this->rectorWithFileAndLineChanges; + } + /** * @return string[] */ - public function getAppliedRectorClasses(): array + public function getRectorClasses(): array { - return $this->appliedRectorClasses; + $rectorClasses = []; + foreach ($this->rectorWithFileAndLineChanges as $rectorWithFileAndLineChange) { + $rectorClasses[] = $rectorWithFileAndLineChange->getRectorClass(); + } + + $rectorClasses = array_unique($rectorClasses); + + sort($rectorClasses); + + return $rectorClasses; } } diff --git a/tests/Standalone/RectorStandaloneRunnerTest.php b/tests/Standalone/RectorStandaloneRunnerTest.php index f62d1a07ab1d..e18f6eb20cbc 100644 --- a/tests/Standalone/RectorStandaloneRunnerTest.php +++ b/tests/Standalone/RectorStandaloneRunnerTest.php @@ -5,24 +5,15 @@ namespace Rector\Core\Tests\Standalone; use PHPUnit\Framework\TestCase; -use Rector\Core\Standalone\RectorStandaloneRunner; use Rector\Core\Standalone\RectorStandaloneRunnerStaticFactory; final class RectorStandaloneRunnerTest extends TestCase { - /** - * @var RectorStandaloneRunner - */ - private $rectorStandaloneRunner; - - protected function setUp(): void - { - $this->rectorStandaloneRunner = RectorStandaloneRunnerStaticFactory::create(); - } - public function test(): void { - $errorAndDiffCollector = $this->rectorStandaloneRunner->processSourceWithSet( + $rectorStandaloneRunner = RectorStandaloneRunnerStaticFactory::create(); + + $errorAndDiffCollector = $rectorStandaloneRunner->processSourceWithSet( [__DIR__ . '/Source/LowQualityFile.php'], 'code-quality', true,