Skip to content

Commit 4195203

Browse files
Added minimal support for class aliases
To add a class alias to a class use the alias annotation
1 parent 7c92739 commit 4195203

File tree

4 files changed

+84
-1
lines changed

4 files changed

+84
-1
lines changed
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace setasign\PhpStubGenerator\Parser\BetterReflection;
6+
7+
use Roave\BetterReflection\Identifier\Identifier;
8+
use Roave\BetterReflection\Identifier\IdentifierType;
9+
use Roave\BetterReflection\Reflection\Reflection;
10+
use Roave\BetterReflection\Reflector\Reflector;
11+
use Roave\BetterReflection\SourceLocator\Type\SourceLocator;
12+
13+
class AliasSourceLocator implements SourceLocator
14+
{
15+
public function __construct(private SourceLocator $redirectSourceLocator, private array &$classAliases)
16+
{
17+
}
18+
19+
/**
20+
* @inheritDoc
21+
*/
22+
public function locateIdentifier(Reflector $reflector, Identifier $identifier): Reflection|null
23+
{
24+
if (!$identifier->isClass() || !\array_key_exists($identifier->getName(), $this->classAliases)) {
25+
return null;
26+
}
27+
28+
return $this->redirectSourceLocator->locateIdentifier(
29+
$reflector,
30+
new Identifier($this->classAliases[$identifier->getName()], $identifier->getType())
31+
);
32+
}
33+
34+
/**
35+
* @inheritDoc
36+
*/
37+
public function locateIdentifiersByType(Reflector $reflector, IdentifierType $identifierType): array
38+
{
39+
return [];
40+
}
41+
}

src/Parser/BetterReflection/BetterReflectionParser.php

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ class BetterReflectionParser implements ParserInterface
2525
*/
2626
private ?array $aliases = null;
2727

28+
private ?array $classAliases = null;
29+
2830
/**
2931
* @param ReaderInterface[] $sources
3032
* @param ReaderInterface[] $resolvingSources These sources are used to resolve reflections but won't generate stubs
@@ -58,6 +60,9 @@ public function parse(): void
5860
);
5961
}
6062

63+
$classAliases = [];
64+
$secondarySourceLocators[] = new AliasSourceLocator($mainSourceLocator, $classAliases);
65+
6166
// php internals
6267
$secondarySourceLocators[] = new MemoizingSourceLocator(
6368
new PhpInternalSourceLocator($astLocator, new ReflectionSourceStubber())
@@ -74,10 +79,19 @@ public function parse(): void
7479
$aliases = [];
7580

7681
$classIdent = new IdentifierType(IdentifierType::IDENTIFIER_CLASS);
82+
7783
foreach ($reflector->reflectAllClasses() as $class) {
7884
$className = $class->getName();
79-
$classes[$class->getNamespaceName()][$className] = new ReflectionClass($class);
8085

86+
$docComment = $class->getDocComment() ?? '';
87+
$classAliasPos = \strpos($docComment, '@alias');
88+
if ($classAliasPos !== false) {
89+
$lineEnding = \strpos($docComment, "\n", $classAliasPos);
90+
$alias = \ltrim(\substr($docComment, $classAliasPos + 7, $lineEnding - $classAliasPos - 7), '\\');
91+
$classAliases[$alias] = \ltrim($className, '\\');
92+
}
93+
94+
$classes[$class->getNamespaceName()][$className] = new ReflectionClass($class);
8195
$aliases[self::TYPE_CLASS][$className] = $astLocator->getNamespaceUses($classIdent, $className);
8296
}
8397

@@ -97,6 +111,7 @@ public function parse(): void
97111
// $this->functions = $functions;
98112
// $this->constants = $constants;
99113
$this->aliases = $aliases;
114+
$this->classAliases = $classAliases;
100115
}
101116

102117
/**
@@ -153,4 +168,16 @@ public function getAliases(string $classOrFunctionName, string $type): array
153168

154169
return $this->aliases[$type][$classOrFunctionName];
155170
}
171+
172+
/**
173+
* @inheritdoc
174+
*/
175+
public function getClassAliases(): array
176+
{
177+
if ($this->classAliases === null) {
178+
throw new \BadMethodCallException('BetterReflectionParser::parse wasn\'t called yet!');
179+
}
180+
181+
return $this->classAliases;
182+
}
156183
}

src/Parser/ParserInterface.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,4 +44,9 @@ public function getClasses(): array;
4444
* @throws \InvalidArgumentException If the class or function is unknown.
4545
*/
4646
public function getAliases(string $classOrFunctionName, string $type): array;
47+
48+
/**
49+
* @return array<string, string> Returns a list of all class aliases in this structure: ['old-name' => 'new-name']
50+
*/
51+
public function getClassAliases(): array;
4752
}

src/PhpStubGenerator.php

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,16 @@ public function generate(): string
123123
}
124124
}
125125

126+
$classAliases = $parser->getClassAliases();
127+
if ($classAliases !== []) {
128+
$result .= 'namespace' . $n
129+
. '{' . $n;
130+
foreach ($classAliases as $oldName => $newName) {
131+
$result .= ' class_alias(\'' . $oldName . '\', \'' . $newName . '\');' . $n;
132+
}
133+
$result .= '}' . $n . $n;
134+
}
135+
126136
// foreach ($parser->getFunctions() as $namespace => $functions) {
127137
// foreach ($functions as $function) {
128138
// $isGlobalNamespace = ($namespace === '');

0 commit comments

Comments
 (0)