Name Resolution
The parser has no notion of namespaces, use statements, or autoloading — a type such as Collection<User> is parsed exactly as written, with Collection and User staying relative names. Resolving what they actually refer to is a separate step, deliberately left up to the caller, and TypeLang\Parser\TypeResolver is the utility for it.
How It Works
TypeResolver is an immutable builder. You register the imports it should resolve against — through the fluent withTypeImport()/withTypeImportAs() methods (or the constructor) — and then call resolve(). It walks the whole node graph (via the same Traverser machinery used by TypeMapVisitor) and rewrites every matching TypeLang\Type\Name it finds in place.
Resolving Against PHP use Statements
The most common use case is resolving relative names the same way PHP resolves class references against the use statements of the file a phpdoc comment lives in.
Given PHP source that declares:
register the plain imports with withTypeImport() and the aliased ones with withTypeImportAs():
Applying it resolves the first segment of every name that matches one of the imports (case-insensitively, just like PHP) and merges in the rest of the name unchanged:
Because TypeResolver is immutable, withTypeImport() and withTypeImportAs() return a new instance each time and never mutate the receiver — the same resolver can be safely shared and extended for different contexts.
Passing Imports Through the Constructor
If you already have the whole import list assembled, hand it to the constructor directly instead of chaining with* calls. Plain imports are listed as values and aliased ones as alias => target pairs:
For a plain import the alias is inferred from the last segment of the name (TypeLang\Parser\Node becomes reachable as Node), which mirrors how a use statement without an explicit as behaves.
Reading Imports From Reflection
Instead of listing imports by hand, TypeResolver can read them straight from the source file of a reflected class or function — resolving type names exactly as PHP would inside that element.
Given a class whose file declares:
withTypeImportsFromClass() registers both of its imports:
withTypeImportsFromFunction() does the same for a free function or a method — both are a ReflectionFunctionAbstract — reading the imports of the file the function is declared in:
Custom Name Rewriting
TypeResolver is intentionally scoped to use-statement semantics. When you need to rewrite names some other way — against a runtime class map, a DI container, a PSR-4 lookup, and so on — drop down to TypeMapVisitor, which calls a callback of your own for every Name in the AST. TypeResolver is simply the ready-made configuration of that visitor for the most common case.