@@ -11,10 +11,6 @@ class InferenceVisitor extends BodyVisitor1<void, DartType> {
11
11
12
12
@override
13
13
void defaultExpression (Expression node, DartType typeContext) {
14
- if (node is IfElement ) {
15
- visitIfElement (node, typeContext);
16
- return ;
17
- }
18
14
unhandled ("${node .runtimeType }" , "InferenceVisitor" , node.fileOffset,
19
15
inferrer.helper.uri);
20
16
}
@@ -25,11 +21,6 @@ class InferenceVisitor extends BodyVisitor1<void, DartType> {
25
21
inferrer.helper.uri);
26
22
}
27
23
28
- visitIfElement (IfElement node, DartType typeContext) {
29
- node.parent.replaceChild (node,
30
- new InvalidExpression ('unhandled if element in collection literal' ));
31
- }
32
-
33
24
@override
34
25
void visitInvalidExpression (InvalidExpression node, DartType typeContext) {}
35
26
@@ -665,6 +656,45 @@ class InferenceVisitor extends BodyVisitor1<void, DartType> {
665
656
return null ;
666
657
}
667
658
659
+ DartType inferElement (
660
+ Expression element,
661
+ int index,
662
+ DartType inferredTypeArgument,
663
+ List <DartType > spreadTypes,
664
+ bool inferenceNeeded,
665
+ bool typeChecksNeeded) {
666
+ if (element is SpreadElement ) {
667
+ DartType spreadType = inferrer.inferExpression (
668
+ element.expression,
669
+ new InterfaceType (inferrer.coreTypes.iterableClass,
670
+ < DartType > [inferredTypeArgument]),
671
+ inferenceNeeded || typeChecksNeeded,
672
+ isVoidAllowed: true );
673
+ if (typeChecksNeeded) {
674
+ spreadTypes[index] = spreadType;
675
+ }
676
+ // Use 'dynamic' for error recovery.
677
+ return getSpreadElementType (spreadType, element.isNullAware) ??
678
+ const DynamicType ();
679
+ } else if (element is IfElement ) {
680
+ inferrer.inferExpression (element.condition,
681
+ inferrer.coreTypes.boolClass.rawType, typeChecksNeeded,
682
+ isVoidAllowed: false );
683
+ inferElement (element.then, index, inferredTypeArgument, spreadTypes,
684
+ inferenceNeeded, typeChecksNeeded);
685
+ if (element.otherwise != null ) {
686
+ inferElement (element.otherwise, index, inferredTypeArgument,
687
+ spreadTypes, inferenceNeeded, typeChecksNeeded);
688
+ }
689
+ // TODO(kmillikin): Implement inference rules for if elements.
690
+ return const DynamicType ();
691
+ } else {
692
+ return inferrer.inferExpression (
693
+ element, inferredTypeArgument, inferenceNeeded || typeChecksNeeded,
694
+ isVoidAllowed: true );
695
+ }
696
+ }
697
+
668
698
void visitListLiteralJudgment (
669
699
ListLiteralJudgment node, DartType typeContext) {
670
700
var listClass = inferrer.coreTypes.listClass;
@@ -692,32 +722,16 @@ class InferenceVisitor extends BodyVisitor1<void, DartType> {
692
722
typeChecksNeeded ? new List <DartType >(node.expressions.length) : null ;
693
723
if (inferenceNeeded || typeChecksNeeded) {
694
724
for (int i = 0 ; i < node.expressions.length; ++ i) {
695
- Expression judgment = node.expressions[i];
696
- if (judgment is SpreadElement ) {
697
- DartType spreadType = inferrer.inferExpression (
698
- judgment.expression,
699
- new InterfaceType (inferrer.coreTypes.iterableClass,
700
- < DartType > [inferredTypeArgument]),
701
- inferenceNeeded || typeChecksNeeded,
702
- isVoidAllowed: true );
703
- if (inferenceNeeded) {
704
- formalTypes.add (listType.typeArguments[0 ]);
705
- }
706
- if (typeChecksNeeded) {
707
- spreadTypes[i] = spreadType;
708
- }
709
- // Use 'dynamic' for error recovery.
710
- actualTypes.add (
711
- getSpreadElementType (spreadType, judgment.isNullAware) ??
712
- const DynamicType ());
713
- } else {
714
- inferrer.inferExpression (judgment, inferredTypeArgument,
715
- inferenceNeeded || typeChecksNeeded,
716
- isVoidAllowed: true );
717
- if (inferenceNeeded) {
718
- formalTypes.add (listType.typeArguments[0 ]);
719
- }
720
- actualTypes.add (getInferredType (judgment, inferrer));
725
+ DartType type = inferElement (
726
+ node.expressions[i],
727
+ i,
728
+ inferredTypeArgument,
729
+ spreadTypes,
730
+ inferenceNeeded,
731
+ typeChecksNeeded);
732
+ actualTypes.add (type);
733
+ if (inferenceNeeded) {
734
+ formalTypes.add (listType.typeArguments[0 ]);
721
735
}
722
736
}
723
737
}
@@ -777,6 +791,8 @@ class InferenceVisitor extends BodyVisitor1<void, DartType> {
777
791
1 )));
778
792
}
779
793
}
794
+ } else if (item is IfElement ) {
795
+ // TODO(kmillikin): Insert type checks on if elements.
780
796
} else {
781
797
inferrer.ensureAssignable (
782
798
node.typeArgument, actualTypes[i], item, item.fileOffset,
@@ -1375,32 +1391,16 @@ class InferenceVisitor extends BodyVisitor1<void, DartType> {
1375
1391
typeChecksNeeded ? new List <DartType >(node.expressions.length) : null ;
1376
1392
if (inferenceNeeded || typeChecksNeeded) {
1377
1393
for (int i = 0 ; i < node.expressions.length; ++ i) {
1378
- Expression judgment = node.expressions[i];
1379
- if (judgment is SpreadElement ) {
1380
- DartType spreadType = inferrer.inferExpression (
1381
- judgment.expression,
1382
- new InterfaceType (inferrer.coreTypes.iterableClass,
1383
- < DartType > [inferredTypeArgument]),
1384
- inferenceNeeded || typeChecksNeeded,
1385
- isVoidAllowed: true );
1386
- if (inferenceNeeded) {
1387
- formalTypes.add (setType.typeArguments[0 ]);
1388
- }
1389
- if (typeChecksNeeded) {
1390
- spreadTypes[i] = spreadType;
1391
- }
1392
- // Use 'dynamic' for error recovery.
1393
- actualTypes.add (
1394
- getSpreadElementType (spreadType, judgment.isNullAware) ??
1395
- const DynamicType ());
1396
- } else {
1397
- inferrer.inferExpression (judgment, inferredTypeArgument,
1398
- inferenceNeeded || typeChecksNeeded,
1399
- isVoidAllowed: true );
1400
- if (inferenceNeeded) {
1401
- formalTypes.add (setType.typeArguments[0 ]);
1402
- }
1403
- actualTypes.add (getInferredType (judgment, inferrer));
1394
+ DartType type = inferElement (
1395
+ node.expressions[i],
1396
+ i,
1397
+ inferredTypeArgument,
1398
+ spreadTypes,
1399
+ inferenceNeeded,
1400
+ typeChecksNeeded);
1401
+ actualTypes.add (type);
1402
+ if (inferenceNeeded) {
1403
+ formalTypes.add (setType.typeArguments[0 ]);
1404
1404
}
1405
1405
}
1406
1406
}
@@ -1460,6 +1460,8 @@ class InferenceVisitor extends BodyVisitor1<void, DartType> {
1460
1460
1 )));
1461
1461
}
1462
1462
}
1463
+ } else if (item is IfElement ) {
1464
+ // TODO(kmillikin): Insert type checks on if elements.
1463
1465
} else {
1464
1466
inferrer.ensureAssignable (node.typeArgument, actualTypes[i],
1465
1467
node.expressions[i], node.expressions[i].fileOffset,
0 commit comments