| 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 e7f019c6b0268907931b61eddc11eef648902d26..1596dd68c7ba30938cc2117f6aa2600f429b1c5b 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
|
| @@ -17,6 +17,7 @@ import 'package:kernel/ast.dart'
|
| Constructor,
|
| DartType,
|
| DynamicType,
|
| + Expression,
|
| Field,
|
| FunctionNode,
|
| FunctionType,
|
| @@ -25,6 +26,7 @@ import 'package:kernel/ast.dart'
|
| Name,
|
| Procedure,
|
| ReturnStatement,
|
| + Statement,
|
| TypeParameter,
|
| TypeParameterType,
|
| VariableDeclaration,
|
| @@ -36,33 +38,25 @@ import 'package:kernel/type_algebra.dart';
|
| /// Keeps track of the local state for the type inference that occurs during
|
| /// compilation of a single method body or top level initializer.
|
| ///
|
| -/// This class abstracts away the representation of the underlying AST using
|
| -/// generic parameters. TODO(paulberry): would it make more sense to abstract
|
| -/// away the representation of types as well?
|
| -///
|
| -/// Derived classes should set S, E, V, and F to the class they use to represent
|
| -/// statements, expressions, variable declarations, and field declarations,
|
| -/// respectively.
|
| -///
|
| /// This class describes the interface for use by clients of type inference
|
| /// (e.g. BodyBuilder). Derived classes should derive from [TypeInferrerImpl].
|
| -abstract class TypeInferrer<S, E, V, F> {
|
| +abstract class TypeInferrer {
|
| /// Gets the [TypePromoter] that can be used to perform type promotion within
|
| /// this method body or initializer.
|
| - TypePromoter<E, V> get typePromoter;
|
| + TypePromoter<Expression, VariableDeclaration> get typePromoter;
|
|
|
| /// The URI of the code for which type inference is currently being
|
| /// performed--this is used for testing.
|
| String get uri;
|
|
|
| /// Gets the [FieldNode] corresponding to the given [readTarget], if any.
|
| - FieldNode<F> getFieldNodeForReadTarget(Member readTarget);
|
| + FieldNode getFieldNodeForReadTarget(Member readTarget);
|
|
|
| /// Performs type inference on the given [statement].
|
| ///
|
| /// Derived classes should override this method with logic that dispatches on
|
| /// the statement type and calls the appropriate specialized "infer" method.
|
| - void inferStatement(S statement);
|
| + void inferStatement(Statement statement);
|
| }
|
|
|
| /// Derived class containing generic implementations of [TypeInferrer].
|
| @@ -70,7 +64,7 @@ abstract class TypeInferrer<S, E, V, F> {
|
| /// This class contains as much of the implementation of type inference as
|
| /// possible without knowing the identity of the type parameters. It defers to
|
| /// abstract methods for everything else.
|
| -abstract class TypeInferrerImpl<S, E, V, F> extends TypeInferrer<S, E, V, F> {
|
| +abstract class TypeInferrerImpl extends TypeInferrer {
|
| static final FunctionType _functionReturningDynamic =
|
| new FunctionType(const [], const DynamicType());
|
|
|
| @@ -98,7 +92,7 @@ abstract class TypeInferrerImpl<S, E, V, F> extends TypeInferrer<S, E, V, F> {
|
| /// inside a closure.
|
| _ClosureContext _closureContext;
|
|
|
| - TypeInferrerImpl(TypeInferenceEngineImpl<F> engine, this.uri, this.listener)
|
| + TypeInferrerImpl(TypeInferenceEngineImpl engine, this.uri, this.listener)
|
| : coreTypes = engine.coreTypes,
|
| strongMode = engine.strongMode,
|
| classHierarchy = engine.classHierarchy,
|
| @@ -107,18 +101,18 @@ abstract class TypeInferrerImpl<S, E, V, F> extends TypeInferrer<S, E, V, F> {
|
|
|
| /// Gets the type promoter that should be used to promote types during
|
| /// inference.
|
| - TypePromoter<E, V> get typePromoter;
|
| + TypePromoter<Expression, VariableDeclaration> get typePromoter;
|
|
|
| /// Gets the initializer for the given [field], or `null` if there is no
|
| /// initializer.
|
| - E getFieldInitializer(F field);
|
| + Expression getFieldInitializer(KernelField field);
|
|
|
| /// Performs the core type inference algorithm for type cast expressions.
|
| ///
|
| /// [typeContext], [typeNeeded], and the return value behave as described in
|
| /// [inferExpression].
|
| - DartType inferAsExpression(
|
| - DartType typeContext, bool typeNeeded, E operand, DartType type) {
|
| + DartType inferAsExpression(DartType typeContext, bool typeNeeded,
|
| + Expression operand, DartType type) {
|
| typeNeeded = listener.asExpressionEnter(typeContext) || typeNeeded;
|
| inferExpression(operand, null, false);
|
| var inferredType = typeNeeded ? type : null;
|
| @@ -144,8 +138,13 @@ abstract class TypeInferrerImpl<S, E, V, F> extends TypeInferrer<S, E, V, F> {
|
| ///
|
| /// [condition], [then], and [otherwise] are the subexpressions. The inferred
|
| /// type is reported via [setStaticType].
|
| - DartType inferConditionalExpression(DartType typeContext, bool typeNeeded,
|
| - E condition, E then, E otherwise, void setStaticType(DartType type)) {
|
| + DartType inferConditionalExpression(
|
| + DartType typeContext,
|
| + bool typeNeeded,
|
| + Expression condition,
|
| + Expression then,
|
| + Expression otherwise,
|
| + void setStaticType(DartType type)) {
|
| typeNeeded = listener.conditionalExpressionEnter(typeContext) || typeNeeded;
|
| inferExpression(condition, coreTypes.boolClass.rawType, false);
|
| // TODO(paulberry): is it correct to pass the context down?
|
| @@ -180,7 +179,7 @@ abstract class TypeInferrerImpl<S, E, V, F> extends TypeInferrer<S, E, V, F> {
|
| int offset,
|
| Constructor target,
|
| List<DartType> explicitTypeArguments,
|
| - void forEachArgument(void callback(String name, E expression)),
|
| + void forEachArgument(void callback(String name, Expression expression)),
|
| void setInferredTypeArguments(List<DartType> types)) {
|
| typeNeeded = listener.constructorInvocationEnter(typeContext) || typeNeeded;
|
| List<DartType> inferredTypes;
|
| @@ -280,10 +279,11 @@ abstract class TypeInferrerImpl<S, E, V, F> extends TypeInferrer<S, E, V, F> {
|
| ///
|
| /// Derived classes should override this method with logic that dispatches on
|
| /// the expression type and calls the appropriate specialized "infer" method.
|
| - DartType inferExpression(E expression, DartType typeContext, bool typeNeeded);
|
| + DartType inferExpression(
|
| + Expression expression, DartType typeContext, bool typeNeeded);
|
|
|
| /// Performs the core type inference algorithm for expression statements.
|
| - void inferExpressionStatement(E expression) {
|
| + void inferExpressionStatement(Expression expression) {
|
| inferExpression(expression, null, false);
|
| }
|
|
|
| @@ -291,13 +291,14 @@ abstract class TypeInferrerImpl<S, E, V, F> extends TypeInferrer<S, E, V, F> {
|
| ///
|
| /// Derived classes should provide an implementation that calls
|
| /// [inferExpression] for the given [field]'s initializer expression.
|
| - DartType inferFieldInitializer(F field, DartType type, bool typeNeeded);
|
| + DartType inferFieldInitializer(
|
| + KernelField field, DartType type, bool typeNeeded);
|
|
|
| /// Performs the core type inference algorithm for local function
|
| /// declarations.
|
| ///
|
| /// [body] is the body of the function.
|
| - void inferFunctionDeclaration(S body) {
|
| + void inferFunctionDeclaration(Statement body) {
|
| var oldClosureContext = _closureContext;
|
| _closureContext = null;
|
| inferStatement(body);
|
| @@ -425,8 +426,7 @@ abstract class TypeInferrerImpl<S, E, V, F> extends TypeInferrer<S, E, V, F> {
|
| bool needToSetReturnType = isExpressionFunction || strongMode;
|
| _ClosureContext oldClosureContext = _closureContext;
|
| _closureContext = new _ClosureContext(isAsync, isGenerator, returnContext);
|
| - // TODO(paulberry): de-genericize this class.
|
| - inferStatement(function.body as S);
|
| + inferStatement(function.body);
|
|
|
| // If the closure is declared with `async*` or `sync*`, let `M` be the least
|
| // upper bound of the types of the `yield` expressions in `B’`, or `void` if
|
| @@ -479,7 +479,8 @@ abstract class TypeInferrerImpl<S, E, V, F> extends TypeInferrer<S, E, V, F> {
|
| }
|
|
|
| /// Performs the core type inference algorithm for if statements.
|
| - void inferIfStatement(E condition, S then, S otherwise) {
|
| + void inferIfStatement(
|
| + Expression condition, Statement then, Statement otherwise) {
|
| inferExpression(condition, coreTypes.boolClass.rawType, false);
|
| inferStatement(then);
|
| if (otherwise != null) inferStatement(otherwise);
|
| @@ -502,7 +503,8 @@ abstract class TypeInferrerImpl<S, E, V, F> extends TypeInferrer<S, E, V, F> {
|
| /// [inferExpression].
|
| ///
|
| /// [operand] is the expression appearing to the left of "is".
|
| - DartType inferIsExpression(DartType typeContext, bool typeNeeded, E operand) {
|
| + DartType inferIsExpression(
|
| + DartType typeContext, bool typeNeeded, Expression operand) {
|
| typeNeeded = listener.isExpressionEnter(typeContext) || typeNeeded;
|
| inferExpression(operand, null, false);
|
| var inferredType = typeNeeded ? coreTypes.boolClass.rawType : null;
|
| @@ -519,7 +521,7 @@ abstract class TypeInferrerImpl<S, E, V, F> extends TypeInferrer<S, E, V, F> {
|
| bool typeNeeded,
|
| int offset,
|
| DartType declaredTypeArgument,
|
| - Iterable<E> expressions,
|
| + Iterable<Expression> expressions,
|
| void setTypeArgument(DartType typeArgument)) {
|
| typeNeeded = listener.listLiteralEnter(typeContext) || typeNeeded;
|
| var listClass = coreTypes.listClass;
|
| @@ -585,10 +587,10 @@ abstract class TypeInferrerImpl<S, E, V, F> extends TypeInferrer<S, E, V, F> {
|
| DartType typeContext,
|
| bool typeNeeded,
|
| int offset,
|
| - E receiver,
|
| + Expression receiver,
|
| Name methodName,
|
| List<DartType> explicitTypeArguments,
|
| - void forEachArgument(void callback(String name, E expression)),
|
| + void forEachArgument(void callback(String name, Expression expression)),
|
| void setInferredTypeArguments(List<DartType> types),
|
| void setInterfaceTarget(Procedure procedure)) {
|
| typeNeeded = listener.methodInvocationEnter(typeContext) || typeNeeded;
|
| @@ -696,7 +698,7 @@ abstract class TypeInferrerImpl<S, E, V, F> extends TypeInferrer<S, E, V, F> {
|
| ///
|
| /// [body] is the expression being returned, or `null` for a bare return
|
| /// statement.
|
| - void inferReturnStatement(E expression) {
|
| + void inferReturnStatement(Expression expression) {
|
| var closureContext = _closureContext;
|
| var typeContext = closureContext != null && !closureContext.isGenerator
|
| ? closureContext.returnContext
|
| @@ -727,9 +729,9 @@ 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 inferStringConcatenation(
|
| - DartType typeContext, bool typeNeeded, Iterable<E> expressions) {
|
| + DartType typeContext, bool typeNeeded, Iterable<Expression> expressions) {
|
| typeNeeded = listener.stringConcatenationEnter(typeContext) || typeNeeded;
|
| - for (E expression in expressions) {
|
| + for (Expression expression in expressions) {
|
| inferExpression(expression, null, false);
|
| }
|
| var inferredType = typeNeeded ? coreTypes.stringClass.rawType : null;
|
| @@ -755,7 +757,7 @@ abstract class TypeInferrerImpl<S, E, V, F> extends TypeInferrer<S, E, V, F> {
|
| /// [offset] is the character offset of the variable declaration (for
|
| /// instrumentation). [setType] is a callback that will be used to set the
|
| /// inferred type.
|
| - void inferVariableDeclaration(DartType declaredType, E initializer,
|
| + void inferVariableDeclaration(DartType declaredType, Expression initializer,
|
| int offset, void setType(DartType type)) {
|
| if (initializer == null) return;
|
| var inferredType = inferDeclarationOrReturnType(
|
| @@ -771,7 +773,7 @@ abstract class TypeInferrerImpl<S, E, V, F> extends TypeInferrer<S, E, V, F> {
|
| DartType typeContext,
|
| bool typeNeeded,
|
| bool mutatedInClosure,
|
| - TypePromotionFact<V> typePromotionFact,
|
| + TypePromotionFact<VariableDeclaration> typePromotionFact,
|
| TypePromotionScope typePromotionScope,
|
| int offset,
|
| DartType declaredOrInferredType,
|
| @@ -790,8 +792,8 @@ abstract class TypeInferrerImpl<S, E, V, F> extends TypeInferrer<S, E, V, F> {
|
| return inferredType;
|
| }
|
|
|
| - DartType inferVariableSet(
|
| - DartType typeContext, bool typeNeeded, DartType declaredType, E value) {
|
| + DartType inferVariableSet(DartType typeContext, bool typeNeeded,
|
| + DartType declaredType, Expression value) {
|
| typeNeeded = listener.variableSetEnter(typeContext) || typeNeeded;
|
| var inferredType = inferExpression(value, declaredType, typeNeeded);
|
| listener.variableSetExit(inferredType);
|
|
|