Skip to content

Commit 9e95a60

Browse files
authored
Merge pull request Roave#74 from Roave/fix/Roave#67-ignore-not-found-classes-by-stubbing-them-to-empty-classes
Roave#67 stub out dependencies that cannot be located by using empty classes
2 parents cd87d1f + 3b48d6b commit 9e95a60

File tree

4 files changed

+129
-2
lines changed

4 files changed

+129
-2
lines changed

src/LocateDependencies/LocateDependenciesViaComposer.php

+2
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
use Assert\Assert;
88
use Composer\Installer;
99
use Roave\BackwardCompatibility\SourceLocator\StaticClassMapSourceLocator;
10+
use Roave\BackwardCompatibility\SourceLocator\StubClassSourceLocator;
1011
use Roave\BetterReflection\Reflection\ReflectionClass;
1112
use Roave\BetterReflection\Reflection\ReflectionProperty;
1213
use Roave\BetterReflection\Reflector\ClassReflector;
@@ -80,6 +81,7 @@ public function __invoke(string $installationPath) : SourceLocator
8081
$this->sourceLocatorFromAutoloadStatic($generatedAutoloadClass),
8182
$this->sourceLocatorFromAutoloadFiles($generatedAutoloadClass),
8283
new PhpInternalSourceLocator($this->astLocator),
84+
new StubClassSourceLocator($this->astLocator),
8385
]);
8486
}
8587

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Roave\BackwardCompatibility\SourceLocator;
6+
7+
use Roave\BetterReflection\Identifier\Identifier;
8+
use Roave\BetterReflection\SourceLocator\Located\LocatedSource;
9+
use Roave\BetterReflection\SourceLocator\Type\AbstractSourceLocator;
10+
use function array_slice;
11+
use function count;
12+
use function explode;
13+
use function implode;
14+
use function sprintf;
15+
16+
final class StubClassSourceLocator extends AbstractSourceLocator
17+
{
18+
/**
19+
* {@inheritDoc}
20+
*/
21+
protected function createLocatedSource(Identifier $identifier) : ?LocatedSource
22+
{
23+
if (! $identifier->isClass()) {
24+
return null;
25+
}
26+
27+
if ($identifier->getName() === Identifier::WILDCARD) {
28+
return null;
29+
}
30+
31+
$fqcn = $identifier->getName();
32+
$classNameParts = explode('\\', $fqcn);
33+
$shortName = array_slice($classNameParts, -1)[0];
34+
$namespaceName = implode('\\', array_slice($classNameParts, 0, count($classNameParts) - 1));
35+
36+
return new LocatedSource(
37+
sprintf('<?php namespace %s{interface %s {}}', $namespaceName, $shortName),
38+
null
39+
);
40+
}
41+
}

test/unit/LocateDependencies/LocateDependenciesViaComposerTest.php

+5-2
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
use PHPUnit\Framework\TestCase;
1010
use Roave\BackwardCompatibility\LocateDependencies\LocateDependenciesViaComposer;
1111
use Roave\BackwardCompatibility\SourceLocator\StaticClassMapSourceLocator;
12+
use Roave\BackwardCompatibility\SourceLocator\StubClassSourceLocator;
1213
use Roave\BetterReflection\BetterReflection;
1314
use Roave\BetterReflection\SourceLocator\Ast\Locator;
1415
use Roave\BetterReflection\SourceLocator\Type\AggregateSourceLocator;
@@ -122,7 +123,7 @@ public function testWillLocateDependencies() : void
122123

123124
$locators = $reflectionLocators->getValue($locator);
124125

125-
self::assertCount(3, $locators);
126+
self::assertCount(4, $locators);
126127
self::assertEquals(
127128
new StaticClassMapSourceLocator(
128129
[
@@ -147,6 +148,7 @@ public function testWillLocateDependencies() : void
147148
$locators[1]
148149
);
149150
self::assertInstanceOf(PhpInternalSourceLocator::class, $locators[2]);
151+
self::assertInstanceOf(StubClassSourceLocator::class, $locators[3]);
150152
}
151153

152154
public function testWillLocateDependenciesEvenWithoutAutoloadFiles() : void
@@ -180,7 +182,7 @@ public function testWillLocateDependenciesEvenWithoutAutoloadFiles() : void
180182

181183
$locators = $reflectionLocators->getValue($locator);
182184

183-
self::assertCount(3, $locators);
185+
self::assertCount(4, $locators);
184186
self::assertEquals(
185187
new StaticClassMapSourceLocator(
186188
[
@@ -193,5 +195,6 @@ public function testWillLocateDependenciesEvenWithoutAutoloadFiles() : void
193195
);
194196
self::assertEquals(new AggregateSourceLocator(), $locators[1]);
195197
self::assertInstanceOf(PhpInternalSourceLocator::class, $locators[2]);
198+
self::assertInstanceOf(StubClassSourceLocator::class, $locators[3]);
196199
}
197200
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace RoaveTest\BackwardCompatibility\SourceLocator;
6+
7+
use PHPUnit\Framework\TestCase;
8+
use Roave\BackwardCompatibility\SourceLocator\StubClassSourceLocator;
9+
use Roave\BetterReflection\BetterReflection;
10+
use Roave\BetterReflection\Identifier\Identifier;
11+
use Roave\BetterReflection\Identifier\IdentifierType;
12+
use Roave\BetterReflection\Reflection\ReflectionClass;
13+
use Roave\BetterReflection\Reflector\Reflector;
14+
15+
/**
16+
* @covers \Roave\BackwardCompatibility\SourceLocator\StubClassSourceLocator
17+
*/
18+
final class StubClassSourceLocatorTest extends TestCase
19+
{
20+
/** @var StubClassSourceLocator */
21+
private $stubLocator;
22+
23+
/** @var Reflector */
24+
private $reflector;
25+
26+
protected function setUp() : void
27+
{
28+
parent::setUp();
29+
30+
$betterReflection = new BetterReflection();
31+
32+
$this->stubLocator = new StubClassSourceLocator($betterReflection->astLocator());
33+
$this->reflector = $betterReflection->classReflector();
34+
}
35+
36+
public function testWillNotRetrieveSymbolsByType() : void
37+
{
38+
self::assertEmpty($this->stubLocator->locateIdentifiersByType(
39+
$this->reflector,
40+
new IdentifierType(IdentifierType::IDENTIFIER_CLASS)
41+
));
42+
}
43+
44+
public function testWillNotRetrieveFunctionReflections() : void
45+
{
46+
self::assertNull($this->stubLocator->locateIdentifier(
47+
$this->reflector,
48+
new Identifier('foo', new IdentifierType(IdentifierType::IDENTIFIER_FUNCTION))
49+
));
50+
}
51+
52+
public function testWillReflectNonNamespacedClass() : void
53+
{
54+
/** @var ReflectionClass $class */
55+
$class = $this->stubLocator->locateIdentifier(
56+
$this->reflector,
57+
new Identifier('AClass', new IdentifierType(IdentifierType::IDENTIFIER_CLASS))
58+
);
59+
60+
self::assertInstanceOf(ReflectionClass::class, $class);
61+
62+
self::assertSame('AClass', $class->getName());
63+
self::assertTrue($class->isInterface());
64+
self::assertFalse($class->inNamespace());
65+
}
66+
67+
public function testWillReflectNamespacedClass() : void
68+
{
69+
/** @var ReflectionClass $class */
70+
$class = $this->stubLocator->locateIdentifier(
71+
$this->reflector,
72+
new Identifier('Foo\Bar\AClass', new IdentifierType(IdentifierType::IDENTIFIER_CLASS))
73+
);
74+
75+
self::assertInstanceOf(ReflectionClass::class, $class);
76+
77+
self::assertSame('Foo\Bar\AClass', $class->getName());
78+
self::assertTrue($class->isInterface());
79+
self::assertTrue($class->inNamespace());
80+
}
81+
}

0 commit comments

Comments
 (0)