Updated Rector to commit e530fc1e1a98faa22509115e79de5e5f2997208d

e530fc1e1a Introducing Collectors - final step 🥳  - processing collected data + test case (#4970)
This commit is contained in:
Tomas Votruba 2023-09-19 11:53:28 +00:00
parent 5ea7f9b378
commit 4ea05c5a5f
27 changed files with 397 additions and 73 deletions

View File

@ -13,6 +13,7 @@ return static function (RectorConfig $rectorConfig) : void {
$rectorConfig->autoloadPaths([]);
$rectorConfig->bootstrapFiles([]);
$rectorConfig->parallel();
$rectorConfig->disableCollectors();
// to avoid autoimporting out of the box
$rectorConfig->importNames(\false, \false);
$rectorConfig->removeUnusedImports(\false);

View File

@ -8,6 +8,7 @@ use PHPStan\Collectors\Collector;
use Rector\Caching\Contract\ValueObject\Storage\CacheStorageInterface;
use Rector\Core\Configuration\Option;
use Rector\Core\Configuration\Parameter\SimpleParameterProvider;
use Rector\Core\Contract\Rector\CollectorRectorInterface;
use Rector\Core\Contract\Rector\ConfigurableRectorInterface;
use Rector\Core\Contract\Rector\RectorInterface;
use Rector\Core\DependencyInjection\Laravel\ContainerMemento;
@ -51,6 +52,13 @@ final class RectorConfig extends Container
{
SimpleParameterProvider::setParameter(Option::PARALLEL, \false);
}
/**
* @experimental since Rector 0.17.x
*/
public function enableCollectors() : void
{
SimpleParameterProvider::setParameter(Option::COLLECTORS, \true);
}
public function parallel(int $seconds = 120, int $maxNumberOfProcess = 16, int $jobSize = 15) : void
{
SimpleParameterProvider::setParameter(Option::PARALLEL, \true);
@ -165,6 +173,9 @@ final class RectorConfig extends Container
Assert::isAOf($rectorClass, RectorInterface::class);
$this->singleton($rectorClass);
$this->tag($rectorClass, RectorInterface::class);
if (\is_a($rectorClass, CollectorRectorInterface::class, \true)) {
$this->tag($rectorClass, CollectorRectorInterface::class);
}
if (\is_a($rectorClass, AbstractScopeAwareRector::class, \true)) {
$this->extend($rectorClass, static function (AbstractScopeAwareRector $scopeAwareRector, Container $container) : AbstractScopeAwareRector {
$scopeAnalyzer = $container->make(ScopeAnalyzer::class);
@ -299,6 +310,13 @@ final class RectorConfig extends Container
ContainerMemento::forgetService($this, $skippedClass);
}
}
/**
* @experimental since Rector 0.17.x
*/
public function disableCollectors() : void
{
SimpleParameterProvider::setParameter(Option::COLLECTORS, \false);
}
/**
* @param mixed $skipRule
*/

View File

@ -73,8 +73,8 @@ final class ParallelFileProcessor
// initial counters
/** @var FileDiff[] $fileDiffs */
$fileDiffs = [];
/** @var CollectedData[] $collectedDatas */
$collectedDatas = [];
/** @var CollectedData[] $collectedData */
$collectedData = [];
/** @var SystemError[] $systemErrors */
$systemErrors = [];
$tcpServer = new TcpServer('127.0.0.1:0', $streamSelectLoop);
@ -95,7 +95,7 @@ final class ParallelFileProcessor
return;
}
$jobsChunk = \array_pop($jobs);
$parallelProcess->request([ReactCommand::ACTION => Action::MAIN, Content::FILES => $jobsChunk]);
$parallelProcess->request([ReactCommand::ACTION => Action::MAIN, Content::FILES => $jobsChunk, Bridge::PREVIOUSLY_COLLECTED_DATA => $configuration->getCollectedData()]);
});
});
/** @var string $serverAddress */
@ -116,14 +116,14 @@ final class ParallelFileProcessor
};
$timeoutInSeconds = SimpleParameterProvider::provideIntParameter(Option::PARALLEL_JOB_TIMEOUT_IN_SECONDS);
$fileChunksBudgetPerProcess = [];
$processSpawner = function () use(&$systemErrors, &$fileDiffs, &$jobs, $postFileCallback, &$systemErrorsCount, &$reachedInternalErrorsCountLimit, $mainScript, $input, $serverPort, $streamSelectLoop, $timeoutInSeconds, $handleErrorCallable, &$fileChunksBudgetPerProcess, &$processSpawner) : void {
$processSpawner = function () use(&$systemErrors, &$fileDiffs, &$collectedData, &$jobs, $postFileCallback, &$systemErrorsCount, &$reachedInternalErrorsCountLimit, $mainScript, $input, $serverPort, $streamSelectLoop, $timeoutInSeconds, $handleErrorCallable, &$fileChunksBudgetPerProcess, &$processSpawner) : void {
$processIdentifier = Random::generate();
$workerCommandLine = $this->workerCommandLineFactory->create($mainScript, ProcessCommand::class, 'worker', $input, $processIdentifier, $serverPort);
$fileChunksBudgetPerProcess[$processIdentifier] = self::MAX_CHUNKS_PER_WORKER;
$parallelProcess = new ParallelProcess($workerCommandLine, $streamSelectLoop, $timeoutInSeconds);
$parallelProcess->start(
// 1. callable on data
function (array $json) use($parallelProcess, &$systemErrors, &$fileDiffs, &$jobs, $postFileCallback, &$systemErrorsCount, &$collectedDatas, &$reachedInternalErrorsCountLimit, $processIdentifier, &$fileChunksBudgetPerProcess, &$processSpawner) : void {
function (array $json) use($parallelProcess, &$systemErrors, &$fileDiffs, &$jobs, $postFileCallback, &$systemErrorsCount, &$collectedData, &$reachedInternalErrorsCountLimit, $processIdentifier, &$fileChunksBudgetPerProcess, &$processSpawner) : void {
// decode arrays to objects
foreach ($json[Bridge::SYSTEM_ERRORS] as $jsonError) {
if (\is_string($jsonError)) {
@ -135,8 +135,8 @@ final class ParallelFileProcessor
foreach ($json[Bridge::FILE_DIFFS] as $jsonFileDiff) {
$fileDiffs[] = FileDiff::decode($jsonFileDiff);
}
foreach ($json[Bridge::COLLECTED_DATA] as $jsonCollectedData) {
$collectedDatas[] = CollectedData::decode($jsonCollectedData);
foreach ($json[Bridge::COLLECTED_DATA] as $collectedDataItem) {
$collectedData[] = CollectedData::decode($collectedDataItem);
}
$postFileCallback($json[Bridge::FILES_COUNT]);
$systemErrorsCount += $json[Bridge::SYSTEM_ERRORS_COUNT];
@ -185,6 +185,6 @@ final class ParallelFileProcessor
if ($reachedSystemErrorsCountLimit) {
$systemErrors[] = new SystemError(\sprintf('Reached system errors count limit of %d, exiting...', self::SYSTEM_ERROR_LIMIT));
}
return new ProcessResult($systemErrors, $fileDiffs, $collectedDatas);
return new ProcessResult($systemErrors, $fileDiffs, $collectedData);
}
}

View File

@ -32,4 +32,8 @@ final class Bridge
* @var string
*/
public const COLLECTED_DATA = 'collected_data';
/**
* @var string
*/
public const PREVIOUSLY_COLLECTED_DATA = 'previously_collected_data';
}

View File

@ -7,6 +7,7 @@ use RectorPrefix202309\Illuminate\Container\RewindableGenerator;
use Iterator;
use RectorPrefix202309\Nette\Utils\FileSystem;
use RectorPrefix202309\Nette\Utils\Strings;
use PHPStan\Collectors\Collector;
use PHPUnit\Framework\ExpectationFailedException;
use Rector\Core\Application\ApplicationFileProcessor;
use Rector\Core\Autoloading\AdditionalAutoloader;
@ -15,10 +16,11 @@ use Rector\Core\Configuration\ConfigurationFactory;
use Rector\Core\Configuration\Option;
use Rector\Core\Configuration\Parameter\SimpleParameterProvider;
use Rector\Core\Contract\DependencyInjection\ResetableInterface;
use Rector\Core\Contract\Rector\CollectorRectorInterface;
use Rector\Core\Contract\Rector\RectorInterface;
use Rector\Core\DependencyInjection\Laravel\ContainerMemento;
use Rector\Core\Exception\ShouldNotHappenException;
use Rector\Core\PhpParser\NodeTraverser\RectorNodeTraverser;
use Rector\Core\Provider\CurrentFileProvider;
use Rector\Core\Rector\AbstractRector;
use Rector\Core\Util\Reflection\PrivatesAccessor;
use Rector\NodeTypeResolver\Reflection\BetterReflection\SourceLocatorProvider\DynamicSourceLocatorProvider;
@ -44,10 +46,6 @@ abstract class AbstractRectorTestCase extends \Rector\Testing\PHPUnit\AbstractLa
* @var array<string, true>
*/
private static $cacheByRuleAndConfig = [];
/**
* @var \Rector\Core\Provider\CurrentFileProvider
*/
private $currentFileProvider;
/**
* Restore default parameters
*/
@ -59,6 +57,7 @@ abstract class AbstractRectorTestCase extends \Rector\Testing\PHPUnit\AbstractLa
SimpleParameterProvider::setParameter(Option::IMPORT_SHORT_CLASSES, \true);
SimpleParameterProvider::setParameter(Option::INDENT_CHAR, ' ');
SimpleParameterProvider::setParameter(Option::INDENT_SIZE, 4);
SimpleParameterProvider::setParameter(Option::COLLECTORS, \false);
}
protected function setUp() : void
{
@ -77,20 +76,23 @@ abstract class AbstractRectorTestCase extends \Rector\Testing\PHPUnit\AbstractLa
/** @var ResetableInterface $resetable */
$resetable->reset();
}
$this->forgetRectorsRules();
$this->forgetRectorsRulesAndCollectors();
$rectorConfig->resetRuleConfigurations();
// this has to be always empty, so we can add new rules with their configuration
$this->assertEmpty($rectorConfig->tagged(RectorInterface::class));
$this->assertEmpty($rectorConfig->tagged(CollectorRectorInterface::class));
$this->assertEmpty($rectorConfig->tagged(Collector::class));
$this->bootFromConfigFiles([$configFile]);
$rectorsGenerator = $rectorConfig->tagged(RectorInterface::class);
if ($rectorsGenerator instanceof RewindableGenerator) {
$phpRectors = \iterator_to_array($rectorsGenerator->getIterator());
$rectors = \iterator_to_array($rectorsGenerator->getIterator());
} else {
// no rules at all, e.g. in case of only post rector run
$phpRectors = [];
$rectors = [];
}
/** @var RectorNodeTraverser $rectorNodeTraverser */
$rectorNodeTraverser = $rectorConfig->make(RectorNodeTraverser::class);
$rectorNodeTraverser->refreshPhpRectors($phpRectors);
$rectorNodeTraverser->refreshPhpRectors($rectors);
// store cache
self::$cacheByRuleAndConfig[$cacheKey] = \true;
}
@ -102,7 +104,6 @@ abstract class AbstractRectorTestCase extends \Rector\Testing\PHPUnit\AbstractLa
/** @var BootstrapFilesIncluder $bootstrapFilesIncluder */
$bootstrapFilesIncluder = $this->make(BootstrapFilesIncluder::class);
$bootstrapFilesIncluder->includeBootstrapFiles();
$this->currentFileProvider = $this->make(CurrentFileProvider::class);
}
protected function tearDown() : void
{
@ -144,21 +145,15 @@ abstract class AbstractRectorTestCase extends \Rector\Testing\PHPUnit\AbstractLa
FileSystem::write($inputFilePath, $inputFileContents);
$this->doTestFileMatchesExpectedContent($inputFilePath, $expectedFileContents, $fixtureFilePath);
}
protected function forgetRectorsRules() : void
protected function forgetRectorsRulesAndCollectors() : void
{
$rectorConfig = self::getContainer();
// 1. forget instance first, then remove tags
$rectors = $rectorConfig->tagged(RectorInterface::class);
foreach ($rectors as $rector) {
$rectorConfig->offsetUnset(\get_class($rector));
}
// 2. remove all tagged rules
// 1. forget tagged services
ContainerMemento::forgetTag($rectorConfig, RectorInterface::class);
ContainerMemento::forgetTag($rectorConfig, Collector::class);
ContainerMemento::forgetTag($rectorConfig, CollectorRectorInterface::class);
// 2. remove after binding too, to avoid setting configuration over and over again
$privatesAccessor = new PrivatesAccessor();
$privatesAccessor->propertyClosure($rectorConfig, 'tags', static function (array $tags) : array {
unset($tags[RectorInterface::class]);
return $tags;
});
// 3. remove after binding too, to avoid setting configuration over and over again
$privatesAccessor->propertyClosure($rectorConfig, 'afterResolvingCallbacks', static function (array $afterResolvingCallbacks) : array {
foreach (\array_keys($afterResolvingCallbacks) as $key) {
if ($key === AbstractRector::class) {
@ -189,7 +184,7 @@ abstract class AbstractRectorTestCase extends \Rector\Testing\PHPUnit\AbstractLa
{
SimpleParameterProvider::setParameter(Option::SOURCE, [$originalFilePath]);
$changedContent = $this->processFilePath($originalFilePath);
$originalFileContent = $this->currentFileProvider->getFile()->getOriginalFileContent();
$originalFileContent = FileSystem::read($originalFilePath);
$fixtureFilename = \basename($fixtureFilePath);
$failureMessage = \sprintf('Failed on fixture file "%s"', $fixtureFilename);
try {
@ -206,9 +201,17 @@ abstract class AbstractRectorTestCase extends \Rector\Testing\PHPUnit\AbstractLa
/** @var ConfigurationFactory $configurationFactory */
$configurationFactory = $this->make(ConfigurationFactory::class);
$configuration = $configurationFactory->createForTests([$filePath]);
$this->applicationFileProcessor->processFiles([$filePath], $configuration);
$currentFile = $this->currentFileProvider->getFile();
return $currentFile->getFileContent();
$processResult = $this->applicationFileProcessor->processFiles([$filePath], $configuration);
if ($processResult->getCollectedData() !== [] && $configuration->isCollectors()) {
// second run with collected data
$configuration->setCollectedData($processResult->getCollectedData());
$configuration->enableSecondRun();
$rectorNodeTraverser = $this->make(RectorNodeTraverser::class);
$rectorNodeTraverser->prepareCollectorRectorsRun($configuration);
$this->applicationFileProcessor->processFiles([$filePath], $configuration);
}
// return changed file contents
return FileSystem::read($filePath);
}
private function createInputFilePath(string $fixtureFilePath) : string
{

View File

@ -0,0 +1,108 @@
<?php
declare (strict_types=1);
namespace Rector\Privatization\Rector\Class_;
use RectorPrefix202309\Nette\Utils\Arrays;
use PhpParser\Node;
use PhpParser\Node\Stmt\Class_;
use PHPStan\Node\CollectedDataNode;
use PHPStan\Reflection\ClassReflection;
use Rector\Core\NodeAnalyzer\ClassAnalyzer;
use Rector\Core\NodeAnalyzer\DoctrineEntityAnalyzer;
use Rector\Core\Rector\AbstractCollectorRector;
use Rector\Core\Reflection\ReflectionResolver;
use Rector\NodeTypeResolver\Node\AttributeKey;
use Rector\Privatization\NodeManipulator\VisibilityManipulator;
use Rector\TypeDeclaration\Collector\ParentClassCollector;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
/**
* @see \Rector\Tests\Privatization\Rector\Class_\FinalizeClassesWithoutChildrenCollectorRector\FinalizeClassesWithoutChildrenCollectorRectorTest
*/
final class FinalizeClassesWithoutChildrenCollectorRector extends AbstractCollectorRector
{
/**
* @readonly
* @var \Rector\Core\NodeAnalyzer\ClassAnalyzer
*/
private $classAnalyzer;
/**
* @readonly
* @var \Rector\Privatization\NodeManipulator\VisibilityManipulator
*/
private $visibilityManipulator;
/**
* @readonly
* @var \Rector\Core\Reflection\ReflectionResolver
*/
private $reflectionResolver;
/**
* @readonly
* @var \Rector\Core\NodeAnalyzer\DoctrineEntityAnalyzer
*/
private $doctrineEntityAnalyzer;
public function __construct(ClassAnalyzer $classAnalyzer, VisibilityManipulator $visibilityManipulator, ReflectionResolver $reflectionResolver, DoctrineEntityAnalyzer $doctrineEntityAnalyzer)
{
$this->classAnalyzer = $classAnalyzer;
$this->visibilityManipulator = $visibilityManipulator;
$this->reflectionResolver = $reflectionResolver;
$this->doctrineEntityAnalyzer = $doctrineEntityAnalyzer;
}
/**
* @return array<class-string<Node>>
*/
public function getNodeTypes() : array
{
return [Class_::class];
}
/**
* @param Class_ $node
*/
public function refactor(Node $node) : ?Node
{
if ($this->shouldSkipClass($node)) {
return null;
}
if ($this->doctrineEntityAnalyzer->hasClassAnnotation($node)) {
return null;
}
$classReflection = $this->reflectionResolver->resolveClassReflection($node);
if (!$classReflection instanceof ClassReflection) {
return null;
}
if ($this->doctrineEntityAnalyzer->hasClassReflectionAttribute($classReflection)) {
return null;
}
$parentClassNames = $this->resolveCollectedParentClassNames($this->getCollectedDataNode());
// the class is being extended in the code, so we should skip it here
if ($this->nodeNameResolver->isNames($node, $parentClassNames)) {
return null;
}
if ($node->attrGroups !== []) {
// improve reprint with correct newline
$node->setAttribute(AttributeKey::ORIGINAL_NODE, null);
}
$this->visibilityManipulator->makeFinal($node);
return $node;
}
public function getRuleDefinition() : RuleDefinition
{
return new RuleDefinition('...', []);
}
private function shouldSkipClass(Class_ $class) : bool
{
if ($class->isFinal() || $class->isAbstract()) {
return \true;
}
return $this->classAnalyzer->isAnonymousClass($class);
}
/**
* @return string[]
*/
private function resolveCollectedParentClassNames(CollectedDataNode $collectedDataNode) : array
{
$parentClassCollectorData = $collectedDataNode->get(ParentClassCollector::class);
$parentClassNames = Arrays::flatten($parentClassCollectorData);
return \array_unique($parentClassNames);
}
}

View File

@ -0,0 +1,31 @@
<?php
declare (strict_types=1);
namespace Rector\TypeDeclaration\Collector;
use PhpParser\Node;
use PhpParser\Node\Name;
use PhpParser\Node\Stmt\Class_;
use PHPStan\Analyser\Scope;
use PHPStan\Collectors\Collector;
/**
* @implements Collector<Class_, string[]|null>
*/
final class ParentClassCollector implements Collector
{
public function getNodeType() : string
{
return Class_::class;
}
/**
* @param Class_ $node
* @return string[]|null
*/
public function processNode(Node $node, Scope $scope) : ?array
{
if (!$node->extends instanceof Name) {
return null;
}
return [$node->extends->toString()];
}
}

View File

@ -11,7 +11,6 @@ use PHPStan\Collectors\Registry;
use Rector\NodeTypeResolver\Node\AttributeKey;
use Throwable;
/**
* @api
* @see Mimics https://github.com/phpstan/phpstan-src/commit/bccd1cd58e0d117ac8755ab228e338d966cac25a
*/
final class CollectorNodeVisitor extends NodeVisitorAbstract
@ -60,7 +59,7 @@ final class CollectorNodeVisitor extends NodeVisitorAbstract
/**
* @return CollectedData[]
*/
public function getCollectedDatas() : array
public function getCollectedData() : array
{
return $this->collectedDatas;
}

View File

@ -7,9 +7,6 @@ use PhpParser\Node;
use PhpParser\NodeTraverser;
use PHPStan\Collectors\CollectedData;
use PHPStan\Collectors\Registry;
/**
* @api
*/
final class CollectorProcessor
{
/**
@ -36,6 +33,6 @@ final class CollectorProcessor
public function process(array $stmts) : array
{
$this->nodeTraverser->traverse($stmts);
return $this->collectorNodeVisitor->getCollectedDatas();
return $this->collectorNodeVisitor->getCollectedData();
}
}

View File

@ -103,6 +103,10 @@ final class FileProcessor
}
public function processFile(File $file, Configuration $configuration) : FileProcessResult
{
if ($configuration->isSecondRun() && $configuration->isCollectors()) {
// 2nd run
$this->rectorNodeTraverser->prepareCollectorRectorsRun($configuration);
}
// 1. parse files to nodes
$parsingSystemError = $this->parseFileAndDecorateNodes($file);
if ($parsingSystemError instanceof SystemError) {
@ -116,7 +120,7 @@ final class FileProcessor
$file->changeHasChanged(\false);
$newStmts = $this->rectorNodeTraverser->traverse($file->getNewStmts());
// collect data
$fileCollectedData = $this->collectorProcessor->process($newStmts);
$fileCollectedData = $configuration->isCollectors() ? $this->collectorProcessor->process($newStmts) : [];
// apply post rectors
$postNewStmts = $this->postFileProcessor->traverse($newStmts);
// this is needed for new tokens added in "afterTraverse()"

View File

@ -19,12 +19,12 @@ final class VersionResolver
* @api
* @var string
*/
public const PACKAGE_VERSION = 'de462cf186c7bdaa8f5ed278fec681232c1f34ae';
public const PACKAGE_VERSION = 'e530fc1e1a98faa22509115e79de5e5f2997208d';
/**
* @api
* @var string
*/
public const RELEASE_DATE = '2023-09-19 12:38:56';
public const RELEASE_DATE = '2023-09-19 13:50:03';
/**
* @var int
*/

View File

@ -29,7 +29,8 @@ final class ConfigurationFactory
public function createForTests(array $paths) : Configuration
{
$fileExtensions = SimpleParameterProvider::provideArrayParameter(\Rector\Core\Configuration\Option::FILE_EXTENSIONS);
return new Configuration(\false, \true, \false, ConsoleOutputFormatter::NAME, $fileExtensions, $paths);
$isCollectors = SimpleParameterProvider::provideBoolParameter(\Rector\Core\Configuration\Option::COLLECTORS, \false);
return new Configuration(\false, \true, \false, ConsoleOutputFormatter::NAME, $fileExtensions, $paths, \true, null, null, \false, null, \false, $isCollectors);
}
/**
* Needs to run in the start of the life cycle, since the rest of workflow uses it.
@ -48,7 +49,8 @@ final class ConfigurationFactory
$parallelIdentifier = (string) $input->getOption(\Rector\Core\Configuration\Option::PARALLEL_IDENTIFIER);
$isDebug = (bool) $input->getOption(\Rector\Core\Configuration\Option::DEBUG);
$memoryLimit = $this->resolveMemoryLimit($input);
return new Configuration($isDryRun, $showProgressBar, $shouldClearCache, $outputFormat, $fileExtensions, $paths, $showDiffs, $parallelPort, $parallelIdentifier, $isParallel, $memoryLimit, $isDebug);
$isCollectors = SimpleParameterProvider::provideBoolParameter(\Rector\Core\Configuration\Option::COLLECTORS);
return new Configuration($isDryRun, $showProgressBar, $shouldClearCache, $outputFormat, $fileExtensions, $paths, $showDiffs, $parallelPort, $parallelIdentifier, $isParallel, $memoryLimit, $isDebug, $isCollectors);
}
private function shouldShowProgressBar(InputInterface $input, string $outputFormat) : bool
{

View File

@ -190,4 +190,9 @@ final class Option
* @var string
*/
public const REGISTERED_RECTOR_SETS = 'registered_rector_sets';
/**
* @internal
* @var string
*/
public const COLLECTORS = 'collectors';
}

View File

@ -115,8 +115,21 @@ final class ProcessCommand extends Command
// MAIN PHASE
// 2. run Rector
$processResult = $this->applicationFileProcessor->run($configuration, $input);
// 3. collectors phase
if ($processResult->getCollectedData() !== []) {
$this->symfonyStyle->newLine(2);
$this->symfonyStyle->title('Running 2nd time with collectors data');
$configuration->setCollectedData($processResult->getCollectedData());
$configuration->enableSecondRun();
// reset rules in Rector traverser
$nextProcessResult = $this->applicationFileProcessor->run($configuration, $input);
// @todo merge results here
$this->symfonyStyle->newLine(3);
// unset all rectors that are not collector
// set new collector rectors - have a custom tag? yes
}
// REPORTING PHASE
// 3. reporting phase
// 4. reporting phaseRunning 2nd time with collectors data
// report diffs and errors
$outputFormat = $configuration->getOutputFormat();
$outputFormatter = $this->outputFormatterCollector->getByName($outputFormat);

View File

@ -5,6 +5,7 @@ namespace Rector\Core\Console\Command;
use RectorPrefix202309\Clue\React\NDJson\Decoder;
use RectorPrefix202309\Clue\React\NDJson\Encoder;
use PHPStan\Collectors\CollectedData;
use RectorPrefix202309\React\EventLoop\StreamSelectLoop;
use RectorPrefix202309\React\Socket\ConnectionInterface;
use RectorPrefix202309\React\Socket\TcpConnector;
@ -23,6 +24,7 @@ use RectorPrefix202309\Symplify\EasyParallel\Enum\Action;
use RectorPrefix202309\Symplify\EasyParallel\Enum\ReactCommand;
use RectorPrefix202309\Symplify\EasyParallel\Enum\ReactEvent;
use Throwable;
use RectorPrefix202309\Webmozart\Assert\Assert;
/**
* Inspired at: https://github.com/phpstan/phpstan-src/commit/9124c66dcc55a222e21b1717ba5f60771f7dda92
* https://github.com/phpstan/phpstan-src/blob/c471c7b050e0929daf432288770de673b394a983/src/Command/WorkerCommand.php
@ -111,8 +113,22 @@ final class WorkerCommand extends Command
if ($action !== Action::MAIN) {
return;
}
$previouslyCollectedDataItems = $json[Bridge::PREVIOUSLY_COLLECTED_DATA] ?? [];
if ($previouslyCollectedDataItems !== []) {
// turn to value objects
$previouslyCollectedDatas = [];
foreach ($previouslyCollectedDataItems as $previouslyCollectedDataItem) {
Assert::keyExists($previouslyCollectedDataItem, 'data');
Assert::keyExists($previouslyCollectedDataItem, 'filePath');
Assert::keyExists($previouslyCollectedDataItem, 'collectorType');
$previouslyCollectedDatas[] = CollectedData::decode($previouslyCollectedDataItem);
}
$configuration->setCollectedData($previouslyCollectedDatas);
$configuration->enableSecondRun();
}
/** @var string[] $filePaths */
$filePaths = $json[Bridge::FILES] ?? [];
Assert::notEmpty($filePaths);
$processResult = $this->applicationFileProcessor->processFiles($filePaths, $configuration, $preFileCallback);
/**
* this invokes all listeners listening $decoder->on(...) @see \Symplify\EasyParallel\Enum\ReactEvent::DATA

View File

@ -0,0 +1,14 @@
<?php
declare (strict_types=1);
namespace Rector\Core\Contract\Rector;
use PHPStan\Node\CollectedDataNode;
/**
* @api
*/
interface CollectorRectorInterface extends \Rector\Core\Contract\Rector\RectorInterface
{
public function setCollectedDataNode(CollectedDataNode $collectedDataNode) : void;
public function getCollectedDataNode() : CollectedDataNode;
}

View File

@ -4,7 +4,7 @@ declare (strict_types=1);
namespace Rector\Core\Contract\Rector;
use Symplify\RuleDocGenerator\Contract\ConfigurableRuleInterface;
interface ConfigurableRectorInterface extends ConfigurableRuleInterface
interface ConfigurableRectorInterface extends \Rector\Core\Contract\Rector\RectorInterface, ConfigurableRuleInterface
{
/**
* @param mixed[] $configuration

View File

@ -10,6 +10,24 @@ use Rector\Core\Util\Reflection\PrivatesAccessor;
*/
final class ContainerMemento
{
/**
* @api
* @see https://tomasvotruba.com/blog/removing-service-from-laravel-container-is-not-that-easy
*/
public static function forgetTag(Container $container, string $tagToForget) : void
{
// 1. forget instances
$taggedClasses = $container->tagged($tagToForget);
foreach ($taggedClasses as $taggedClass) {
$container->offsetUnset(\get_class($taggedClass));
}
// 2. forget tagged references
$privatesAccessor = new PrivatesAccessor();
$privatesAccessor->propertyClosure($container, 'tags', static function (array $tags) use($tagToForget) : array {
unset($tags[$tagToForget]);
return $tags;
});
}
public static function forgetService(Container $container, string $typeToForget) : void
{
// 1. remove the service

View File

@ -59,6 +59,7 @@ use Rector\Core\Console\Output\OutputFormatterCollector;
use Rector\Core\Console\Style\RectorStyle;
use Rector\Core\Console\Style\SymfonyStyleFactory;
use Rector\Core\Contract\DependencyInjection\ResetableInterface;
use Rector\Core\Contract\Rector\CollectorRectorInterface;
use Rector\Core\Contract\Rector\RectorInterface;
use Rector\Core\NodeDecorator\CreatedByRuleDecorator;
use Rector\Core\PhpParser\Comparing\NodeComparator;
@ -177,6 +178,7 @@ use Rector\StaticTypeMapper\PhpParser\NullableTypeNodeMapper;
use Rector\StaticTypeMapper\PhpParser\StringNodeMapper;
use Rector\StaticTypeMapper\PhpParser\UnionTypeNodeMapper;
use Rector\StaticTypeMapper\StaticTypeMapper;
use Rector\TypeDeclaration\Collector\ParentClassCollector;
use Rector\Utils\Command\MissingInSetCommand;
use Rector\Utils\Command\OutsideAnySetCommand;
use RectorPrefix202309\Symfony\Component\Console\Application;
@ -246,6 +248,8 @@ final class LazyContainerFactory
$rectorConfig->import(__DIR__ . '/../../config/config.php');
// rector collectors
$rectorConfig->when(Registry::class)->needs('$collectors')->giveTagged(Collector::class);
// @todo collectors - just for testing purpose
$rectorConfig->collector(ParentClassCollector::class);
$rectorConfig->singleton(Application::class, static function (Container $container) : Application {
$application = $container->make(ConsoleApplication::class);
$commandNamesToHide = ['list', 'completion', 'help'];
@ -278,6 +282,7 @@ final class LazyContainerFactory
$rectorConfig->when(ConstExprParser::class)->needs('$usedAttributes')->give(['lines' => \true, 'indexes' => \true]);
$rectorConfig->alias(TypeParser::class, BetterTypeParser::class);
$rectorConfig->when(RectorNodeTraverser::class)->needs('$rectors')->giveTagged(RectorInterface::class);
$rectorConfig->when(RectorNodeTraverser::class)->needs('$collectorRectors')->giveTagged(CollectorRectorInterface::class);
$rectorConfig->when(ConfigInitializer::class)->needs('$rectors')->giveTagged(RectorInterface::class);
$rectorConfig->when(ClassNameImportSkipper::class)->needs('$classNameImportSkipVoters')->giveTagged(ClassNameImportSkipVoterInterface::class);
$rectorConfig->singleton(DynamicSourceLocatorProvider::class, static function (Container $container) : DynamicSourceLocatorProvider {
@ -308,7 +313,7 @@ final class LazyContainerFactory
$rectorConfig->when(Skipper::class)->needs('$skipVoters')->giveTagged(SkipVoterInterface::class);
$this->registerTagged($rectorConfig, self::SKIP_VOTER_CLASSES, SkipVoterInterface::class);
$rectorConfig->afterResolving(AbstractRector::class, static function (AbstractRector $rector, Container $container) : void {
$rector->autowire($container->make(NodeNameResolver::class), $container->make(NodeTypeResolver::class), $container->make(SimpleCallableNodeTraverser::class), $container->make(NodeFactory::class), $container->make(PhpDocInfoFactory::class), $container->make(StaticTypeMapper::class), $container->make(Skipper::class), $container->make(ValueResolver::class), $container->make(BetterNodeFinder::class), $container->make(NodeComparator::class), $container->make(CurrentFileProvider::class), $container->make(CreatedByRuleDecorator::class), $container->make(ChangedNodeScopeRefresher::class));
$rector->autowire($container->get(NodeNameResolver::class), $container->get(NodeTypeResolver::class), $container->get(SimpleCallableNodeTraverser::class), $container->get(NodeFactory::class), $container->get(PhpDocInfoFactory::class), $container->get(StaticTypeMapper::class), $container->get(Skipper::class), $container->get(ValueResolver::class), $container->get(BetterNodeFinder::class), $container->get(NodeComparator::class), $container->get(CurrentFileProvider::class), $container->get(CreatedByRuleDecorator::class), $container->get(ChangedNodeScopeRefresher::class));
});
$this->registerTagged($rectorConfig, self::PHP_PARSER_NODE_MAPPER_CLASSES, PhpParserNodeMapperInterface::class);
$this->registerTagged($rectorConfig, self::PHP_DOC_NODE_DECORATOR_CLASSES, PhpDocNodeDecoratorInterface::class);

View File

@ -5,7 +5,10 @@ namespace Rector\Core\PhpParser\NodeTraverser;
use PhpParser\Node;
use PhpParser\NodeTraverser;
use PHPStan\Node\CollectedDataNode;
use Rector\Core\Contract\Rector\CollectorRectorInterface;
use Rector\Core\Contract\Rector\RectorInterface;
use Rector\Core\ValueObject\Configuration;
use Rector\VersionBonding\PhpVersionedFilter;
final class RectorNodeTraverser extends NodeTraverser
{
@ -13,6 +16,10 @@ final class RectorNodeTraverser extends NodeTraverser
* @var RectorInterface[]
*/
private $rectors;
/**
* @var CollectorRectorInterface[]
*/
private $collectorRectors;
/**
* @readonly
* @var \Rector\VersionBonding\PhpVersionedFilter
@ -24,10 +31,12 @@ final class RectorNodeTraverser extends NodeTraverser
private $areNodeVisitorsPrepared = \false;
/**
* @param RectorInterface[] $rectors
* @param CollectorRectorInterface[] $collectorRectors
*/
public function __construct(array $rectors, PhpVersionedFilter $phpVersionedFilter)
public function __construct(array $rectors, array $collectorRectors, PhpVersionedFilter $phpVersionedFilter)
{
$this->rectors = $rectors;
$this->collectorRectors = $collectorRectors;
$this->phpVersionedFilter = $phpVersionedFilter;
parent::__construct();
}
@ -50,6 +59,19 @@ final class RectorNodeTraverser extends NodeTraverser
$this->visitors = [];
$this->areNodeVisitorsPrepared = \false;
}
public function prepareCollectorRectorsRun(Configuration $configuration) : void
{
if ($this->collectorRectors === []) {
return;
}
$collectedDataNode = new CollectedDataNode($configuration->getCollectedData(), \false);
// hydrate abstract collector rector with configuration
foreach ($this->collectorRectors as $collectorRector) {
$collectorRector->setCollectedDataNode($collectedDataNode);
}
$this->visitors = $this->collectorRectors;
$this->areNodeVisitorsPrepared = \true;
}
/**
* This must happen after $this->configuration is set after ProcessCommand::execute() is run,
* otherwise we get default false positives.
@ -62,8 +84,11 @@ final class RectorNodeTraverser extends NodeTraverser
return;
}
// filer out by version
$activePhpRectors = $this->phpVersionedFilter->filter($this->rectors);
$this->visitors = \array_merge($this->visitors, $activePhpRectors);
$activeRectors = $this->phpVersionedFilter->filter($this->rectors);
$nonCollectorActiveRectors = \array_filter($activeRectors, static function (RectorInterface $rector) : bool {
return !$rector instanceof CollectorRectorInterface;
});
$this->visitors = \array_merge($this->visitors, $nonCollectorActiveRectors);
$this->areNodeVisitorsPrepared = \true;
}
}

View File

@ -0,0 +1,32 @@
<?php
declare (strict_types=1);
namespace Rector\Core\Rector;
use PHPStan\Node\CollectedDataNode;
use Rector\Core\Contract\Rector\CollectorRectorInterface;
use Rector\Core\Exception\ShouldNotHappenException;
use RectorPrefix202309\Webmozart\Assert\Assert;
abstract class AbstractCollectorRector extends \Rector\Core\Rector\AbstractRector implements CollectorRectorInterface
{
/**
* @var \PHPStan\Node\CollectedDataNode|null
*/
private $collectedDataNode;
/**
* @api used via optional contract
*/
public function setCollectedDataNode(CollectedDataNode $collectedDataNode) : void
{
Assert::isAOf(static::class, CollectorRectorInterface::class);
$this->collectedDataNode = $collectedDataNode;
}
public function getCollectedDataNode() : CollectedDataNode
{
if (!$this->collectedDataNode instanceof CollectedDataNode) {
throw new ShouldNotHappenException('CollectedDataNode is not set');
}
// this should be called only from CollectorRectorInterface
return $this->collectedDataNode;
}
}

View File

@ -68,6 +68,11 @@ final class Configuration
* @var bool
*/
private $isDebug = \false;
/**
* @readonly
* @var bool
*/
private $isCollectors = \false;
/**
* @var bool
*/
@ -80,7 +85,7 @@ final class Configuration
* @param string[] $fileExtensions
* @param string[] $paths
*/
public function __construct(bool $isDryRun = \false, bool $showProgressBar = \true, bool $shouldClearCache = \false, string $outputFormat = ConsoleOutputFormatter::NAME, array $fileExtensions = ['php'], array $paths = [], bool $showDiffs = \true, ?string $parallelPort = null, ?string $parallelIdentifier = null, bool $isParallel = \false, ?string $memoryLimit = null, bool $isDebug = \false)
public function __construct(bool $isDryRun = \false, bool $showProgressBar = \true, bool $shouldClearCache = \false, string $outputFormat = ConsoleOutputFormatter::NAME, array $fileExtensions = ['php'], array $paths = [], bool $showDiffs = \true, ?string $parallelPort = null, ?string $parallelIdentifier = null, bool $isParallel = \false, ?string $memoryLimit = null, bool $isDebug = \false, bool $isCollectors = \false)
{
$this->isDryRun = $isDryRun;
$this->showProgressBar = $showProgressBar;
@ -94,6 +99,7 @@ final class Configuration
$this->isParallel = $isParallel;
$this->memoryLimit = $memoryLimit;
$this->isDebug = $isDebug;
$this->isCollectors = $isCollectors;
}
public function isDryRun() : bool
{
@ -151,18 +157,16 @@ final class Configuration
return $this->isDebug;
}
/**
* @api
* @param CollectedData[] $collectedDatas
* @param CollectedData[] $collectedData
*/
public function setCollectedDatas(array $collectedDatas) : void
public function setCollectedData(array $collectedData) : void
{
$this->collectedData = $collectedDatas;
$this->collectedData = $collectedData;
}
/**
* @api
* @return CollectedData[]
*/
public function getCollectedDatas() : array
public function getCollectedData() : array
{
return $this->collectedData;
}
@ -180,4 +184,18 @@ final class Configuration
{
return $this->isSecondRun;
}
/**
* @api used in tests
*/
public function reset() : void
{
$this->isSecondRun = \false;
}
/**
* @api
*/
public function isCollectors() : bool
{
return $this->isCollectors;
}
}

View File

@ -6,6 +6,7 @@ namespace Rector\Core\ValueObject;
use PHPStan\Collectors\CollectedData;
use Rector\Core\ValueObject\Error\SystemError;
use Rector\Core\ValueObject\Reporting\FileDiff;
use RectorPrefix202309\Webmozart\Assert\Assert;
final class FileProcessResult
{
/**
@ -22,16 +23,18 @@ final class FileProcessResult
* @var CollectedData[]
* @readonly
*/
private $collectedData;
private $collectedDatas;
/**
* @param SystemError[] $systemErrors
* @param CollectedData[] $collectedData
* @param CollectedData[] $collectedDatas
*/
public function __construct(array $systemErrors, ?FileDiff $fileDiff, array $collectedData)
public function __construct(array $systemErrors, ?FileDiff $fileDiff, array $collectedDatas)
{
$this->systemErrors = $systemErrors;
$this->fileDiff = $fileDiff;
$this->collectedData = $collectedData;
$this->collectedDatas = $collectedDatas;
Assert::allIsInstanceOf($systemErrors, SystemError::class);
Assert::allIsInstanceOf($collectedDatas, CollectedData::class);
}
/**
* @return SystemError[]
@ -49,6 +52,6 @@ final class FileProcessResult
*/
public function getCollectedData() : array
{
return $this->collectedData;
return $this->collectedDatas;
}
}

2
vendor/autoload.php vendored
View File

@ -22,4 +22,4 @@ if (PHP_VERSION_ID < 50600) {
require_once __DIR__ . '/composer/autoload_real.php';
return ComposerAutoloaderIniteb8b71a07cc01b1bdf06402c4a91c2cb::getLoader();
return ComposerAutoloaderInit9a5baaca6ad7ba8e6ad063003e0a6fee::getLoader();

View File

@ -1175,6 +1175,7 @@ return array(
'Rector\\Core\\Console\\Style\\SymfonyStyleFactory' => $baseDir . '/src/Console/Style/SymfonyStyleFactory.php',
'Rector\\Core\\Contract\\DependencyInjection\\ResetableInterface' => $baseDir . '/src/Contract/DependencyInjection/ResetableInterface.php',
'Rector\\Core\\Contract\\PhpParser\\Node\\StmtsAwareInterface' => $baseDir . '/src/Contract/PhpParser/Node/StmtsAwareInterface.php',
'Rector\\Core\\Contract\\Rector\\CollectorRectorInterface' => $baseDir . '/src/Contract/Rector/CollectorRectorInterface.php',
'Rector\\Core\\Contract\\Rector\\ConfigurableRectorInterface' => $baseDir . '/src/Contract/Rector/ConfigurableRectorInterface.php',
'Rector\\Core\\Contract\\Rector\\RectorInterface' => $baseDir . '/src/Contract/Rector/RectorInterface.php',
'Rector\\Core\\Contract\\Rector\\ScopeAwareRectorInterface' => $baseDir . '/src/Contract/Rector/ScopeAwareRectorInterface.php',
@ -1259,6 +1260,7 @@ return array(
'Rector\\Core\\Php\\ReservedKeywordAnalyzer' => $baseDir . '/src/Php/ReservedKeywordAnalyzer.php',
'Rector\\Core\\ProcessAnalyzer\\RectifiedAnalyzer' => $baseDir . '/src/ProcessAnalyzer/RectifiedAnalyzer.php',
'Rector\\Core\\Provider\\CurrentFileProvider' => $baseDir . '/src/Provider/CurrentFileProvider.php',
'Rector\\Core\\Rector\\AbstractCollectorRector' => $baseDir . '/src/Rector/AbstractCollectorRector.php',
'Rector\\Core\\Rector\\AbstractRector' => $baseDir . '/src/Rector/AbstractRector.php',
'Rector\\Core\\Rector\\AbstractScopeAwareRector' => $baseDir . '/src/Rector/AbstractScopeAwareRector.php',
'Rector\\Core\\Reflection\\ClassReflectionAnalyzer' => $baseDir . '/src/Reflection/ClassReflectionAnalyzer.php',
@ -1943,6 +1945,7 @@ return array(
'Rector\\Privatization\\Guard\\ParentPropertyLookupGuard' => $baseDir . '/rules/Privatization/Guard/ParentPropertyLookupGuard.php',
'Rector\\Privatization\\NodeManipulator\\VisibilityManipulator' => $baseDir . '/rules/Privatization/NodeManipulator/VisibilityManipulator.php',
'Rector\\Privatization\\Rector\\ClassMethod\\PrivatizeFinalClassMethodRector' => $baseDir . '/rules/Privatization/Rector/ClassMethod/PrivatizeFinalClassMethodRector.php',
'Rector\\Privatization\\Rector\\Class_\\FinalizeClassesWithoutChildrenCollectorRector' => $baseDir . '/rules/Privatization/Rector/Class_/FinalizeClassesWithoutChildrenCollectorRector.php',
'Rector\\Privatization\\Rector\\Class_\\FinalizeClassesWithoutChildrenRector' => $baseDir . '/rules/Privatization/Rector/Class_/FinalizeClassesWithoutChildrenRector.php',
'Rector\\Privatization\\Rector\\MethodCall\\PrivatizeLocalGetterToPropertyRector' => $baseDir . '/rules/Privatization/Rector/MethodCall/PrivatizeLocalGetterToPropertyRector.php',
'Rector\\Privatization\\Rector\\Property\\PrivatizeFinalClassPropertyRector' => $baseDir . '/rules/Privatization/Rector/Property/PrivatizeFinalClassPropertyRector.php',
@ -2255,6 +2258,7 @@ return array(
'Rector\\TypeDeclaration\\AlreadyAssignDetector\\ConstructorAssignDetector' => $baseDir . '/rules/TypeDeclaration/AlreadyAssignDetector/ConstructorAssignDetector.php',
'Rector\\TypeDeclaration\\AlreadyAssignDetector\\NullTypeAssignDetector' => $baseDir . '/rules/TypeDeclaration/AlreadyAssignDetector/NullTypeAssignDetector.php',
'Rector\\TypeDeclaration\\AlreadyAssignDetector\\PropertyDefaultAssignDetector' => $baseDir . '/rules/TypeDeclaration/AlreadyAssignDetector/PropertyDefaultAssignDetector.php',
'Rector\\TypeDeclaration\\Collector\\ParentClassCollector' => $baseDir . '/rules/TypeDeclaration/Collector/ParentClassCollector.php',
'Rector\\TypeDeclaration\\Contract\\PHPStan\\TypeWithClassTypeSpecifierInterface' => $baseDir . '/rules/TypeDeclaration/Contract/PHPStan/TypeWithClassTypeSpecifierInterface.php',
'Rector\\TypeDeclaration\\FunctionLikeReturnTypeResolver' => $baseDir . '/rules/TypeDeclaration/FunctionLikeReturnTypeResolver.php',
'Rector\\TypeDeclaration\\Guard\\ParamTypeAddGuard' => $baseDir . '/rules/TypeDeclaration/Guard/ParamTypeAddGuard.php',

View File

@ -2,7 +2,7 @@
// autoload_real.php @generated by Composer
class ComposerAutoloaderIniteb8b71a07cc01b1bdf06402c4a91c2cb
class ComposerAutoloaderInit9a5baaca6ad7ba8e6ad063003e0a6fee
{
private static $loader;
@ -22,17 +22,17 @@ class ComposerAutoloaderIniteb8b71a07cc01b1bdf06402c4a91c2cb
return self::$loader;
}
spl_autoload_register(array('ComposerAutoloaderIniteb8b71a07cc01b1bdf06402c4a91c2cb', 'loadClassLoader'), true, true);
spl_autoload_register(array('ComposerAutoloaderInit9a5baaca6ad7ba8e6ad063003e0a6fee', 'loadClassLoader'), true, true);
self::$loader = $loader = new \Composer\Autoload\ClassLoader(\dirname(__DIR__));
spl_autoload_unregister(array('ComposerAutoloaderIniteb8b71a07cc01b1bdf06402c4a91c2cb', 'loadClassLoader'));
spl_autoload_unregister(array('ComposerAutoloaderInit9a5baaca6ad7ba8e6ad063003e0a6fee', 'loadClassLoader'));
require __DIR__ . '/autoload_static.php';
call_user_func(\Composer\Autoload\ComposerStaticIniteb8b71a07cc01b1bdf06402c4a91c2cb::getInitializer($loader));
call_user_func(\Composer\Autoload\ComposerStaticInit9a5baaca6ad7ba8e6ad063003e0a6fee::getInitializer($loader));
$loader->setClassMapAuthoritative(true);
$loader->register(true);
$filesToLoad = \Composer\Autoload\ComposerStaticIniteb8b71a07cc01b1bdf06402c4a91c2cb::$files;
$filesToLoad = \Composer\Autoload\ComposerStaticInit9a5baaca6ad7ba8e6ad063003e0a6fee::$files;
$requireFile = \Closure::bind(static function ($fileIdentifier, $file) {
if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) {
$GLOBALS['__composer_autoload_files'][$fileIdentifier] = true;

View File

@ -4,7 +4,7 @@
namespace Composer\Autoload;
class ComposerStaticIniteb8b71a07cc01b1bdf06402c4a91c2cb
class ComposerStaticInit9a5baaca6ad7ba8e6ad063003e0a6fee
{
public static $files = array (
'ad155f8f1cf0d418fe49e248db8c661b' => __DIR__ . '/..' . '/react/promise/src/functions_include.php',
@ -1395,6 +1395,7 @@ class ComposerStaticIniteb8b71a07cc01b1bdf06402c4a91c2cb
'Rector\\Core\\Console\\Style\\SymfonyStyleFactory' => __DIR__ . '/../..' . '/src/Console/Style/SymfonyStyleFactory.php',
'Rector\\Core\\Contract\\DependencyInjection\\ResetableInterface' => __DIR__ . '/../..' . '/src/Contract/DependencyInjection/ResetableInterface.php',
'Rector\\Core\\Contract\\PhpParser\\Node\\StmtsAwareInterface' => __DIR__ . '/../..' . '/src/Contract/PhpParser/Node/StmtsAwareInterface.php',
'Rector\\Core\\Contract\\Rector\\CollectorRectorInterface' => __DIR__ . '/../..' . '/src/Contract/Rector/CollectorRectorInterface.php',
'Rector\\Core\\Contract\\Rector\\ConfigurableRectorInterface' => __DIR__ . '/../..' . '/src/Contract/Rector/ConfigurableRectorInterface.php',
'Rector\\Core\\Contract\\Rector\\RectorInterface' => __DIR__ . '/../..' . '/src/Contract/Rector/RectorInterface.php',
'Rector\\Core\\Contract\\Rector\\ScopeAwareRectorInterface' => __DIR__ . '/../..' . '/src/Contract/Rector/ScopeAwareRectorInterface.php',
@ -1479,6 +1480,7 @@ class ComposerStaticIniteb8b71a07cc01b1bdf06402c4a91c2cb
'Rector\\Core\\Php\\ReservedKeywordAnalyzer' => __DIR__ . '/../..' . '/src/Php/ReservedKeywordAnalyzer.php',
'Rector\\Core\\ProcessAnalyzer\\RectifiedAnalyzer' => __DIR__ . '/../..' . '/src/ProcessAnalyzer/RectifiedAnalyzer.php',
'Rector\\Core\\Provider\\CurrentFileProvider' => __DIR__ . '/../..' . '/src/Provider/CurrentFileProvider.php',
'Rector\\Core\\Rector\\AbstractCollectorRector' => __DIR__ . '/../..' . '/src/Rector/AbstractCollectorRector.php',
'Rector\\Core\\Rector\\AbstractRector' => __DIR__ . '/../..' . '/src/Rector/AbstractRector.php',
'Rector\\Core\\Rector\\AbstractScopeAwareRector' => __DIR__ . '/../..' . '/src/Rector/AbstractScopeAwareRector.php',
'Rector\\Core\\Reflection\\ClassReflectionAnalyzer' => __DIR__ . '/../..' . '/src/Reflection/ClassReflectionAnalyzer.php',
@ -2163,6 +2165,7 @@ class ComposerStaticIniteb8b71a07cc01b1bdf06402c4a91c2cb
'Rector\\Privatization\\Guard\\ParentPropertyLookupGuard' => __DIR__ . '/../..' . '/rules/Privatization/Guard/ParentPropertyLookupGuard.php',
'Rector\\Privatization\\NodeManipulator\\VisibilityManipulator' => __DIR__ . '/../..' . '/rules/Privatization/NodeManipulator/VisibilityManipulator.php',
'Rector\\Privatization\\Rector\\ClassMethod\\PrivatizeFinalClassMethodRector' => __DIR__ . '/../..' . '/rules/Privatization/Rector/ClassMethod/PrivatizeFinalClassMethodRector.php',
'Rector\\Privatization\\Rector\\Class_\\FinalizeClassesWithoutChildrenCollectorRector' => __DIR__ . '/../..' . '/rules/Privatization/Rector/Class_/FinalizeClassesWithoutChildrenCollectorRector.php',
'Rector\\Privatization\\Rector\\Class_\\FinalizeClassesWithoutChildrenRector' => __DIR__ . '/../..' . '/rules/Privatization/Rector/Class_/FinalizeClassesWithoutChildrenRector.php',
'Rector\\Privatization\\Rector\\MethodCall\\PrivatizeLocalGetterToPropertyRector' => __DIR__ . '/../..' . '/rules/Privatization/Rector/MethodCall/PrivatizeLocalGetterToPropertyRector.php',
'Rector\\Privatization\\Rector\\Property\\PrivatizeFinalClassPropertyRector' => __DIR__ . '/../..' . '/rules/Privatization/Rector/Property/PrivatizeFinalClassPropertyRector.php',
@ -2475,6 +2478,7 @@ class ComposerStaticIniteb8b71a07cc01b1bdf06402c4a91c2cb
'Rector\\TypeDeclaration\\AlreadyAssignDetector\\ConstructorAssignDetector' => __DIR__ . '/../..' . '/rules/TypeDeclaration/AlreadyAssignDetector/ConstructorAssignDetector.php',
'Rector\\TypeDeclaration\\AlreadyAssignDetector\\NullTypeAssignDetector' => __DIR__ . '/../..' . '/rules/TypeDeclaration/AlreadyAssignDetector/NullTypeAssignDetector.php',
'Rector\\TypeDeclaration\\AlreadyAssignDetector\\PropertyDefaultAssignDetector' => __DIR__ . '/../..' . '/rules/TypeDeclaration/AlreadyAssignDetector/PropertyDefaultAssignDetector.php',
'Rector\\TypeDeclaration\\Collector\\ParentClassCollector' => __DIR__ . '/../..' . '/rules/TypeDeclaration/Collector/ParentClassCollector.php',
'Rector\\TypeDeclaration\\Contract\\PHPStan\\TypeWithClassTypeSpecifierInterface' => __DIR__ . '/../..' . '/rules/TypeDeclaration/Contract/PHPStan/TypeWithClassTypeSpecifierInterface.php',
'Rector\\TypeDeclaration\\FunctionLikeReturnTypeResolver' => __DIR__ . '/../..' . '/rules/TypeDeclaration/FunctionLikeReturnTypeResolver.php',
'Rector\\TypeDeclaration\\Guard\\ParamTypeAddGuard' => __DIR__ . '/../..' . '/rules/TypeDeclaration/Guard/ParamTypeAddGuard.php',
@ -2596,9 +2600,9 @@ class ComposerStaticIniteb8b71a07cc01b1bdf06402c4a91c2cb
public static function getInitializer(ClassLoader $loader)
{
return \Closure::bind(function () use ($loader) {
$loader->prefixLengthsPsr4 = ComposerStaticIniteb8b71a07cc01b1bdf06402c4a91c2cb::$prefixLengthsPsr4;
$loader->prefixDirsPsr4 = ComposerStaticIniteb8b71a07cc01b1bdf06402c4a91c2cb::$prefixDirsPsr4;
$loader->classMap = ComposerStaticIniteb8b71a07cc01b1bdf06402c4a91c2cb::$classMap;
$loader->prefixLengthsPsr4 = ComposerStaticInit9a5baaca6ad7ba8e6ad063003e0a6fee::$prefixLengthsPsr4;
$loader->prefixDirsPsr4 = ComposerStaticInit9a5baaca6ad7ba8e6ad063003e0a6fee::$prefixDirsPsr4;
$loader->classMap = ComposerStaticInit9a5baaca6ad7ba8e6ad063003e0a6fee::$classMap;
}, null, ClassLoader::class);
}