@@ -2456,7 +2456,7 @@ abstract class BodyBuilder extends ScopeListener<JumpTarget>
2456
2456
if (entry is MapEntry ) {
2457
2457
// TODO(danrubel): report the error on the colon
2458
2458
addProblem (fasta.templateExpectedButGot.withArguments (',' ),
2459
- entry.value. fileOffset - 1 , 1 );
2459
+ entry.fileOffset, 1 );
2460
2460
} else {
2461
2461
// TODO(danrubel): Revise once control flow and spread
2462
2462
// collection entries are supported.
@@ -2518,6 +2518,13 @@ abstract class BodyBuilder extends ScopeListener<JumpTarget>
2518
2518
final typeArgCount = typeArguments? .length;
2519
2519
bool isSet = typeArgCount == 1 ? true : typeArgCount != null ? false : null ;
2520
2520
2521
+ for (int i = 0 ; i < setOrMapEntries.length; ++ i) {
2522
+ if (setOrMapEntries[i] is ! MapEntry &&
2523
+ ! isConvertibleToMapEntry (setOrMapEntries[i])) {
2524
+ hasSetEntry = true ;
2525
+ }
2526
+ }
2527
+
2521
2528
// TODO(danrubel): If the type arguments are not known (null) then
2522
2529
// defer set/map determination until after type resolution as per the
2523
2530
// unified collection spec: https://github.com/dart-lang/language/pull/200
@@ -2527,7 +2534,15 @@ abstract class BodyBuilder extends ScopeListener<JumpTarget>
2527
2534
if (isSet) {
2528
2535
buildLiteralSet (typeArguments, constKeyword, leftBrace, setOrMapEntries);
2529
2536
} else {
2530
- buildLiteralMap (typeArguments, constKeyword, leftBrace, setOrMapEntries);
2537
+ List <MapEntry > mapEntries = new List <MapEntry >(setOrMapEntries.length);
2538
+ for (int i = 0 ; i < setOrMapEntries.length; ++ i) {
2539
+ if (setOrMapEntries[i] is MapEntry ) {
2540
+ mapEntries[i] = setOrMapEntries[i];
2541
+ } else {
2542
+ mapEntries[i] = convertToMapEntry (setOrMapEntries[i]);
2543
+ }
2544
+ }
2545
+ buildLiteralMap (typeArguments, constKeyword, leftBrace, mapEntries);
2531
2546
}
2532
2547
}
2533
2548
@@ -2551,10 +2566,26 @@ abstract class BodyBuilder extends ScopeListener<JumpTarget>
2551
2566
push (forest.literalNull (token));
2552
2567
}
2553
2568
2569
+ bool isConvertibleToMapEntry (Expression element) {
2570
+ if (element is SpreadElement ) return true ;
2571
+ if (element is IfElement ) {
2572
+ return isConvertibleToMapEntry (element.then) &&
2573
+ (element.otherwise == null ||
2574
+ isConvertibleToMapEntry (element.otherwise));
2575
+ }
2576
+ if (element is ForElement ) {
2577
+ return isConvertibleToMapEntry (element.body);
2578
+ }
2579
+ if (element is ForInElement ) {
2580
+ return isConvertibleToMapEntry (element.body);
2581
+ }
2582
+ return false ;
2583
+ }
2584
+
2554
2585
MapEntry convertToMapEntry (Expression element) {
2555
2586
if (element is SpreadElement ) {
2556
2587
return new SpreadMapEntry (element.expression, element.isNullAware)
2557
- ..fileOffset = element.fileOffset;
2588
+ ..fileOffset = element.expression. fileOffset;
2558
2589
}
2559
2590
if (element is IfElement ) {
2560
2591
return new IfMapEntry (
@@ -2586,7 +2617,7 @@ abstract class BodyBuilder extends ScopeListener<JumpTarget>
2586
2617
}
2587
2618
2588
2619
void buildLiteralMap (List <UnresolvedType <KernelTypeBuilder >> typeArguments,
2589
- Token constKeyword, Token leftBrace, List <dynamic > setOrMapEntries ) {
2620
+ Token constKeyword, Token leftBrace, List <MapEntry > entries ) {
2590
2621
DartType keyType;
2591
2622
DartType valueType;
2592
2623
if (typeArguments != null ) {
@@ -2607,17 +2638,6 @@ abstract class BodyBuilder extends ScopeListener<JumpTarget>
2607
2638
valueType = implicitTypeArgument;
2608
2639
}
2609
2640
2610
- List <MapEntry > entries = < MapEntry > [];
2611
- if (setOrMapEntries != null ) {
2612
- for (var entry in setOrMapEntries) {
2613
- if (entry is MapEntry ) {
2614
- entries.add (entry);
2615
- } else {
2616
- entries.add (convertToMapEntry (entry));
2617
- }
2618
- }
2619
- }
2620
-
2621
2641
Expression node = forest.literalMap (
2622
2642
constKeyword,
2623
2643
constKeyword != null || constantContext == ConstantContext .inferred,
0 commit comments