Index: pkg/front_end/lib/src/fasta/type_inference/type_inferrer.dart |
diff --git a/pkg/front_end/lib/src/fasta/type_inference/type_inferrer.dart b/pkg/front_end/lib/src/fasta/type_inference/type_inferrer.dart |
index 1f83f1b64358f47f93aca0394eb30f910d6f40e8..48eeba31b05e4fb0022866a7d9ca5953f0e6a2aa 100644 |
--- a/pkg/front_end/lib/src/fasta/type_inference/type_inferrer.dart |
+++ b/pkg/front_end/lib/src/fasta/type_inference/type_inferrer.dart |
@@ -238,13 +238,59 @@ abstract class TypeInferrerImpl<S, E, V, F> extends TypeInferrer<S, E, V, F> { |
/// [typeContext], [typeNeeded], and the return value behave as described in |
/// [inferExpression]. |
DartType inferListLiteral( |
- DartType typeContext, bool typeNeeded, DartType typeArgument) { |
- if (!typeNeeded) return null; |
- if (typeArgument != null) { |
- return new InterfaceType(coreTypes.listClass, [typeArgument]); |
+ DartType typeContext, |
+ bool typeNeeded, |
+ int offset, |
+ DartType declaredTypeArgument, |
+ Iterable<E> expressions, |
+ void setTypeArgument(DartType typeArgument)) { |
+ var listClass = coreTypes.listClass; |
+ var listType = listClass.thisType; |
+ List<DartType> typesFromDownwardsInference; |
+ InterfaceType inferredListType; |
+ DartType inferredTypeArgument; |
+ List<DartType> formalTypes; |
+ List<DartType> actualTypes; |
+ bool inferenceNeeded = declaredTypeArgument == null && strongMode; |
+ if (inferenceNeeded) { |
+ typesFromDownwardsInference = [null]; |
+ inferredListType = typeSchemaEnvironment.inferGenericFunctionOrType( |
+ listClass.typeParameters, |
+ listType, |
+ [], |
+ [], |
+ typeContext, |
+ typesFromDownwardsInference, |
+ downwards: true); |
+ inferredTypeArgument = typesFromDownwardsInference[0]; |
+ formalTypes = []; |
+ actualTypes = []; |
+ } else { |
+ inferredTypeArgument = declaredTypeArgument ?? const DynamicType(); |
+ inferredListType = new InterfaceType(listClass, [inferredTypeArgument]); |
+ } |
+ for (var expression in expressions) { |
+ var expressionType = |
+ inferExpression(expression, inferredTypeArgument, inferenceNeeded); |
+ if (inferenceNeeded) { |
+ formalTypes.add(listType.typeArguments[0]); |
+ actualTypes.add(expressionType); |
+ } |
+ } |
+ if (inferenceNeeded) { |
+ inferredListType = typeSchemaEnvironment.inferGenericFunctionOrType( |
+ listClass.typeParameters, |
+ listType, |
+ formalTypes, |
+ actualTypes, |
+ typeContext, |
+ typesFromDownwardsInference); |
+ inferredTypeArgument = inferredListType.typeArguments[0]; |
+ instrumentation?.record(Uri.parse(uri), offset, 'typeArgs', |
+ new InstrumentationValueForTypeArgs([inferredTypeArgument])); |
+ setTypeArgument(inferredTypeArgument); |
} |
- // TODO(scheglov) Implement LUB for list elements |
- return const DynamicType(); |
+ return typeNeeded ? inferredListType : null; |
} |
/// Performs the core type inference algorithm for static variable getters. |