| Index: pkg/compiler/lib/src/cps_ir/cps_ir_builder_task.dart
|
| diff --git a/pkg/compiler/lib/src/cps_ir/cps_ir_builder_task.dart b/pkg/compiler/lib/src/cps_ir/cps_ir_builder_task.dart
|
| index 3ae2c1bd8b306e4d385366a8cd3a4fd3465aa8bd..4d5b2940b22065f10c7280d193df7819993301f1 100644
|
| --- a/pkg/compiler/lib/src/cps_ir/cps_ir_builder_task.dart
|
| +++ b/pkg/compiler/lib/src/cps_ir/cps_ir_builder_task.dart
|
| @@ -1111,8 +1111,105 @@ class IrBuilderVisitor extends ast.Visitor<ir.Primitive>
|
| }
|
|
|
| visitAsyncForIn(ast.AsyncForIn node) {
|
| - // await for is not yet implemented.
|
| - return giveup(node, 'await for');
|
| + // Translate await for into a loop over a StreamIterator. The source
|
| + // statement:
|
| + //
|
| + // await for (<decl> in <stream>) <body>
|
| + //
|
| + // is translated as if it were:
|
| + //
|
| + // var iterator = new StreamIterator(<stream>);
|
| + // try {
|
| + // while (await iterator.hasNext()) {
|
| + // <decl> = await iterator.current;
|
| + // <body>
|
| + // }
|
| + // } finally {
|
| + // await iterator.cancel();
|
| + // }
|
| + ir.Primitive stream = visit(node.expression);
|
| + ir.Primitive dummyTypeArgument = irBuilder.buildNullConstant();
|
| + ConstructorElement constructor = helpers.streamIteratorConstructor;
|
| + ir.Primitive iterator = irBuilder.addPrimitive(new ir.InvokeConstructor(
|
| + constructor.enclosingClass.thisType,
|
| + constructor,
|
| + new Selector.callConstructor(constructor.memberName, 1),
|
| + <ir.Primitive>[stream, dummyTypeArgument],
|
| + sourceInformationBuilder.buildGeneric(node)));
|
| +
|
| + ir.Node buildTryBody(IrBuilder builder) {
|
| + ir.Node buildLoopCondition(IrBuilder builder) {
|
| + ir.Primitive moveNext = builder.buildDynamicInvocation(
|
| + iterator,
|
| + Selectors.moveNext,
|
| + elements.getMoveNextTypeMask(node),
|
| + <ir.Primitive>[]);
|
| + return builder.addPrimitive(new ir.Await(moveNext));
|
| + }
|
| +
|
| + ir.Node buildLoopBody(IrBuilder builder) {
|
| + return withBuilder(builder, () {
|
| + ir.Primitive current = irBuilder.buildDynamicInvocation(
|
| + iterator,
|
| + Selectors.current,
|
| + elements.getCurrentTypeMask(node),
|
| + <ir.Primitive>[]);
|
| + Element variable = elements.getForInVariable(node);
|
| + if (Elements.isLocal(variable)) {
|
| + if (node.declaredIdentifier.asVariableDefinitions() != null) {
|
| + irBuilder.declareLocalVariable(variable);
|
| + }
|
| + irBuilder.buildLocalVariableSet(variable, current);
|
| + } else if (Elements.isError(variable) ||
|
| + Elements.isMalformed(variable)) {
|
| + Selector selector =
|
| + new Selector.setter(new Name(variable.name, variable.library));
|
| + List<ir.Primitive> args = <ir.Primitive>[current];
|
| + // Note the comparison below. It can be the case that an element
|
| + // isError and isMalformed.
|
| + if (Elements.isError(variable)) {
|
| + irBuilder.buildStaticNoSuchMethod(selector, args);
|
| + } else {
|
| + irBuilder.buildErroneousInvocation(variable, selector, args);
|
| + }
|
| + } else if (Elements.isStaticOrTopLevel(variable)) {
|
| + if (variable.isField) {
|
| + irBuilder.addPrimitive(new ir.SetStatic(variable, current));
|
| + } else {
|
| + irBuilder.buildStaticSetterSet(variable, current);
|
| + }
|
| + } else {
|
| + ir.Primitive receiver = irBuilder.buildThis();
|
| + ast.Node identifier = node.declaredIdentifier;
|
| + irBuilder.buildDynamicSet(
|
| + receiver,
|
| + elements.getSelector(identifier),
|
| + elements.getTypeMask(identifier),
|
| + current);
|
| + }
|
| + visit(node.body);
|
| + });
|
| + }
|
| +
|
| + builder.buildWhile(
|
| + buildCondition: buildLoopCondition,
|
| + buildBody: buildLoopBody,
|
| + target: elements.getTargetDefinition(node),
|
| + closureScope: getClosureScopeForNode(node));
|
| + }
|
| +
|
| + ir.Node buildFinallyBody(IrBuilder builder) {
|
| + ir.Primitive cancellation = builder.buildDynamicInvocation(
|
| + iterator,
|
| + Selectors.cancel,
|
| + backend.dynamicType,
|
| + <ir.Primitive>[],
|
| + sourceInformation: sourceInformationBuilder.buildGeneric(node));
|
| + return builder.addPrimitive(new ir.Await(cancellation));
|
| + }
|
| +
|
| + irBuilder.buildTryFinally(new TryStatementInfo(), buildTryBody,
|
| + buildFinallyBody);
|
| }
|
|
|
| visitAwait(ast.Await node) {
|
|
|