44
55use PhpParser \Node \Name ;
66use PHPStan \DependencyInjection \AutowiredService ;
7+ use PHPStan \DependencyInjection \Container ;
78use PHPStan \Php \ComposerPhpVersionFactory ;
89use PHPStan \Php \PhpVersion ;
10+ use PHPStan \PhpDoc \TypeStringResolver ;
911use PHPStan \Reflection \NamespaceAnswerer ;
1012use PHPStan \Reflection \ReflectionProvider ;
1113use PHPStan \Reflection \ReflectionProvider \ReflectionProviderProvider ;
@@ -50,6 +52,7 @@ public function __construct(
5052 private array $ dynamicConstantNames ,
5153 private int |array |null $ phpVersion ,
5254 private ComposerPhpVersionFactory $ composerPhpVersionFactory ,
55+ private ?Container $ container ,
5356 )
5457 {
5558 }
@@ -404,8 +407,18 @@ private function getMaxPhpVersion(): ?PhpVersion
404407
405408 public function resolveConstantType (string $ constantName , Type $ constantType ): Type
406409 {
407- if ($ constantType ->isConstantValue ()->yes () && in_array ($ constantName , $ this ->dynamicConstantNames , true )) {
408- return $ constantType ->generalize (GeneralizePrecision::lessSpecific ());
410+ if ($ constantType ->isConstantValue ()->yes ()) {
411+ if (array_key_exists ($ constantName , $ this ->dynamicConstantNames )) {
412+ $ phpdocTypes = $ this ->dynamicConstantNames [$ constantName ];
413+ if ($ this ->container !== null ) {
414+ $ typeStringResolver = $ this ->container ->getByType (TypeStringResolver::class);
415+ return $ typeStringResolver ->resolve ($ phpdocTypes , new NameScope (null , [], null ));
416+ }
417+ return $ constantType ;
418+ }
419+ if (in_array ($ constantName , $ this ->dynamicConstantNames , true )) {
420+ return $ constantType ->generalize (GeneralizePrecision::lessSpecific ());
421+ }
409422 }
410423
411424 return $ constantType ;
@@ -414,6 +427,22 @@ public function resolveConstantType(string $constantName, Type $constantType): T
414427 public function resolveClassConstantType (string $ className , string $ constantName , Type $ constantType , ?Type $ nativeType ): Type
415428 {
416429 $ lookupConstantName = sprintf ('%s::%s ' , $ className , $ constantName );
430+ if (array_key_exists ($ lookupConstantName , $ this ->dynamicConstantNames )) {
431+ if ($ constantType ->isConstantValue ()->yes ()) {
432+ $ phpdocTypes = $ this ->dynamicConstantNames [$ lookupConstantName ];
433+ if ($ this ->container !== null ) {
434+ $ typeStringResolver = $ this ->container ->getByType (TypeStringResolver::class);
435+ return $ typeStringResolver ->resolve ($ phpdocTypes , new NameScope (null , [], $ className ));
436+ }
437+ }
438+
439+ if ($ nativeType !== null ) {
440+ return $ nativeType ;
441+ }
442+
443+ return $ constantType ;
444+ }
445+
417446 if (in_array ($ lookupConstantName , $ this ->dynamicConstantNames , true )) {
418447 if ($ nativeType !== null ) {
419448 return $ nativeType ;
0 commit comments