@@ -637,6 +637,9 @@ public function getBitwiseAndType(Expr $left, Expr $right, callable $getTypeCall
637
637
}
638
638
return TypeCombinator::union (...$ resultTypes );
639
639
}
640
+
641
+ $ leftType = $ this ->optimizeScalarType ($ leftType );
642
+ $ rightType = $ this ->optimizeScalarType ($ rightType );
640
643
}
641
644
642
645
if ($ leftType ->isString ()->yes () && $ rightType ->isString ()->yes ()) {
@@ -703,6 +706,9 @@ public function getBitwiseOrType(Expr $left, Expr $right, callable $getTypeCallb
703
706
}
704
707
return TypeCombinator::union (...$ resultTypes );
705
708
}
709
+
710
+ $ leftType = $ this ->optimizeScalarType ($ leftType );
711
+ $ rightType = $ this ->optimizeScalarType ($ rightType );
706
712
}
707
713
708
714
if ($ leftType ->isString ()->yes () && $ rightType ->isString ()->yes ()) {
@@ -759,6 +765,9 @@ public function getBitwiseXorType(Expr $left, Expr $right, callable $getTypeCall
759
765
}
760
766
return TypeCombinator::union (...$ resultTypes );
761
767
}
768
+
769
+ $ leftType = $ this ->optimizeScalarType ($ leftType );
770
+ $ rightType = $ this ->optimizeScalarType ($ rightType );
762
771
}
763
772
764
773
if ($ leftType ->isString ()->yes () && $ rightType ->isString ()->yes ()) {
@@ -844,6 +853,9 @@ public function getDivType(Expr $left, Expr $right, callable $getTypeCallback):
844
853
}
845
854
return TypeCombinator::union (...$ resultTypes );
846
855
}
856
+
857
+ $ leftType = $ this ->optimizeScalarType ($ leftType );
858
+ $ rightType = $ this ->optimizeScalarType ($ rightType );
847
859
}
848
860
849
861
$ rightScalarValues = $ rightType ->toNumber ()->getConstantScalarValues ();
@@ -909,6 +921,9 @@ public function getModType(Expr $left, Expr $right, callable $getTypeCallback):
909
921
}
910
922
return TypeCombinator::union (...$ resultTypes );
911
923
}
924
+
925
+ $ leftType = $ this ->optimizeScalarType ($ leftType );
926
+ $ rightType = $ this ->optimizeScalarType ($ rightType );
912
927
}
913
928
914
929
$ integerType = $ rightType ->toInteger ();
@@ -1001,6 +1016,9 @@ public function getPlusType(Expr $left, Expr $right, callable $getTypeCallback):
1001
1016
1002
1017
return TypeCombinator::union (...$ resultTypes );
1003
1018
}
1019
+
1020
+ $ leftType = $ this ->optimizeScalarType ($ leftType );
1021
+ $ rightType = $ this ->optimizeScalarType ($ rightType );
1004
1022
}
1005
1023
1006
1024
$ leftConstantArrays = $ leftType ->getConstantArrays ();
@@ -1162,6 +1180,9 @@ public function getMinusType(Expr $left, Expr $right, callable $getTypeCallback)
1162
1180
1163
1181
return TypeCombinator::union (...$ resultTypes );
1164
1182
}
1183
+
1184
+ $ leftType = $ this ->optimizeScalarType ($ leftType );
1185
+ $ rightType = $ this ->optimizeScalarType ($ rightType );
1165
1186
}
1166
1187
1167
1188
return $ this ->resolveCommonMath (new BinaryOp \Minus ($ left , $ right ), $ leftType , $ rightType );
@@ -1203,6 +1224,9 @@ public function getMulType(Expr $left, Expr $right, callable $getTypeCallback):
1203
1224
1204
1225
return TypeCombinator::union (...$ resultTypes );
1205
1226
}
1227
+
1228
+ $ leftType = $ this ->optimizeScalarType ($ leftType );
1229
+ $ rightType = $ this ->optimizeScalarType ($ rightType );
1206
1230
}
1207
1231
1208
1232
$ leftNumberType = $ leftType ->toNumber ();
@@ -1288,6 +1312,9 @@ public function getShiftLeftType(Expr $left, Expr $right, callable $getTypeCallb
1288
1312
1289
1313
return TypeCombinator::union (...$ resultTypes );
1290
1314
}
1315
+
1316
+ $ leftType = $ this ->optimizeScalarType ($ leftType );
1317
+ $ rightType = $ this ->optimizeScalarType ($ rightType );
1291
1318
}
1292
1319
1293
1320
$ leftNumberType = $ leftType ->toNumber ();
@@ -1344,6 +1371,9 @@ public function getShiftRightType(Expr $left, Expr $right, callable $getTypeCall
1344
1371
1345
1372
return TypeCombinator::union (...$ resultTypes );
1346
1373
}
1374
+
1375
+ $ leftType = $ this ->optimizeScalarType ($ leftType );
1376
+ $ rightType = $ this ->optimizeScalarType ($ rightType );
1347
1377
}
1348
1378
1349
1379
$ leftNumberType = $ leftType ->toNumber ();
@@ -1356,6 +1386,33 @@ public function getShiftRightType(Expr $left, Expr $right, callable $getTypeCall
1356
1386
return $ this ->resolveCommonMath (new Expr \BinaryOp \ShiftRight ($ left , $ right ), $ leftType , $ rightType );
1357
1387
}
1358
1388
1389
+ private function optimizeScalarType (Type $ type ): Type
1390
+ {
1391
+ $ types = [];
1392
+ if ($ type ->isInteger ()->yes ()) {
1393
+ $ types [] = new IntegerType ();
1394
+ }
1395
+ if ($ type ->isString ()->yes ()) {
1396
+ $ types [] = new StringType ();
1397
+ }
1398
+ if ($ type ->isFloat ()->yes ()) {
1399
+ $ types [] = new FloatType ();
1400
+ }
1401
+ if ($ type ->isNull ()->yes ()) {
1402
+ $ types [] = new NullType ();
1403
+ }
1404
+
1405
+ if (count ($ types ) === 0 ) {
1406
+ return new ErrorType ();
1407
+ }
1408
+
1409
+ if (count ($ types ) === 1 ) {
1410
+ return $ types [0 ];
1411
+ }
1412
+
1413
+ return new UnionType ($ types );
1414
+ }
1415
+
1359
1416
/**
1360
1417
* @return TypeResult<BooleanType>
1361
1418
*/
0 commit comments