Skip to content

Commit cb1f6b2

Browse files
committed
Improve type resolver docs
1 parent 31f5bee commit cb1f6b2

1 file changed

Lines changed: 59 additions & 0 deletions

File tree

Writerside/topics/parser/type-resolver.md

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,10 @@ final readonly class TypeResolver
2929

3030
public function withTypeImportAs(string $name, string $alias): self;
3131

32+
public function withTypeImportsFromClass(\ReflectionClass $class): self;
33+
34+
public function withTypeImportsFromFunction(\ReflectionFunctionAbstract $function): self;
35+
3236
public function resolve(TypeNode $type): TypeNode;
3337
}
3438
```
@@ -124,6 +128,61 @@ For a plain import the alias is inferred from the last segment of the name
124128
(`TypeLang\Parser\Node` becomes reachable as `Node`), which mirrors how a
125129
`use` statement without an explicit `as` behaves.
126130

131+
## Reading Imports From Reflection
132+
133+
Instead of listing imports by hand, `TypeResolver` can read them straight from
134+
the source file of a reflected class or function — resolving type names exactly
135+
as PHP would inside that element.
136+
137+
Given a class whose file declares:
138+
139+
```php
140+
namespace App;
141+
142+
use TypeLang\Parser\Node;
143+
use TypeLang\Parser\Exception as Error;
144+
145+
final class Example {}
146+
```
147+
148+
`withTypeImportsFromClass()` registers both of its imports:
149+
150+
```php
151+
use TypeLang\Parser\TypeParser;
152+
use TypeLang\Parser\TypeResolver;
153+
154+
$statement = new TypeParser()
155+
->parse('Node|Error\SemanticException');
156+
157+
$statement = new TypeResolver()
158+
->withTypeImportsFromClass(new ReflectionClass(App\Example::class))
159+
->resolve($statement);
160+
161+
foreach ($statement->statements as $type) {
162+
echo $type->name->toString(), "\n";
163+
}
164+
165+
// Expected Output:
166+
// TypeLang\Parser\Node
167+
// TypeLang\Parser\Exception\SemanticException
168+
```
169+
170+
`withTypeImportsFromFunction()` does the same for a free function or a method —
171+
both are a `ReflectionFunctionAbstract` — reading the imports of the file the
172+
function is declared in:
173+
174+
```php
175+
use TypeLang\Parser\TypeResolver;
176+
177+
$resolver = new TypeResolver()
178+
->withTypeImportsFromFunction(new ReflectionFunction('App\example'));
179+
```
180+
181+
> Only the file header, up to the element's own declaration, is scanned, and
182+
> only real `use` imports are collected — a trait `use` inside a class body or
183+
> a closure `use (...)` capture is never mistaken for an import.
184+
> {style="note"}
185+
127186
## Custom Name Rewriting
128187

129188
`TypeResolver` is intentionally scoped to `use`-statement semantics. When you

0 commit comments

Comments
 (0)