@@ -48,18 +48,6 @@ class InferenceVisitor
48
48
49
49
Class ? mapEntryClass;
50
50
51
- // Stores the offset of the map entry found by inferMapEntry.
52
- int ? mapEntryOffset = null ;
53
-
54
- // Stores the offset of the map spread found by inferMapEntry.
55
- int ? mapSpreadOffset = null ;
56
-
57
- // Stores the offset of the iterable spread found by inferMapEntry.
58
- int ? iterableSpreadOffset = null ;
59
-
60
- // Stores the type of the iterable spread found by inferMapEntry.
61
- DartType ? iterableSpreadType = null ;
62
-
63
51
InferenceVisitor (this .inferrer);
64
52
65
53
/// Computes uri and offset for [node] for internal errors in a way that is
@@ -2174,7 +2162,8 @@ class InferenceVisitor
2174
2162
Map <TreeNode , DartType > inferredSpreadTypes,
2175
2163
Map <Expression , DartType > inferredConditionTypes,
2176
2164
bool inferenceNeeded,
2177
- bool typeChecksNeeded) {
2165
+ bool typeChecksNeeded,
2166
+ _MapLiteralEntryOffsets offsets) {
2178
2167
if (entry is SpreadMapEntry ) {
2179
2168
ExpressionInferenceResult spreadResult = inferrer.inferExpression (
2180
2169
entry.expression, spreadContext, inferenceNeeded || typeChecksNeeded,
@@ -2230,7 +2219,7 @@ class InferenceVisitor
2230
2219
2231
2220
// Don't report the error here, it might be an ambiguous Set. The
2232
2221
// error is reported in checkMapEntry if it's disambiguated as map.
2233
- iterableSpreadType = spreadType;
2222
+ offsets. iterableSpreadType = spreadType;
2234
2223
} else {
2235
2224
Expression receiver = entry.expression;
2236
2225
Expression problem = inferrer.helper.buildProblem (
@@ -2389,10 +2378,10 @@ class InferenceVisitor
2389
2378
inferrer.coreTypes.iterableRawType (inferrer.libraryBuilder.nullable),
2390
2379
SubtypeCheckMode .withNullabilities);
2391
2380
if (isMap && ! isIterable) {
2392
- mapSpreadOffset = entry.fileOffset;
2381
+ offsets. mapSpreadOffset = entry.fileOffset;
2393
2382
}
2394
2383
if (! isMap && isIterable) {
2395
- iterableSpreadOffset = entry.expression.fileOffset;
2384
+ offsets. iterableSpreadOffset = entry.expression.fileOffset;
2396
2385
}
2397
2386
2398
2387
return replacement;
@@ -2421,17 +2410,17 @@ class InferenceVisitor
2421
2410
inferredSpreadTypes,
2422
2411
inferredConditionTypes,
2423
2412
inferenceNeeded,
2424
- typeChecksNeeded);
2413
+ typeChecksNeeded,
2414
+ offsets);
2425
2415
entry.then = then..parent = entry;
2426
- MapLiteralEntry otherwise;
2427
2416
if (entry.otherwise != null ) {
2428
2417
inferrer.flowAnalysis.ifStatement_elseBegin ();
2429
2418
// We need to modify the actual types added in the recursive call to
2430
2419
// inferMapEntry.
2431
2420
DartType ? actualValueType = actualTypes.removeLast ();
2432
2421
DartType ? actualKeyType = actualTypes.removeLast ();
2433
2422
DartType actualTypeForSet = actualTypesForSet.removeLast ();
2434
- otherwise = inferMapEntry (
2423
+ MapLiteralEntry otherwise = inferMapEntry (
2435
2424
entry.otherwise! ,
2436
2425
entry,
2437
2426
inferredKeyType,
@@ -2442,7 +2431,8 @@ class InferenceVisitor
2442
2431
inferredSpreadTypes,
2443
2432
inferredConditionTypes,
2444
2433
inferenceNeeded,
2445
- typeChecksNeeded);
2434
+ typeChecksNeeded,
2435
+ offsets);
2446
2436
int length = actualTypes.length;
2447
2437
actualTypes[length - 2 ] = inferrer.typeSchemaEnvironment
2448
2438
.getStandardUpperBound (actualKeyType, actualTypes[length - 2 ],
@@ -2524,7 +2514,8 @@ class InferenceVisitor
2524
2514
inferredSpreadTypes,
2525
2515
inferredConditionTypes,
2526
2516
inferenceNeeded,
2527
- typeChecksNeeded);
2517
+ typeChecksNeeded,
2518
+ offsets);
2528
2519
entry.body = body..parent = entry;
2529
2520
inferrer.flowAnalysis.for_updaterBegin ();
2530
2521
for (int index = 0 ; index < entry.updates.length; index++ ) {
@@ -2576,7 +2567,8 @@ class InferenceVisitor
2576
2567
inferredSpreadTypes,
2577
2568
inferredConditionTypes,
2578
2569
inferenceNeeded,
2579
- typeChecksNeeded);
2570
+ typeChecksNeeded,
2571
+ offsets);
2580
2572
entry.body = body..parent = entry;
2581
2573
// This is matched by the call to [forEach_bodyBegin] in
2582
2574
// [handleForInWithoutVariable] or [handleForInDeclaringVariable].
@@ -2603,7 +2595,7 @@ class InferenceVisitor
2603
2595
actualTypes.add (valueResult.inferredType);
2604
2596
// Use 'dynamic' for error recovery.
2605
2597
actualTypesForSet.add (const DynamicType ());
2606
- mapEntryOffset = entry.fileOffset;
2598
+ offsets. mapEntryOffset = entry.fileOffset;
2607
2599
return entry;
2608
2600
}
2609
2601
}
@@ -2613,18 +2605,19 @@ class InferenceVisitor
2613
2605
DartType keyType,
2614
2606
DartType valueType,
2615
2607
Map <TreeNode , DartType > inferredSpreadTypes,
2616
- Map <Expression , DartType > inferredConditionTypes) {
2608
+ Map <Expression , DartType > inferredConditionTypes,
2609
+ _MapLiteralEntryOffsets offsets) {
2617
2610
// It's disambiguated as a map literal.
2618
2611
MapLiteralEntry replacement = entry;
2619
- if (iterableSpreadOffset != null ) {
2612
+ if (offsets. iterableSpreadOffset != null ) {
2620
2613
replacement = new MapLiteralEntry (
2621
2614
inferrer.helper.buildProblem (
2622
2615
templateSpreadMapEntryTypeMismatch.withArguments (
2623
- iterableSpreadType! , inferrer.isNonNullableByDefault),
2624
- iterableSpreadOffset! ,
2616
+ offsets. iterableSpreadType! , inferrer.isNonNullableByDefault),
2617
+ offsets. iterableSpreadOffset! ,
2625
2618
1 ),
2626
2619
new NullLiteral ())
2627
- ..fileOffset = iterableSpreadOffset! ;
2620
+ ..fileOffset = offsets. iterableSpreadOffset! ;
2628
2621
}
2629
2622
if (entry is SpreadMapEntry ) {
2630
2623
DartType ? spreadType = inferredSpreadTypes[entry.expression];
@@ -2638,11 +2631,11 @@ class InferenceVisitor
2638
2631
}
2639
2632
} else if (entry is IfMapEntry ) {
2640
2633
MapLiteralEntry then = checkMapEntry (entry.then, keyType, valueType,
2641
- inferredSpreadTypes, inferredConditionTypes);
2634
+ inferredSpreadTypes, inferredConditionTypes, offsets );
2642
2635
entry.then = then..parent = entry;
2643
2636
if (entry.otherwise != null ) {
2644
2637
MapLiteralEntry otherwise = checkMapEntry (entry.otherwise! , keyType,
2645
- valueType, inferredSpreadTypes, inferredConditionTypes);
2638
+ valueType, inferredSpreadTypes, inferredConditionTypes, offsets );
2646
2639
entry.otherwise = otherwise..parent = entry;
2647
2640
}
2648
2641
} else if (entry is ForMapEntry ) {
@@ -2655,11 +2648,11 @@ class InferenceVisitor
2655
2648
entry.condition = condition..parent = entry;
2656
2649
}
2657
2650
MapLiteralEntry body = checkMapEntry (entry.body, keyType, valueType,
2658
- inferredSpreadTypes, inferredConditionTypes);
2651
+ inferredSpreadTypes, inferredConditionTypes, offsets );
2659
2652
entry.body = body..parent = entry;
2660
2653
} else if (entry is ForInMapEntry ) {
2661
2654
MapLiteralEntry body = checkMapEntry (entry.body, keyType, valueType,
2662
- inferredSpreadTypes, inferredConditionTypes);
2655
+ inferredSpreadTypes, inferredConditionTypes, offsets );
2663
2656
entry.body = body..parent = entry;
2664
2657
} else {
2665
2658
// Do nothing. Assignability checks are done during type inference.
@@ -2735,11 +2728,8 @@ class InferenceVisitor
2735
2728
bool hasMapEntry = false ;
2736
2729
bool hasMapSpread = false ;
2737
2730
bool hasIterableSpread = false ;
2731
+ _MapLiteralEntryOffsets offsets = new _MapLiteralEntryOffsets ();
2738
2732
if (inferenceNeeded || typeChecksNeeded) {
2739
- mapEntryOffset = null ;
2740
- mapSpreadOffset = null ;
2741
- iterableSpreadOffset = null ;
2742
- iterableSpreadType = null ;
2743
2733
DartType spreadTypeContext = const UnknownType ();
2744
2734
if (typeContextIsIterable && ! typeContextIsMap) {
2745
2735
spreadTypeContext = inferrer.typeSchemaEnvironment.getTypeAsInstanceOf (
@@ -2754,9 +2744,8 @@ class InferenceVisitor
2754
2744
< DartType > [inferredKeyType, inferredValueType]);
2755
2745
}
2756
2746
for (int index = 0 ; index < node.entries.length; ++ index) {
2757
- MapLiteralEntry entry = node.entries[index];
2758
- entry = inferMapEntry (
2759
- entry,
2747
+ MapLiteralEntry entry = inferMapEntry (
2748
+ node.entries[index],
2760
2749
node,
2761
2750
inferredKeyType,
2762
2751
inferredValueType,
@@ -2766,16 +2755,17 @@ class InferenceVisitor
2766
2755
inferredSpreadTypes! ,
2767
2756
inferredConditionTypes! ,
2768
2757
inferenceNeeded,
2769
- typeChecksNeeded);
2758
+ typeChecksNeeded,
2759
+ offsets);
2770
2760
node.entries[index] = entry..parent = node;
2771
2761
if (inferenceNeeded) {
2772
2762
formalTypes! .add (mapType.typeArguments[0 ]);
2773
2763
formalTypes.add (mapType.typeArguments[1 ]);
2774
2764
}
2775
2765
}
2776
- hasMapEntry = mapEntryOffset != null ;
2777
- hasMapSpread = mapSpreadOffset != null ;
2778
- hasIterableSpread = iterableSpreadOffset != null ;
2766
+ hasMapEntry = offsets. mapEntryOffset != null ;
2767
+ hasMapSpread = offsets. mapSpreadOffset != null ;
2768
+ hasIterableSpread = offsets. iterableSpreadOffset != null ;
2779
2769
}
2780
2770
if (inferenceNeeded) {
2781
2771
bool canBeSet = ! hasMapSpread && ! hasMapEntry && ! typeContextIsMap;
@@ -2880,8 +2870,13 @@ class InferenceVisitor
2880
2870
}
2881
2871
if (typeChecksNeeded) {
2882
2872
for (int index = 0 ; index < node.entries.length; ++ index) {
2883
- MapLiteralEntry entry = checkMapEntry (node.entries[index], node.keyType,
2884
- node.valueType, inferredSpreadTypes! , inferredConditionTypes! );
2873
+ MapLiteralEntry entry = checkMapEntry (
2874
+ node.entries[index],
2875
+ node.keyType,
2876
+ node.valueType,
2877
+ inferredSpreadTypes! ,
2878
+ inferredConditionTypes! ,
2879
+ offsets);
2885
2880
node.entries[index] = entry..parent = node;
2886
2881
}
2887
2882
}
@@ -7348,3 +7343,18 @@ class _UriOffset {
7348
7343
7349
7344
_UriOffset (this .uri, this .fileOffset);
7350
7345
}
7346
+
7347
+ /// Offset and type information collection in [InferenceVisitor.inferMapEntry] .
7348
+ class _MapLiteralEntryOffsets {
7349
+ // Stores the offset of the map entry found by inferMapEntry.
7350
+ int ? mapEntryOffset;
7351
+
7352
+ // Stores the offset of the map spread found by inferMapEntry.
7353
+ int ? mapSpreadOffset;
7354
+
7355
+ // Stores the offset of the iterable spread found by inferMapEntry.
7356
+ int ? iterableSpreadOffset;
7357
+
7358
+ // Stores the type of the iterable spread found by inferMapEntry.
7359
+ DartType ? iterableSpreadType;
7360
+ }
0 commit comments