@@ -1263,6 +1263,58 @@ private function resolveType(Expr $node): Type
1263
1263
$ leftType = $ this ->getType ($ left );
1264
1264
$ rightType = $ this ->getType ($ right );
1265
1265
1266
+ if ($ node instanceof Expr \AssignOp \Plus || $ node instanceof Expr \BinaryOp \Plus) {
1267
+ $ leftConstantArrays = TypeUtils::getConstantArrays ($ leftType );
1268
+ $ rightConstantArrays = TypeUtils::getConstantArrays ($ rightType );
1269
+
1270
+ if (count ($ leftConstantArrays ) > 0 && count ($ rightConstantArrays ) > 0 ) {
1271
+ $ resultTypes = [];
1272
+ foreach ($ rightConstantArrays as $ rightConstantArray ) {
1273
+ foreach ($ leftConstantArrays as $ leftConstantArray ) {
1274
+ $ newArrayBuilder = ConstantArrayTypeBuilder::createFromConstantArray ($ rightConstantArray );
1275
+ foreach ($ leftConstantArray ->getKeyTypes () as $ leftKeyType ) {
1276
+ $ newArrayBuilder ->setOffsetValueType (
1277
+ $ leftKeyType ,
1278
+ $ leftConstantArray ->getOffsetValueType ($ leftKeyType )
1279
+ );
1280
+ }
1281
+ $ resultTypes [] = $ newArrayBuilder ->getArray ();
1282
+ }
1283
+ }
1284
+
1285
+ return TypeCombinator::union (...$ resultTypes );
1286
+ }
1287
+ $ arrayType = new ArrayType (new MixedType (), new MixedType ());
1288
+
1289
+ if ($ arrayType ->isSuperTypeOf ($ leftType )->yes () && $ arrayType ->isSuperTypeOf ($ rightType )->yes ()) {
1290
+ if ($ leftType ->getIterableKeyType ()->equals ($ rightType ->getIterableKeyType ())) {
1291
+ // to preserve BenevolentUnionType
1292
+ $ keyType = $ leftType ->getIterableKeyType ();
1293
+ } else {
1294
+ $ keyTypes = [];
1295
+ foreach ([
1296
+ $ leftType ->getIterableKeyType (),
1297
+ $ rightType ->getIterableKeyType (),
1298
+ ] as $ keyType ) {
1299
+ $ keyTypes [] = $ keyType ;
1300
+ }
1301
+ $ keyType = TypeCombinator::union (...$ keyTypes );
1302
+ }
1303
+ return new ArrayType (
1304
+ $ keyType ,
1305
+ TypeCombinator::union ($ leftType ->getIterableValueType (), $ rightType ->getIterableValueType ())
1306
+ );
1307
+ }
1308
+
1309
+ if ($ leftType instanceof MixedType && $ rightType instanceof MixedType) {
1310
+ return new BenevolentUnionType ([
1311
+ new FloatType (),
1312
+ new IntegerType (),
1313
+ new ArrayType (new MixedType (), new MixedType ()),
1314
+ ]);
1315
+ }
1316
+ }
1317
+
1266
1318
if (($ leftType instanceof IntegerRangeType || $ leftType instanceof ConstantIntegerType || $ leftType instanceof UnionType) &&
1267
1319
($ rightType instanceof IntegerRangeType || $ rightType instanceof ConstantIntegerType || $ rightType instanceof UnionType) &&
1268
1320
!($ node instanceof Node \Expr \BinaryOp \Pow || $ node instanceof Node \Expr \AssignOp \Pow)) {
@@ -1321,58 +1373,6 @@ private function resolveType(Expr $node): Type
1321
1373
}
1322
1374
}
1323
1375
1324
- if ($ node instanceof Expr \AssignOp \Plus || $ node instanceof Expr \BinaryOp \Plus) {
1325
- $ leftConstantArrays = TypeUtils::getConstantArrays ($ leftType );
1326
- $ rightConstantArrays = TypeUtils::getConstantArrays ($ rightType );
1327
-
1328
- if (count ($ leftConstantArrays ) > 0 && count ($ rightConstantArrays ) > 0 ) {
1329
- $ resultTypes = [];
1330
- foreach ($ rightConstantArrays as $ rightConstantArray ) {
1331
- foreach ($ leftConstantArrays as $ leftConstantArray ) {
1332
- $ newArrayBuilder = ConstantArrayTypeBuilder::createFromConstantArray ($ rightConstantArray );
1333
- foreach ($ leftConstantArray ->getKeyTypes () as $ leftKeyType ) {
1334
- $ newArrayBuilder ->setOffsetValueType (
1335
- $ leftKeyType ,
1336
- $ leftConstantArray ->getOffsetValueType ($ leftKeyType )
1337
- );
1338
- }
1339
- $ resultTypes [] = $ newArrayBuilder ->getArray ();
1340
- }
1341
- }
1342
-
1343
- return TypeCombinator::union (...$ resultTypes );
1344
- }
1345
- $ arrayType = new ArrayType (new MixedType (), new MixedType ());
1346
-
1347
- if ($ arrayType ->isSuperTypeOf ($ leftType )->yes () && $ arrayType ->isSuperTypeOf ($ rightType )->yes ()) {
1348
- if ($ leftType ->getIterableKeyType ()->equals ($ rightType ->getIterableKeyType ())) {
1349
- // to preserve BenevolentUnionType
1350
- $ keyType = $ leftType ->getIterableKeyType ();
1351
- } else {
1352
- $ keyTypes = [];
1353
- foreach ([
1354
- $ leftType ->getIterableKeyType (),
1355
- $ rightType ->getIterableKeyType (),
1356
- ] as $ keyType ) {
1357
- $ keyTypes [] = $ keyType ;
1358
- }
1359
- $ keyType = TypeCombinator::union (...$ keyTypes );
1360
- }
1361
- return new ArrayType (
1362
- $ keyType ,
1363
- TypeCombinator::union ($ leftType ->getIterableValueType (), $ rightType ->getIterableValueType ())
1364
- );
1365
- }
1366
-
1367
- if ($ leftType instanceof MixedType && $ rightType instanceof MixedType) {
1368
- return new BenevolentUnionType ([
1369
- new FloatType (),
1370
- new IntegerType (),
1371
- new ArrayType (new MixedType (), new MixedType ()),
1372
- ]);
1373
- }
1374
- }
1375
-
1376
1376
$ types = TypeCombinator::union ($ leftType , $ rightType );
1377
1377
if (
1378
1378
$ leftType instanceof ArrayType
0 commit comments