mirror of https://github.com/rectorphp/rector.git
Updated Rector to commit e530fc1e1a98faa22509115e79de5e5f2997208d
e530fc1e1a
Introducing Collectors - final step 🥳 - processing collected data + test case (#4970)
This commit is contained in:
parent
5ea7f9b378
commit
4ea05c5a5f
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
*/
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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';
|
||||
}
|
||||
|
|
|
@ -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
|
||||
{
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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()];
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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()"
|
||||
|
|
|
@ -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
|
||||
*/
|
||||
|
|
|
@ -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
|
||||
{
|
||||
|
|
|
@ -190,4 +190,9 @@ final class Option
|
|||
* @var string
|
||||
*/
|
||||
public const REGISTERED_RECTOR_SETS = 'registered_rector_sets';
|
||||
/**
|
||||
* @internal
|
||||
* @var string
|
||||
*/
|
||||
public const COLLECTORS = 'collectors';
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,4 +22,4 @@ if (PHP_VERSION_ID < 50600) {
|
|||
|
||||
require_once __DIR__ . '/composer/autoload_real.php';
|
||||
|
||||
return ComposerAutoloaderIniteb8b71a07cc01b1bdf06402c4a91c2cb::getLoader();
|
||||
return ComposerAutoloaderInit9a5baaca6ad7ba8e6ad063003e0a6fee::getLoader();
|
||||
|
|
|
@ -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',
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue