11/// Type-hint resolution to concrete `ClassInfo` values.
22///
3- /// This module contains the logic for mapping type-hint strings (as they
4- /// appear in return types, property annotations, and PHPDoc tags) to
5- /// resolved `ClassInfo` values that the completion, hover, and definition
6- /// engines can work with.
3+ /// This module contains the logic for mapping parsed [`PhpType`] values
4+ /// (as they appear in return types, property annotations, and PHPDoc
5+ /// tags) to resolved `ClassInfo` values that the completion, hover, and
6+ /// definition engines can work with.
77///
88/// Split from [`super::resolver`] for navigability. The entry points are:
99///
10- /// - [`type_hint_to_classes `]: the public facade that maps a
11- /// type-hint string to all matching `ClassInfo` values (handles unions,
12- /// intersections, generics, `self`/`static`/`$this`, nullable types,
13- /// object shapes, and type alias expansion).
10+ /// - [`type_hint_to_classes_typed `]: maps a parsed [`PhpType`] to all
11+ /// matching `ClassInfo` values (handles unions, intersections, generics ,
12+ /// `self`/`static`/`$this`, nullable types, object shapes, and type
13+ /// alias expansion).
1414/// - [`resolve_type_alias`]: fully expands a type alias defined
1515/// via `@phpstan-type` / `@psalm-type` / `@phpstan-import-type`.
1616/// - [`resolve_property_types`]: resolves a property's type hint
@@ -47,12 +47,11 @@ pub(crate) fn resolve_property_types(
4747 type_hint_to_classes_typed ( & type_hint, & class_info. name , all_classes, class_loader)
4848}
4949
50- /// Map a type-hint string to all matching `ClassInfo` values.
50+ /// Map a parsed [`PhpType`] to all matching `ClassInfo` values.
5151///
5252/// Handles:
5353/// - Nullable types: `?Foo` → strips `?`, resolves `Foo`
5454/// - Union types: `A|B|C` → resolves each part independently
55- /// (respects `<…>` nesting so `Collection<int|string>` is not split)
5655/// - Intersection types: `A&B` → resolves each part independently
5756/// - Generic types: `Collection<int, User>` → resolves `Collection`,
5857/// then applies generic substitution (`TKey→int`, `TValue→User`)
@@ -62,18 +61,9 @@ pub(crate) fn resolve_property_types(
6261/// `false`, `true`) → skipped (not class types)
6362///
6463/// Each resolvable class-like part is returned as a separate entry.
65- pub ( crate ) fn type_hint_to_classes (
66- type_hint : & str ,
67- owning_class_name : & str ,
68- all_classes : & [ Arc < ClassInfo > ] ,
69- class_loader : & dyn Fn ( & str ) -> Option < Arc < ClassInfo > > ,
70- ) -> Vec < ClassInfo > {
71- type_hint_to_classes_depth ( type_hint, owning_class_name, all_classes, class_loader, 0 )
72- }
73-
74- /// Like [`type_hint_to_classes`], but accepts a pre-parsed [`PhpType`]
75- /// to avoid a parse→stringify→reparse round-trip when the caller already
76- /// has a structured type.
64+ ///
65+ /// Callers that start with a raw type string should parse it with
66+ /// `PhpType::parse()` first.
7767pub ( crate ) fn type_hint_to_classes_typed (
7868 ty : & PhpType ,
7969 owning_class_name : & str ,
@@ -83,32 +73,8 @@ pub(crate) fn type_hint_to_classes_typed(
8373 type_hint_to_classes_typed_depth ( ty, owning_class_name, all_classes, class_loader, 0 )
8474}
8575
86- /// Inner implementation of [`type_hint_to_classes`] with a recursion
87- /// depth guard to prevent infinite loops from circular type aliases.
88- fn type_hint_to_classes_depth (
89- type_hint : & str ,
90- owning_class_name : & str ,
91- all_classes : & [ Arc < ClassInfo > ] ,
92- class_loader : & dyn Fn ( & str ) -> Option < Arc < ClassInfo > > ,
93- depth : u8 ,
94- ) -> Vec < ClassInfo > {
95- if depth > MAX_ALIAS_DEPTH {
96- return vec ! [ ] ;
97- }
98-
99- // Parse first — PhpType::parse handles `?Foo`, `(A&B)|C`, and all
100- // other syntax natively, making manual string preprocessing redundant.
101- // Alias resolution is handled by `resolve_named_type` when the parsed
102- // type turns out to be a `Named` variant.
103- let parsed = PhpType :: parse ( type_hint) ;
104- type_hint_to_classes_typed_depth ( & parsed, owning_class_name, all_classes, class_loader, depth)
105- }
106-
107- /// Inner implementation that operates on a pre-parsed [`PhpType`].
108- ///
109- /// Union and intersection members are recursed directly without
110- /// stringifying and re-parsing. Named types still go through
111- /// string-based alias resolution when necessary.
76+ /// Inner implementation with a recursion depth guard to prevent
77+ /// infinite loops from circular type aliases.
11278fn type_hint_to_classes_typed_depth (
11379 ty : & PhpType ,
11480 owning_class_name : & str ,
0 commit comments