diff --git a/composer.json b/composer.json index 0181e8063402..e5105c01f54c 100644 --- a/composer.json +++ b/composer.json @@ -36,9 +36,6 @@ "nette/robot-loader": "^3.2", "nette/utils": "^3.2", "nikic/php-parser": "^4.10.4", - "ondrejmirtes/better-reflection": "^4.3.50", - "jetbrains/phpstorm-stubs": "2020.2 as dev-master", - "roave/signature": "1.4 as 1.1.0", "phpstan/phpdoc-parser": "^0.4.9", "phpstan/phpstan": "^0.12.76", "phpstan/phpstan-phpunit": "^0.12.17", diff --git a/packages/better-php-doc-parser/src/AnnotationReader/NodeAnnotationReader.php b/packages/better-php-doc-parser/src/AnnotationReader/NodeAnnotationReader.php index f537499444d8..4cb3f16ee928 100644 --- a/packages/better-php-doc-parser/src/AnnotationReader/NodeAnnotationReader.php +++ b/packages/better-php-doc-parser/src/AnnotationReader/NodeAnnotationReader.php @@ -15,7 +15,6 @@ use Rector\DoctrineAnnotationGenerated\PhpDocNode\ConstantReferenceIdentifierRestorer; use Rector\NodeNameResolver\NodeNameResolver; use Rector\NodeTypeResolver\Node\AttributeKey; -use ReflectionClass; use ReflectionProperty; use Symplify\PackageBuilder\Reflection\PrivatesAccessor; use Throwable; @@ -51,12 +50,14 @@ public function __construct( ConstantReferenceIdentifierRestorer $constantReferenceIdentifierRestorer, NodeNameResolver $nodeNameResolver, Reader $reader, - ReflectionProvider $reflectionProvider + ReflectionProvider $reflectionProvider, + PrivatesAccessor $privatesAccessor ) { $this->reader = $reader; $this->nodeNameResolver = $nodeNameResolver; $this->constantReferenceIdentifierRestorer = $constantReferenceIdentifierRestorer; $this->reflectionProvider = $reflectionProvider; + $this->privatesAccessor = $privatesAccessor; } public function readAnnotation(Node $node, string $annotationClass): ?object @@ -100,7 +101,6 @@ public function readPropertyAnnotation(Property $property, string $annotationCla try { // covers cases like https://github.com/rectorphp/rector/issues/3046 - // @todo this will require original reflection /** @var object[] $propertyAnnotations */ $propertyAnnotations = $this->reader->getPropertyAnnotations($propertyReflection); return $this->matchNextAnnotation($propertyAnnotations, $annotationClassName, $property); @@ -122,8 +122,7 @@ private function readMethodAnnotation(ClassMethod $classMethod, string $annotati $methodReflection = $reflectionClass->getNativeMethod($methodName); // @see https://github.com/phpstan/phpstan-src/commit/5fad625b7770b9c5beebb19ccc1a493839308fb4 - $privatesAccessor = new PrivatesAccessor(); - $nativeMethodReflection = $privatesAccessor->getPrivateProperty($methodReflection, 'reflection'); + $nativeMethodReflection = $this->privatesAccessor->getPrivateProperty($methodReflection, 'reflection'); try { // covers cases like https://github.com/rectorphp/rector/issues/3046 @@ -159,9 +158,7 @@ private function createClassReflectionFromNode(Class_ $class): ClassReflection $className = $this->nodeNameResolver->getName($class); // covers cases like https://github.com/rectorphp/rector/issues/3230#issuecomment-683317288 - return $this->reflectionProvider->getClass($className); -// return new ReflectionClass($className); } /** @@ -211,10 +208,7 @@ private function getNativePropertyReflection(Property $property): ?ReflectionPro $propertyReflection = $classReflection->getProperty($propertyName, $propertyScope); // @see https://github.com/phpstan/phpstan-src/commit/5fad625b7770b9c5beebb19ccc1a493839308fb4 - $privatesAccessor = new PrivatesAccessor(); - return $privatesAccessor->getPrivateProperty($propertyReflection, 'reflection'); - - // return new ReflectionProperty($className, $propertyName); + return $this->privatesAccessor->getPrivateProperty($propertyReflection, 'reflection'); } catch (Throwable $throwable) { // in case of PHPUnit property or just-added property return null; diff --git a/packages/node-type-resolver/config/config.php b/packages/node-type-resolver/config/config.php index 7dc10e311ddd..5b08c788db4b 100644 --- a/packages/node-type-resolver/config/config.php +++ b/packages/node-type-resolver/config/config.php @@ -13,6 +13,8 @@ use Rector\Core\PhpParser\Node\BetterNodeFinder; use Rector\Core\PhpParser\Printer\BetterStandardPrinter; use Rector\NodeTypeResolver\DependencyInjection\PHPStanServicesFactory; +use Rector\NodeTypeResolver\Reflection\BetterReflection\SourceLocator\IntermediateSourceLocator; +use Rector\NodeTypeResolver\Reflection\BetterReflection\SourceLocatorProvider\DynamicSourceLocator; use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator; use function Symfony\Component\DependencyInjection\Loader\Configurator\service; @@ -29,7 +31,10 @@ ->autoconfigure(); $services->load('Rector\NodeTypeResolver\\', __DIR__ . '/../src') - ->exclude([__DIR__ . '/../src/Contract']); + ->exclude([__DIR__ . '/../src/Contract', __DIR__ . '/../src/Reflection/BetterReflection']); + + $services->set(IntermediateSourceLocator::class); + // $services->set(DynamicSourceLocatorProvider::class); $services->set(TypeAnalyzer::class); $services->set(FilesFinder::class); @@ -48,5 +53,8 @@ $services->set(TypeNodeResolver::class) ->factory([service(PHPStanServicesFactory::class), 'createTypeNodeResolver']); + $services->set(DynamicSourceLocator::class) + ->factory([service(PHPStanServicesFactory::class), 'createDynamicSourceLocatorProvider']); + $services->set(NodeConnectingVisitor::class); }; diff --git a/packages/node-type-resolver/config/phpstan/static-reflection.neon b/packages/node-type-resolver/config/phpstan/static-reflection.neon index 5c225bc0cf09..efd5a7e2de95 100644 --- a/packages/node-type-resolver/config/phpstan/static-reflection.neon +++ b/packages/node-type-resolver/config/phpstan/static-reflection.neon @@ -5,17 +5,11 @@ parameters: services: - Rector\NodeTypeResolver\Reflection\BetterReflection\RectorBetterReflectionSourceLocatorFactory + - Rector\NodeTypeResolver\Reflection\BetterReflection\SourceLocator\IntermediateSourceLocator + - Rector\NodeTypeResolver\Reflection\BetterReflection\SourceLocatorProvider\DynamicSourceLocator # basically decorates native PHPStan source locator with a dynamic source locator that is also available in Rector DI betterReflectionSourceLocator: - class: Roave\BetterReflection\SourceLocator\Type\SourceLocator - factory: @Rector\NodeTypeResolver\Reflection\BetterReflection\RectorBetterReflectionSourceLocatorFactory::create - arguments: - sourceLocator: @defaultBetterReflectionSourceLocator - autowired: false - - # see https://github.com/phpstan/phpstan-src/blob/78a9f057d7a1c73cc34af70db406b9392ce0ca3a/conf/config.neon#L1332-L1335 - defaultBetterReflectionSourceLocator: - class: Roave\BetterReflection\SourceLocator\Type\SourceLocator - factory: @PHPStan\Reflection\BetterReflection\BetterReflectionSourceLocatorFactory::create + class: _HumbugBoxfac515c46e83\Roave\BetterReflection\SourceLocator\Type\SourceLocator + factory: ['@Rector\NodeTypeResolver\Reflection\BetterReflection\RectorBetterReflectionSourceLocatorFactory', 'create'] autowired: false diff --git a/packages/node-type-resolver/src/DependencyInjection/PHPStanServicesFactory.php b/packages/node-type-resolver/src/DependencyInjection/PHPStanServicesFactory.php index 63f3d0bebc42..a18edd8c7ea3 100644 --- a/packages/node-type-resolver/src/DependencyInjection/PHPStanServicesFactory.php +++ b/packages/node-type-resolver/src/DependencyInjection/PHPStanServicesFactory.php @@ -15,6 +15,7 @@ use PHPStan\PhpDoc\TypeNodeResolver; use PHPStan\Reflection\ReflectionProvider; use Rector\Core\Configuration\Option; +use Rector\NodeTypeResolver\Reflection\BetterReflection\SourceLocatorProvider\DynamicSourceLocator; use Symplify\PackageBuilder\Parameter\ParameterProvider; /** @@ -39,19 +40,7 @@ public function __construct(ParameterProvider $parameterProvider) $existingAdditionalConfigFiles = array_filter($additionalConfigFiles, 'file_exists'); - // this allows to statically autoload files from Rector tests - $analysedPathsFromConfig = []; - if (defined('RECTOR_REPOSITORY')) { - $analysedPathsFromConfig[] = sys_get_temp_dir() . '/_temp_fixture_easy_testing'; - } - - $this->container = $containerFactory->create( - sys_get_temp_dir(), - $existingAdditionalConfigFiles, - [], - [], - $analysedPathsFromConfig - ); + $this->container = $containerFactory->create(sys_get_temp_dir(), $existingAdditionalConfigFiles, []); } /** @@ -117,4 +106,12 @@ public function createTypeNodeResolver(): TypeNodeResolver { return $this->container->getByType(TypeNodeResolver::class); } + + /** + * @api + */ + public function createDynamicSourceLocatorProvider(): DynamicSourceLocator + { + return $this->container->getByType(DynamicSourceLocator::class); + } } diff --git a/packages/node-type-resolver/src/Reflection/BetterReflection/RectorBetterReflectionSourceLocatorFactory.php b/packages/node-type-resolver/src/Reflection/BetterReflection/RectorBetterReflectionSourceLocatorFactory.php index 7e05f91f2216..726457893044 100644 --- a/packages/node-type-resolver/src/Reflection/BetterReflection/RectorBetterReflectionSourceLocatorFactory.php +++ b/packages/node-type-resolver/src/Reflection/BetterReflection/RectorBetterReflectionSourceLocatorFactory.php @@ -4,10 +4,34 @@ namespace Rector\NodeTypeResolver\Reflection\BetterReflection; +use _HumbugBoxfac515c46e83\Roave\BetterReflection\SourceLocator\Type\AggregateSourceLocator; +use _HumbugBoxfac515c46e83\Roave\BetterReflection\SourceLocator\Type\SourceLocator; +use PHPStan\Reflection\BetterReflection\BetterReflectionSourceLocatorFactory; +use Rector\NodeTypeResolver\Reflection\BetterReflection\SourceLocator\IntermediateSourceLocator; + final class RectorBetterReflectionSourceLocatorFactory { - public function __construct(\Roave\BetterReflection\SourceLocator\Type\SourceLocator $sourceLocator) + /** + * @var BetterReflectionSourceLocatorFactory + */ + private $betterReflectionSourceLocatorFactory; + + /** + * @var IntermediateSourceLocator + */ + private $intermediateSourceLocator; + + public function __construct( + BetterReflectionSourceLocatorFactory $betterReflectionSourceLocatorFactory, + IntermediateSourceLocator $intermediateSourceLocator + ) { + $this->betterReflectionSourceLocatorFactory = $betterReflectionSourceLocatorFactory; + $this->intermediateSourceLocator = $intermediateSourceLocator; + } + + public function create(): SourceLocator { - dump($sourceLocator); + $phpStanSourceLocator = $this->betterReflectionSourceLocatorFactory->create(); + return new AggregateSourceLocator([$this->intermediateSourceLocator, $phpStanSourceLocator]); } } diff --git a/packages/node-type-resolver/src/Reflection/BetterReflection/SourceLocator/IntermediateSourceLocator.php b/packages/node-type-resolver/src/Reflection/BetterReflection/SourceLocator/IntermediateSourceLocator.php new file mode 100644 index 000000000000..278c2b0a6802 --- /dev/null +++ b/packages/node-type-resolver/src/Reflection/BetterReflection/SourceLocator/IntermediateSourceLocator.php @@ -0,0 +1,53 @@ +dynamicSourceLocator = $dynamicSourceLocator; + } + + public function locateIdentifier(Reflector $reflector, Identifier $identifier): ?Reflection + { + $sourceLocator = $this->dynamicSourceLocator->provide(); + + $locatedIdentifier = $sourceLocator->locateIdentifier($reflector, $identifier); + if ($locatedIdentifier instanceof Reflection) { + return $locatedIdentifier; + } + + return null; + } + + /** + * Find all identifiers of a type + * @return Reflection[] + */ + public function locateIdentifiersByType(Reflector $reflector, IdentifierType $identifierType): array + { + $sourceLocator = $this->dynamicSourceLocator->provide(); + + $reflections = $sourceLocator->locateIdentifiersByType($reflector, $identifierType); + if ($reflections !== []) { + return $reflections; + } + + return []; + } +} diff --git a/packages/node-type-resolver/src/Reflection/BetterReflection/SourceLocatorProvider/DynamicSourceLocator.php b/packages/node-type-resolver/src/Reflection/BetterReflection/SourceLocatorProvider/DynamicSourceLocator.php new file mode 100644 index 000000000000..a01650d3afff --- /dev/null +++ b/packages/node-type-resolver/src/Reflection/BetterReflection/SourceLocatorProvider/DynamicSourceLocator.php @@ -0,0 +1,77 @@ +parser = $parser; +// $this->container = $container; + $this->fileNodesFetcher = $fileNodesFetcher; + } + +// public function addDirectory(string $directory): void +// { +// $this->directories[] = $directory; +// } + + public function addFileInfo(SmartFileInfo $fileInfo): void + { + $this->fileInfos[] = $fileInfo; + } + + public function provide(): SourceLocator + { +// $locator = new Locator($this->parser, function (): FunctionReflector { +// return $this->container->getService('betterReflectionFunctionReflector'); +// }); +// + $sourceLocators = []; +// $sourceLocators[] = new DirectoriesSourceLocator($this->directories, $locator); + + foreach ($this->fileInfos as $fileInfo) { + $sourceLocators[] = new OptimizedSingleFileSourceLocator($this->fileNodesFetcher, $fileInfo->getRealPath()); + } + + return new AggregateSourceLocator($sourceLocators); + } +} diff --git a/packages/testing/src/PHPUnit/AbstractRectorTestCase.php b/packages/testing/src/PHPUnit/AbstractRectorTestCase.php index 60fe2761cbc5..6f9c04ba5a52 100644 --- a/packages/testing/src/PHPUnit/AbstractRectorTestCase.php +++ b/packages/testing/src/PHPUnit/AbstractRectorTestCase.php @@ -20,6 +20,7 @@ use Rector\Core\PhpParser\Printer\BetterStandardPrinter; use Rector\Core\Stubs\StubLoader; use Rector\Core\ValueObject\StaticNonPhpFileSuffixes; +use Rector\NodeTypeResolver\Reflection\BetterReflection\SourceLocatorProvider\DynamicSourceLocator; use Rector\Testing\Application\EnabledRectorClassProvider; use Rector\Testing\Configuration\AllRectorConfigFactory; use Rector\Testing\Contract\RunnableInterface; @@ -180,6 +181,10 @@ protected function doTestFileInfo(SmartFileInfo $fixtureFileInfo, array $extraFi $nodeScopeResolver = $this->getService(NodeScopeResolver::class); $nodeScopeResolver->setAnalysedFiles([$inputFileInfo->getRealPath()]); + /** @var DynamicSourceLocator $dynamicDirectoryLocatorProvider */ + $dynamicDirectoryLocatorProvider = $this->getService(DynamicSourceLocator::class); + $dynamicDirectoryLocatorProvider->addFileInfo($inputFileInfo); + $expectedFileInfo = $inputFileInfoAndExpectedFileInfo->getExpectedFileInfo(); $this->doTestFileMatchesExpectedContent($inputFileInfo, $expectedFileInfo, $fixtureFileInfo, $extraFileInfos); diff --git a/rules/renaming/src/NodeManipulator/ClassRenamer.php b/rules/renaming/src/NodeManipulator/ClassRenamer.php index 48ad3483f042..1535612688b1 100644 --- a/rules/renaming/src/NodeManipulator/ClassRenamer.php +++ b/rules/renaming/src/NodeManipulator/ClassRenamer.php @@ -189,10 +189,6 @@ private function refactorNamespace(Namespace_ $namespace, array $oldToNewClasses $currentName = $this->nodeNameResolver->getName($classLike); $newClassFullyQualified = $oldToNewClasses[$currentName]; - dump($this->reflectionProvider->hasClass($newClassFullyQualified)); - dump($newClassFullyQualified); - die; - if ($this->reflectionProvider->hasClass($newClassFullyQualified)) { return null; }