7
7
use PHPStan \Type \Constant \ConstantIntegerType ;
8
8
use function is_float ;
9
9
use function is_int ;
10
+ use function pow ;
10
11
11
12
final class ExponentiateHelper
12
13
{
@@ -25,28 +26,9 @@ public static function exponentiate(Type $base, Type $exponent): Type
25
26
return new NeverType ();
26
27
}
27
28
28
- $ allowedOperandTypes = new UnionType ([
29
- new IntegerType (),
30
- new FloatType (),
31
- new IntersectionType ([
32
- new StringType (),
33
- new AccessoryNumericStringType (),
34
- ]),
35
- new BooleanType (),
36
- new NullType (),
37
- ]);
38
- if (!$ allowedOperandTypes ->isSuperTypeOf ($ exponent )->yes ()) {
39
- return new ErrorType ();
40
- }
41
- if (!$ allowedOperandTypes ->isSuperTypeOf ($ base )->yes ()) {
42
- return new ErrorType ();
43
- }
44
-
45
- if ($ base instanceof ConstantScalarType) {
46
- $ result = self ::exponentiateConstantScalar ($ base , $ exponent );
47
- if ($ result !== null ) {
48
- return $ result ;
49
- }
29
+ $ result = self ::exponentiateConstantScalar ($ base , $ exponent );
30
+ if ($ result !== null ) {
31
+ return $ result ;
50
32
}
51
33
52
34
// exponentiation of a float, stays a float
@@ -84,16 +66,37 @@ public static function exponentiate(Type $base, Type $exponent): Type
84
66
]);
85
67
}
86
68
87
- private static function exponentiateConstantScalar (ConstantScalarType $ base , Type $ exponent ): ?Type
69
+ private static function exponentiateConstantScalar (Type $ base , Type $ exponent ): ?Type
88
70
{
71
+ $ allowedOperandTypes = new UnionType ([
72
+ new IntegerType (),
73
+ new FloatType (),
74
+ new IntersectionType ([
75
+ new StringType (),
76
+ new AccessoryNumericStringType (),
77
+ ]),
78
+ new BooleanType (),
79
+ new NullType (),
80
+ ]);
81
+ if (!$ allowedOperandTypes ->isSuperTypeOf ($ exponent )->yes ()) {
82
+ return new ErrorType ();
83
+ }
84
+ if (!$ allowedOperandTypes ->isSuperTypeOf ($ base )->yes ()) {
85
+ return new ErrorType ();
86
+ }
87
+
88
+ if (!$ base instanceof ConstantScalarType) {
89
+ return null ;
90
+ }
91
+
89
92
if ($ exponent instanceof IntegerRangeType) {
90
93
$ min = null ;
91
94
$ max = null ;
92
95
if ($ exponent ->getMin () !== null ) {
93
- $ min = $ base ->getValue () ** $ exponent ->getMin ();
96
+ $ min = self :: pow ( $ base ->getValue (), $ exponent ->getMin () );
94
97
}
95
98
if ($ exponent ->getMax () !== null ) {
96
- $ max = $ base ->getValue () ** $ exponent ->getMax ();
99
+ $ max = self :: pow ( $ base ->getValue (), $ exponent ->getMax () );
97
100
}
98
101
99
102
if (!is_float ($ min ) && !is_float ($ max )) {
@@ -102,7 +105,7 @@ private static function exponentiateConstantScalar(ConstantScalarType $base, Typ
102
105
}
103
106
104
107
if ($ exponent instanceof ConstantScalarType) {
105
- $ result = $ base ->getValue () ** $ exponent ->getValue ();
108
+ $ result = self :: pow ( $ base ->getValue (), $ exponent ->getValue () );
106
109
if (is_int ($ result )) {
107
110
return new ConstantIntegerType ($ result );
108
111
}
@@ -112,4 +115,12 @@ private static function exponentiateConstantScalar(ConstantScalarType $base, Typ
112
115
return null ;
113
116
}
114
117
118
+ /**
119
+ * @return float|int
120
+ */
121
+ private static function pow (mixed $ base , mixed $ exp )
122
+ {
123
+ return pow ($ base , $ exp );
124
+ }
125
+
115
126
}
0 commit comments