@@ -632,6 +632,9 @@ public function getBitwiseAndType(Expr $left, Expr $right, callable $getTypeCall
632
632
}
633
633
return TypeCombinator::union (...$ resultTypes );
634
634
}
635
+
636
+ $ leftType = $ this ->optimizeScalarType ($ leftType );
637
+ $ rightType = $ this ->optimizeScalarType ($ rightType );
635
638
}
636
639
637
640
if ($ leftType ->isString ()->yes () && $ rightType ->isString ()->yes ()) {
@@ -698,6 +701,9 @@ public function getBitwiseOrType(Expr $left, Expr $right, callable $getTypeCallb
698
701
}
699
702
return TypeCombinator::union (...$ resultTypes );
700
703
}
704
+
705
+ $ leftType = $ this ->optimizeScalarType ($ leftType );
706
+ $ rightType = $ this ->optimizeScalarType ($ rightType );
701
707
}
702
708
703
709
if ($ leftType ->isString ()->yes () && $ rightType ->isString ()->yes ()) {
@@ -754,6 +760,9 @@ public function getBitwiseXorType(Expr $left, Expr $right, callable $getTypeCall
754
760
}
755
761
return TypeCombinator::union (...$ resultTypes );
756
762
}
763
+
764
+ $ leftType = $ this ->optimizeScalarType ($ leftType );
765
+ $ rightType = $ this ->optimizeScalarType ($ rightType );
757
766
}
758
767
759
768
if ($ leftType ->isString ()->yes () && $ rightType ->isString ()->yes ()) {
@@ -839,6 +848,9 @@ public function getDivType(Expr $left, Expr $right, callable $getTypeCallback):
839
848
}
840
849
return TypeCombinator::union (...$ resultTypes );
841
850
}
851
+
852
+ $ leftType = $ this ->optimizeScalarType ($ leftType );
853
+ $ rightType = $ this ->optimizeScalarType ($ rightType );
842
854
}
843
855
844
856
$ rightScalarValues = $ rightType ->toNumber ()->getConstantScalarValues ();
@@ -899,6 +911,9 @@ public function getModType(Expr $left, Expr $right, callable $getTypeCallback):
899
911
}
900
912
return TypeCombinator::union (...$ resultTypes );
901
913
}
914
+
915
+ $ leftType = $ this ->optimizeScalarType ($ leftType );
916
+ $ rightType = $ this ->optimizeScalarType ($ rightType );
902
917
}
903
918
904
919
$ integerType = $ rightType ->toInteger ();
@@ -991,6 +1006,9 @@ public function getPlusType(Expr $left, Expr $right, callable $getTypeCallback):
991
1006
992
1007
return TypeCombinator::union (...$ resultTypes );
993
1008
}
1009
+
1010
+ $ leftType = $ this ->optimizeScalarType ($ leftType );
1011
+ $ rightType = $ this ->optimizeScalarType ($ rightType );
994
1012
}
995
1013
996
1014
$ leftConstantArrays = $ leftType ->getConstantArrays ();
@@ -1152,6 +1170,9 @@ public function getMinusType(Expr $left, Expr $right, callable $getTypeCallback)
1152
1170
1153
1171
return TypeCombinator::union (...$ resultTypes );
1154
1172
}
1173
+
1174
+ $ leftType = $ this ->optimizeScalarType ($ leftType );
1175
+ $ rightType = $ this ->optimizeScalarType ($ rightType );
1155
1176
}
1156
1177
1157
1178
return $ this ->resolveCommonMath (new BinaryOp \Minus ($ left , $ right ), $ leftType , $ rightType );
@@ -1193,6 +1214,9 @@ public function getMulType(Expr $left, Expr $right, callable $getTypeCallback):
1193
1214
1194
1215
return TypeCombinator::union (...$ resultTypes );
1195
1216
}
1217
+
1218
+ $ leftType = $ this ->optimizeScalarType ($ leftType );
1219
+ $ rightType = $ this ->optimizeScalarType ($ rightType );
1196
1220
}
1197
1221
1198
1222
$ leftNumberType = $ leftType ->toNumber ();
@@ -1278,6 +1302,9 @@ public function getShiftLeftType(Expr $left, Expr $right, callable $getTypeCallb
1278
1302
1279
1303
return TypeCombinator::union (...$ resultTypes );
1280
1304
}
1305
+
1306
+ $ leftType = $ this ->optimizeScalarType ($ leftType );
1307
+ $ rightType = $ this ->optimizeScalarType ($ rightType );
1281
1308
}
1282
1309
1283
1310
$ leftNumberType = $ leftType ->toNumber ();
@@ -1334,6 +1361,9 @@ public function getShiftRightType(Expr $left, Expr $right, callable $getTypeCall
1334
1361
1335
1362
return TypeCombinator::union (...$ resultTypes );
1336
1363
}
1364
+
1365
+ $ leftType = $ this ->optimizeScalarType ($ leftType );
1366
+ $ rightType = $ this ->optimizeScalarType ($ rightType );
1337
1367
}
1338
1368
1339
1369
$ leftNumberType = $ leftType ->toNumber ();
@@ -1346,6 +1376,33 @@ public function getShiftRightType(Expr $left, Expr $right, callable $getTypeCall
1346
1376
return $ this ->resolveCommonMath (new Expr \BinaryOp \ShiftRight ($ left , $ right ), $ leftType , $ rightType );
1347
1377
}
1348
1378
1379
+ private function optimizeScalarType (Type $ type ): Type
1380
+ {
1381
+ $ types = [];
1382
+ if ($ type ->isInteger ()->yes ()) {
1383
+ $ types [] = new IntegerType ();
1384
+ }
1385
+ if ($ type ->isString ()->yes ()) {
1386
+ $ types [] = new StringType ();
1387
+ }
1388
+ if ($ type ->isFloat ()->yes ()) {
1389
+ $ types [] = new FloatType ();
1390
+ }
1391
+ if ($ type ->isNull ()->yes ()) {
1392
+ $ types [] = new NullType ();
1393
+ }
1394
+
1395
+ if (count ($ types ) === 0 ) {
1396
+ return new ErrorType ();
1397
+ }
1398
+
1399
+ if (count ($ types ) === 1 ) {
1400
+ return $ types [0 ];
1401
+ }
1402
+
1403
+ return new UnionType ($ types );
1404
+ }
1405
+
1349
1406
/**
1350
1407
* @return TypeResult<BooleanType>
1351
1408
*/
0 commit comments