Chromium Code Reviews| Index: pkg/front_end/lib/src/fasta/kernel/kernel_shadow_ast.dart |
| diff --git a/pkg/front_end/lib/src/fasta/kernel/kernel_shadow_ast.dart b/pkg/front_end/lib/src/fasta/kernel/kernel_shadow_ast.dart |
| index fc6476d6a6edce75691183cfd8dd7f80a504044f..acbaebe66ef48e0d374fe11d445347f797aad3fe 100644 |
| --- a/pkg/front_end/lib/src/fasta/kernel/kernel_shadow_ast.dart |
| +++ b/pkg/front_end/lib/src/fasta/kernel/kernel_shadow_ast.dart |
| @@ -440,6 +440,59 @@ class KernelField extends Field { |
| } |
| } |
| +/// Concrete shadow object representing a for-in loop in kernel form. |
| +class KernelForInStatement extends ForInStatement implements KernelStatement { |
| + final bool _declaresVariable; |
| + |
| + KernelForInStatement(VariableDeclaration variable, Expression iterable, |
| + Statement body, this._declaresVariable, |
| + {bool isAsync: false}) |
| + : super(variable, iterable, body, isAsync: isAsync); |
| + |
| + @override |
| + void _inferStatement(KernelTypeInferrer inferrer) { |
| + inferrer.listener.forInStatementEnter(this); |
| + var iterableClass = isAsync |
| + ? inferrer.coreTypes.streamClass |
| + : inferrer.coreTypes.iterableClass; |
| + DartType context; |
| + bool typeNeeded = false; |
| + KernelVariableDeclaration variable; |
| + if (_declaresVariable) { |
| + variable = this.variable; |
| + if (variable._implicitlyTyped) { |
| + typeNeeded = true; |
| + // TODO(paulberry): In this case, should the context be `Iterable<?>`? |
| + } else { |
| + context = inferrer.wrapType(variable.type, iterableClass); |
| + } |
| + } else { |
| + // TODO(paulberry): In this case, should the context be based on the |
| + // declared type of the loop variable? |
|
ahe
2017/05/29 13:39:22
Notice also that the loop variable corresponds to
Paul Berry
2017/05/29 14:23:32
Good point. I've added a TODO to address this.
|
| + } |
| + var inferredExpressionType = |
| + inferrer.inferExpression(iterable, context, typeNeeded); |
| + if (typeNeeded) { |
| + var inferredType = const DynamicType(); |
| + if (inferredExpressionType is InterfaceType) { |
| + InterfaceType supertype = inferrer.classHierarchy |
| + .getTypeAsInstanceOf(inferredExpressionType, iterableClass); |
| + if (supertype != null) { |
| + inferredType = supertype.typeArguments[0]; |
| + } |
| + } |
| + inferrer.instrumentation?.record( |
| + Uri.parse(inferrer.uri), |
| + variable.fileOffset, |
| + 'type', |
| + new InstrumentationValueForType(inferredType)); |
| + variable.type = inferredType; |
| + } |
| + inferrer.inferStatement(body); |
| + inferrer.listener.forInStatementExit(this); |
| + } |
| +} |
| + |
| /// Concrete shadow object representing a local function declaration in kernel |
| /// form. |
| class KernelFunctionDeclaration extends FunctionDeclaration |