@@ -69,7 +69,7 @@ public static function parse(string $function): array
6969 if (str_contains ($ function , ':: ' )) {
7070 [$ className , $ methodName ] = explode (':: ' , $ function , 2 );
7171
72- if (class_exists ($ className ) || interface_exists ($ className ) || trait_exists ($ className )) {
72+ if (class_exists ($ className ) || interface_exists ($ className ) || trait_exists ($ className ) || enum_exists ( $ className ) ) {
7373 /** @var class-string<object> $className */
7474 $ refClass = new \ReflectionClass ($ className );
7575 if ($ refClass ->hasMethod ($ methodName )) {
@@ -102,12 +102,6 @@ public static function parse(string $function): array
102102
103103 /**
104104 * Parses and resolves the @var or @property docblock for a given class property.
105- *
106- * Resolution Steps:
107- * 1. Search class and parent class hierarchy for physical properties.
108- * 2. Search implemented interfaces (PHP 8.4 interface properties).
109- * 3. Fall back to class-level magic @property tags if enabled and physical property is not found.
110- * 4. Parse physical @var tags if not already resolved as a magic property.
111105 */
112106 public static function parseProperty (string $ className , string $ propertyName ): ?TypeNode
113107 {
@@ -116,7 +110,7 @@ public static function parseProperty(string $className, string $propertyName): ?
116110 return self ::$ propertyCache [$ cacheKey ];
117111 }
118112
119- if (! class_exists ($ className ) && ! trait_exists ($ className ) && ! interface_exists ($ className )) {
113+ if (! class_exists ($ className ) && ! trait_exists ($ className ) && ! interface_exists ($ className ) && ! enum_exists ( $ className ) ) {
120114 return self ::$ propertyCache [$ cacheKey ] = null ;
121115 }
122116
@@ -227,10 +221,6 @@ public static function parseProperty(string $className, string $propertyName): ?
227221 /**
228222 * Parses and resolves a class-level @method docblock for __call / __callStatic.
229223 *
230- * Resolution Steps:
231- * 1. Search class, parent, interface, and trait hierarchy for @method tags (excluding vendor files).
232- * 2. Substitute type aliases and resolve FQCNs for parameters and return types.
233- *
234224 * @return array{return: ?TypeNode, parameters: array<int, array{name: string, type: ?TypeNode, isVariadic: bool, isOptional: bool}>, aliases: array<string, TypeNode>, templates: array<string, TemplateTagValueNode>}|null
235225 */
236226 public static function parseMagicMethod (string $ className , string $ methodName ): ?array
@@ -240,7 +230,7 @@ public static function parseMagicMethod(string $className, string $methodName):
240230 return self ::$ magicMethodCache [$ cacheKey ];
241231 }
242232
243- if (! class_exists ($ className ) && ! trait_exists ($ className ) && ! interface_exists ($ className )) {
233+ if (! class_exists ($ className ) && ! trait_exists ($ className ) && ! interface_exists ($ className ) && ! enum_exists ( $ className ) ) {
244234 return self ::$ magicMethodCache [$ cacheKey ] = null ;
245235 }
246236
@@ -349,7 +339,7 @@ public static function parseMagicMethod(string $className, string $methodName):
349339 */
350340 public static function parseClassAliases (string $ className ): array
351341 {
352- if (! class_exists ($ className ) && ! interface_exists ($ className ) && ! trait_exists ($ className )) {
342+ if (! class_exists ($ className ) && ! interface_exists ($ className ) && ! trait_exists ($ className ) && ! enum_exists ( $ className ) ) {
353343 return [];
354344 }
355345
@@ -547,9 +537,16 @@ private static function parseMethodHierarchyDocs(
547537 $ targetParamName = $ paramName ;
548538 } else {
549539 $ paramIndex = $ hierNameToIndex [$ paramName ] ?? null ;
550- $ targetParamName = ($ paramIndex !== null && isset ($ baseParamNames [$ paramIndex ]))
551- ? $ baseParamNames [$ paramIndex ]
552- : null ;
540+ if ($ paramIndex !== null && isset ($ baseParamNames [$ paramIndex ])) {
541+ $ candidateName = $ baseParamNames [$ paramIndex ];
542+ if (! isset ($ hierNameToIndex [$ candidateName ])) {
543+ $ targetParamName = $ candidateName ;
544+ } else {
545+ $ targetParamName = null ;
546+ }
547+ } else {
548+ $ targetParamName = null ;
549+ }
553550 }
554551
555552 if ($ targetParamName !== null && ! isset ($ types [$ targetParamName ])) {
@@ -609,7 +606,7 @@ private static function applyConstructorPromotionFallback(\ReflectionMethod $ref
609606 *
610607 * @param array<string, TypeNode> $aliases
611608 */
612- private static function substituteAliases (TypeNode $ node , array $ aliases ): TypeNode
609+ public static function substituteAliases (TypeNode $ node , array $ aliases ): TypeNode
613610 {
614611 if ($ node instanceof IdentifierTypeNode) {
615612 if (isset ($ aliases [$ node ->name ])) {
0 commit comments