diff --git a/src/LocateDependencies/LocateDependenciesViaComposer.php b/src/LocateDependencies/LocateDependenciesViaComposer.php index 61985d8e..e179ab74 100644 --- a/src/LocateDependencies/LocateDependenciesViaComposer.php +++ b/src/LocateDependencies/LocateDependenciesViaComposer.php @@ -7,6 +7,7 @@ use Assert\Assert; use Composer\Installer; use Roave\BackwardCompatibility\SourceLocator\StaticClassMapSourceLocator; +use Roave\BackwardCompatibility\SourceLocator\StubClassSourceLocator; use Roave\BetterReflection\Reflection\ReflectionClass; use Roave\BetterReflection\Reflection\ReflectionProperty; use Roave\BetterReflection\Reflector\ClassReflector; @@ -80,6 +81,7 @@ public function __invoke(string $installationPath) : SourceLocator $this->sourceLocatorFromAutoloadStatic($generatedAutoloadClass), $this->sourceLocatorFromAutoloadFiles($generatedAutoloadClass), new PhpInternalSourceLocator($this->astLocator), + new StubClassSourceLocator($this->astLocator), ]); } diff --git a/src/SourceLocator/StubClassSourceLocator.php b/src/SourceLocator/StubClassSourceLocator.php new file mode 100644 index 00000000..7e7c2d67 --- /dev/null +++ b/src/SourceLocator/StubClassSourceLocator.php @@ -0,0 +1,41 @@ +isClass()) { + return null; + } + + if ($identifier->getName() === Identifier::WILDCARD) { + return null; + } + + $fqcn = $identifier->getName(); + $classNameParts = explode('\\', $fqcn); + $shortName = array_slice($classNameParts, -1)[0]; + $namespaceName = implode('\\', array_slice($classNameParts, 0, count($classNameParts) - 1)); + + return new LocatedSource( + sprintf('getValue($locator); - self::assertCount(3, $locators); + self::assertCount(4, $locators); self::assertEquals( new StaticClassMapSourceLocator( [ @@ -147,6 +148,7 @@ public function testWillLocateDependencies() : void $locators[1] ); self::assertInstanceOf(PhpInternalSourceLocator::class, $locators[2]); + self::assertInstanceOf(StubClassSourceLocator::class, $locators[3]); } public function testWillLocateDependenciesEvenWithoutAutoloadFiles() : void @@ -180,7 +182,7 @@ public function testWillLocateDependenciesEvenWithoutAutoloadFiles() : void $locators = $reflectionLocators->getValue($locator); - self::assertCount(3, $locators); + self::assertCount(4, $locators); self::assertEquals( new StaticClassMapSourceLocator( [ @@ -193,5 +195,6 @@ public function testWillLocateDependenciesEvenWithoutAutoloadFiles() : void ); self::assertEquals(new AggregateSourceLocator(), $locators[1]); self::assertInstanceOf(PhpInternalSourceLocator::class, $locators[2]); + self::assertInstanceOf(StubClassSourceLocator::class, $locators[3]); } } diff --git a/test/unit/SourceLocator/StubClassSourceLocatorTest.php b/test/unit/SourceLocator/StubClassSourceLocatorTest.php new file mode 100644 index 00000000..d25b2521 --- /dev/null +++ b/test/unit/SourceLocator/StubClassSourceLocatorTest.php @@ -0,0 +1,81 @@ +stubLocator = new StubClassSourceLocator($betterReflection->astLocator()); + $this->reflector = $betterReflection->classReflector(); + } + + public function testWillNotRetrieveSymbolsByType() : void + { + self::assertEmpty($this->stubLocator->locateIdentifiersByType( + $this->reflector, + new IdentifierType(IdentifierType::IDENTIFIER_CLASS) + )); + } + + public function testWillNotRetrieveFunctionReflections() : void + { + self::assertNull($this->stubLocator->locateIdentifier( + $this->reflector, + new Identifier('foo', new IdentifierType(IdentifierType::IDENTIFIER_FUNCTION)) + )); + } + + public function testWillReflectNonNamespacedClass() : void + { + /** @var ReflectionClass $class */ + $class = $this->stubLocator->locateIdentifier( + $this->reflector, + new Identifier('AClass', new IdentifierType(IdentifierType::IDENTIFIER_CLASS)) + ); + + self::assertInstanceOf(ReflectionClass::class, $class); + + self::assertSame('AClass', $class->getName()); + self::assertTrue($class->isInterface()); + self::assertFalse($class->inNamespace()); + } + + public function testWillReflectNamespacedClass() : void + { + /** @var ReflectionClass $class */ + $class = $this->stubLocator->locateIdentifier( + $this->reflector, + new Identifier('Foo\Bar\AClass', new IdentifierType(IdentifierType::IDENTIFIER_CLASS)) + ); + + self::assertInstanceOf(ReflectionClass::class, $class); + + self::assertSame('Foo\Bar\AClass', $class->getName()); + self::assertTrue($class->isInterface()); + self::assertTrue($class->inNamespace()); + } +}