33namespace PHPStan \Analyser ;
44
55use PhpParser \Node \Name ;
6+ use PHPStan \DependencyInjection \Container ;
67use PHPStan \Php \ComposerPhpVersionFactory ;
78use PHPStan \Php \PhpVersion ;
9+ use PHPStan \PhpDoc \TypeStringResolver ;
810use PHPStan \Reflection \NamespaceAnswerer ;
911use PHPStan \Reflection \ReflectionProvider ;
1012use PHPStan \Reflection \ReflectionProvider \ReflectionProviderProvider ;
@@ -46,6 +48,9 @@ public function __construct(
4648 private array $ dynamicConstantNames ,
4749 private int |array |null $ phpVersion ,
4850 private ComposerPhpVersionFactory $ composerPhpVersionFactory ,
51+ private ?PhpVersion $ composerMinPhpVersion ,
52+ private ?PhpVersion $ composerMaxPhpVersion ,
53+ private ?Container $ container ,
4954 )
5055 {
5156 }
@@ -400,8 +405,17 @@ private function getMaxPhpVersion(): ?PhpVersion
400405
401406 public function resolveConstantType (string $ constantName , Type $ constantType ): Type
402407 {
403- if ($ constantType ->isConstantValue ()->yes () && in_array ($ constantName , $ this ->dynamicConstantNames , true )) {
404- return $ constantType ->generalize (GeneralizePrecision::lessSpecific ());
408+ if ($ constantType ->isConstantValue ()->yes ()) {
409+ if (array_key_exists ($ constantName , $ this ->dynamicConstantNames )) {
410+ $ phpdocTypes = $ this ->dynamicConstantNames [$ constantName ];
411+ $ typeStringResolver = $ this ->container ?->getByType(TypeStringResolver::class);
412+ if ($ typeStringResolver !== null ) {
413+ return $ typeStringResolver ->resolve ($ phpdocTypes , new NameScope (null , [], null ));
414+ }
415+ }
416+ if (in_array ($ constantName , $ this ->dynamicConstantNames , true )) {
417+ return $ constantType ->generalize (GeneralizePrecision::lessSpecific ());
418+ }
405419 }
406420
407421 return $ constantType ;
@@ -410,6 +424,20 @@ public function resolveConstantType(string $constantName, Type $constantType): T
410424 public function resolveClassConstantType (string $ className , string $ constantName , Type $ constantType , ?Type $ nativeType ): Type
411425 {
412426 $ lookupConstantName = sprintf ('%s::%s ' , $ className , $ constantName );
427+ if (array_key_exists ($ lookupConstantName , $ this ->dynamicConstantNames )) {
428+ if ($ nativeType !== null ) {
429+ return $ nativeType ;
430+ }
431+
432+ if ($ constantType ->isConstantValue ()->yes ()) {
433+ $ phpdocTypes = $ this ->dynamicConstantNames [$ lookupConstantName ];
434+ $ typeStringResolver = $ this ->container ?->getByType(TypeStringResolver::class);
435+ if ($ typeStringResolver !== null ) {
436+ return $ typeStringResolver ->resolve ($ phpdocTypes , new NameScope (null , [], $ className ));
437+ }
438+ }
439+ }
440+
413441 if (in_array ($ lookupConstantName , $ this ->dynamicConstantNames , true )) {
414442 if ($ nativeType !== null ) {
415443 return $ nativeType ;
0 commit comments