3
3
namespace PHPStan \Analyser ;
4
4
5
5
use PhpParser \Node \Name ;
6
+ use PHPStan \Php \ComposerPhpVersionFactory ;
6
7
use PHPStan \Php \PhpVersion ;
7
8
use PHPStan \Reflection \NamespaceAnswerer ;
8
9
use PHPStan \Reflection \ReflectionProvider ;
9
10
use PHPStan \Reflection \ReflectionProvider \ReflectionProviderProvider ;
11
+ use PHPStan \ShouldNotHappenException ;
10
12
use PHPStan \Type \Accessory \AccessoryNonFalsyStringType ;
11
13
use PHPStan \Type \Constant \ConstantFloatType ;
12
14
use PHPStan \Type \Constant \ConstantIntegerType ;
21
23
use PHPStan \Type \UnionType ;
22
24
use function array_key_exists ;
23
25
use function in_array ;
26
+ use function is_array ;
27
+ use function is_int ;
24
28
use function max ;
25
29
use function sprintf ;
26
30
use const INF ;
@@ -35,12 +39,13 @@ final class ConstantResolver
35
39
36
40
/**
37
41
* @param string[] $dynamicConstantNames
42
+ * @param int|array{min: int, max: int}|null $phpVersion
38
43
*/
39
44
public function __construct (
40
45
private ReflectionProviderProvider $ reflectionProviderProvider ,
41
46
private array $ dynamicConstantNames ,
42
- private ? PhpVersion $ composerMinPhpVersion ,
43
- private ?PhpVersion $ composerMaxPhpVersion ,
47
+ private int | array | null $ phpVersion ,
48
+ private ?ComposerPhpVersionFactory $ composerPhpVersionFactory ,
44
49
)
45
50
{
46
51
}
@@ -87,11 +92,11 @@ public function resolvePredefinedConstant(string $resolvedConstantName): ?Type
87
92
$ minMajor = 5 ;
88
93
$ maxMajor = null ;
89
94
90
- if ($ this ->composerMinPhpVersion !== null ) {
91
- $ minMajor = max ($ minMajor , $ this ->composerMinPhpVersion ->getMajorVersionId ());
95
+ if ($ this ->getMinPhpVersion () !== null ) {
96
+ $ minMajor = max ($ minMajor , $ this ->getMinPhpVersion () ->getMajorVersionId ());
92
97
}
93
- if ($ this ->composerMaxPhpVersion !== null ) {
94
- $ maxMajor = $ this ->composerMaxPhpVersion ->getMajorVersionId ();
98
+ if ($ this ->getMaxPhpVersion () !== null ) {
99
+ $ maxMajor = $ this ->getMaxPhpVersion () ->getMajorVersionId ();
95
100
}
96
101
97
102
return $ this ->createInteger ($ minMajor , $ maxMajor );
@@ -101,12 +106,12 @@ public function resolvePredefinedConstant(string $resolvedConstantName): ?Type
101
106
$ maxMinor = null ;
102
107
103
108
if (
104
- $ this ->composerMinPhpVersion !== null
105
- && $ this ->composerMaxPhpVersion !== null
106
- && $ this ->composerMaxPhpVersion ->getMajorVersionId () === $ this ->composerMinPhpVersion ->getMajorVersionId ()
109
+ $ this ->getMinPhpVersion () !== null
110
+ && $ this ->getMaxPhpVersion () !== null
111
+ && $ this ->getMaxPhpVersion () ->getMajorVersionId () === $ this ->getMinPhpVersion () ->getMajorVersionId ()
107
112
) {
108
- $ minMinor = $ this ->composerMinPhpVersion ->getMinorVersionId ();
109
- $ maxMinor = $ this ->composerMaxPhpVersion ->getMinorVersionId ();
113
+ $ minMinor = $ this ->getMinPhpVersion () ->getMinorVersionId ();
114
+ $ maxMinor = $ this ->getMaxPhpVersion () ->getMinorVersionId ();
110
115
}
111
116
112
117
return $ this ->createInteger ($ minMinor , $ maxMinor );
@@ -116,25 +121,25 @@ public function resolvePredefinedConstant(string $resolvedConstantName): ?Type
116
121
$ maxRelease = null ;
117
122
118
123
if (
119
- $ this ->composerMinPhpVersion !== null
120
- && $ this ->composerMaxPhpVersion !== null
121
- && $ this ->composerMaxPhpVersion ->getMajorVersionId () === $ this ->composerMinPhpVersion ->getMajorVersionId ()
122
- && $ this ->composerMaxPhpVersion ->getMinorVersionId () === $ this ->composerMinPhpVersion ->getMinorVersionId ()
124
+ $ this ->getMinPhpVersion () !== null
125
+ && $ this ->getMaxPhpVersion () !== null
126
+ && $ this ->getMaxPhpVersion () ->getMajorVersionId () === $ this ->getMinPhpVersion () ->getMajorVersionId ()
127
+ && $ this ->getMaxPhpVersion () ->getMinorVersionId () === $ this ->getMinPhpVersion () ->getMinorVersionId ()
123
128
) {
124
- $ minRelease = $ this ->composerMinPhpVersion ->getPatchVersionId ();
125
- $ maxRelease = $ this ->composerMaxPhpVersion ->getPatchVersionId ();
129
+ $ minRelease = $ this ->getMinPhpVersion () ->getPatchVersionId ();
130
+ $ maxRelease = $ this ->getMaxPhpVersion () ->getPatchVersionId ();
126
131
}
127
132
128
133
return $ this ->createInteger ($ minRelease , $ maxRelease );
129
134
}
130
135
if ($ resolvedConstantName === 'PHP_VERSION_ID ' ) {
131
136
$ minVersion = 50207 ;
132
137
$ maxVersion = null ;
133
- if ($ this ->composerMinPhpVersion !== null ) {
134
- $ minVersion = max ($ minVersion , $ this ->composerMinPhpVersion ->getVersionId ());
138
+ if ($ this ->getMinPhpVersion () !== null ) {
139
+ $ minVersion = max ($ minVersion , $ this ->getMinPhpVersion () ->getVersionId ());
135
140
}
136
- if ($ this ->composerMaxPhpVersion !== null ) {
137
- $ maxVersion = $ this ->composerMaxPhpVersion ->getVersionId ();
141
+ if ($ this ->getMaxPhpVersion () !== null ) {
142
+ $ maxVersion = $ this ->getMaxPhpVersion () ->getVersionId ();
138
143
}
139
144
140
145
return $ this ->createInteger ($ minVersion , $ maxVersion );
@@ -351,6 +356,48 @@ public function resolvePredefinedConstant(string $resolvedConstantName): ?Type
351
356
return null ;
352
357
}
353
358
359
+ private function getMinPhpVersion (): ?PhpVersion
360
+ {
361
+ if (is_int ($ this ->phpVersion )) {
362
+ return null ;
363
+ }
364
+
365
+ if (is_array ($ this ->phpVersion )) {
366
+ if ($ this ->phpVersion ['max ' ] < $ this ->phpVersion ['min ' ]) {
367
+ throw new ShouldNotHappenException ('Invalid PHP version range: phpVersion.max should be greater or equal to phpVersion.min. ' );
368
+ }
369
+
370
+ return new PhpVersion ($ this ->phpVersion ['min ' ]);
371
+ }
372
+
373
+ if ($ this ->composerPhpVersionFactory === null ) {
374
+ return null ;
375
+ }
376
+
377
+ return $ this ->composerPhpVersionFactory ->getMinVersion ();
378
+ }
379
+
380
+ private function getMaxPhpVersion (): ?PhpVersion
381
+ {
382
+ if (is_int ($ this ->phpVersion )) {
383
+ return null ;
384
+ }
385
+
386
+ if (is_array ($ this ->phpVersion )) {
387
+ if ($ this ->phpVersion ['max ' ] < $ this ->phpVersion ['min ' ]) {
388
+ throw new ShouldNotHappenException ('Invalid PHP version range: phpVersion.max should be greater or equal to phpVersion.min. ' );
389
+ }
390
+
391
+ return new PhpVersion ($ this ->phpVersion ['max ' ]);
392
+ }
393
+
394
+ if ($ this ->composerPhpVersionFactory === null ) {
395
+ return null ;
396
+ }
397
+
398
+ return $ this ->composerPhpVersionFactory ->getMaxVersion ();
399
+ }
400
+
354
401
public function resolveConstantType (string $ constantName , Type $ constantType ): Type
355
402
{
356
403
if ($ constantType ->isConstantValue ()->yes () && in_array ($ constantName , $ this ->dynamicConstantNames , true )) {
0 commit comments