Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(317)

Side by Side Diff: frog/await/transformation.dart

Issue 9121025: cleanup to Value - fix for StringEscapesTest (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 8 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 /** 5 /**
6 * Desugarizes all await calls in a single function. This visitor assumes that 6 * Desugarizes all await calls in a single function. This visitor assumes that
7 * the tree is already normalized with [AwaitNormalizer]. For this reason it 7 * the tree is already normalized with [AwaitNormalizer]. For this reason it
8 * only needs to recurse on statements and not on expressions. Like in 8 * only needs to recurse on statements and not on expressions. Like in
9 * [AwaitChecker], nested functions have to be processed separately. 9 * [AwaitChecker], nested functions have to be processed separately.
10 */ 10 */
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
65 } 65 }
66 66
67 visitFunctionDefinition(FunctionDefinition node) { 67 visitFunctionDefinition(FunctionDefinition node) {
68 if (!haveAwait.contains(node)) return node; 68 if (!haveAwait.contains(node)) return node;
69 // TODO(sigmund): consider making this part of the normalizer 69 // TODO(sigmund): consider making this part of the normalizer
70 // make implicit return explicit: 70 // make implicit return explicit:
71 if (node.body is BlockStatement) { 71 if (node.body is BlockStatement) {
72 BlockStatement block = node.body; 72 BlockStatement block = node.body;
73 if (block.body.last() is! ReturnStatement) { 73 if (block.body.last() is! ReturnStatement) {
74 continuation.addFirst( 74 continuation.addFirst(
75 _callCompleter(new NullExpression(node.span), node.span)); 75 _callCompleter(_makeNull(node.span), node.span));
76 } 76 }
77 } 77 }
78 78
79 Statement newBody = node.body.visit(this); 79 Statement newBody = node.body.visit(this);
80 // TODO(sigmund): extract type arg and put it in completer 80 // TODO(sigmund): extract type arg and put it in completer
81 // We update the body in-place to make it easier to update nested functions 81 // We update the body in-place to make it easier to update nested functions
82 // without having to rewrite the containing function's AST. 82 // without having to rewrite the containing function's AST.
83 node.body = new BlockStatement([ 83 node.body = new BlockStatement([
84 _declareCompleter(null, node.span), 84 _declareCompleter(null, node.span),
85 _wrapInTryCatch(newBody, node == _mainMethod.definition), 85 _wrapInTryCatch(newBody, node == _mainMethod.definition),
(...skipping 368 matching lines...) Expand 10 before | Expand all | Expand 10 after
454 [new NewExpression(false, typeRef, null, [], span)], 454 [new NewExpression(false, typeRef, null, [], span)],
455 span); 455 span);
456 return def; 456 return def;
457 } 457 }
458 458
459 /** 459 /**
460 * Wrap [s] in a try-catch block that propagates errors through the future 460 * Wrap [s] in a try-catch block that propagates errors through the future
461 * that is returned from the asynchronous function. If the function that we 461 * that is returned from the asynchronous function. If the function that we
462 * are generating is `main`, we add a noop listener on the resulting future. 462 * are generating is `main`, we add a noop listener on the resulting future.
463 * Without it, we would have to make it illegal to use `await` in main. This 463 * Without it, we would have to make it illegal to use `await` in main. This
464 * is because futures swallow exceptions if their values are never used. 464 * is because futures swallow exceptions if their values are never used.
465 */ 465 */
466 Statement _wrapInTryCatch(Statement s, bool isMain) { 466 Statement _wrapInTryCatch(Statement s, bool isMain) {
467 final ex = new Identifier("ex", s.span); 467 final ex = new Identifier("ex", s.span);
468 Statement catchStatement = 468 Statement catchStatement =
469 _callCompleterException(new VarExpression(ex, ex.span), s.span); 469 _callCompleterException(new VarExpression(ex, ex.span), s.span);
470 if (isMain) { 470 if (isMain) {
471 final future = new DotExpression( 471 final future = new DotExpression(
472 new VarExpression(new Identifier(_COMPLETER_NAME, s.span), s.span), 472 new VarExpression(new Identifier(_COMPLETER_NAME, s.span), s.span),
473 new Identifier("future", s.span), s.span); 473 new Identifier("future", s.span), s.span);
474 final noopHandler = new LambdaExpression( 474 final noopHandler = new LambdaExpression(
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
554 554
555 /** Make a statement invoking a function in scope. */ 555 /** Make a statement invoking a function in scope. */
556 Statement _callNoArg(String mName, SourceSpan span) { 556 Statement _callNoArg(String mName, SourceSpan span) {
557 return new ExpressionStatement(new CallExpression( 557 return new ExpressionStatement(new CallExpression(
558 new VarExpression(new Identifier(mName, span), span), [], span), span); 558 new VarExpression(new Identifier(mName, span), span), [], span), span);
559 } 559 }
560 560
561 /** Make the statement: [: target.method(value); :]. */ 561 /** Make the statement: [: target.method(value); :]. */
562 Statement _callTarget1Arg( 562 Statement _callTarget1Arg(
563 String target, String method, Expression value, SourceSpan span) { 563 String target, String method, Expression value, SourceSpan span) {
564 if (value == null) value = new NullExpression(span); 564 if (value == null) value = _makeNull(span);
565 return new ExpressionStatement(new CallExpression( 565 return new ExpressionStatement(new CallExpression(
566 new DotExpression( 566 new DotExpression(
567 new VarExpression(new Identifier(target, span), span), 567 new VarExpression(new Identifier(target, span), span),
568 new Identifier(method, span), span), 568 new Identifier(method, span), span),
569 [new ArgumentNode(null, value, value.span)], span), span); 569 [new ArgumentNode(null, value, value.span)], span), span);
570 } 570 }
571 571
572 /** Make the statement: [: f(value); :]. */ 572 /** Make the statement: [: f(value); :]. */
573 Statement _call1Arg(String f, Expression value, SourceSpan span) { 573 Statement _call1Arg(String f, Expression value, SourceSpan span) {
574 if (value == null) value = new NullExpression(span); 574 if (value == null) value = _makeNull(span);
575 return new ExpressionStatement(new CallExpression( 575 return new ExpressionStatement(new CallExpression(
576 new VarExpression(new Identifier(f, span), span), 576 new VarExpression(new Identifier(f, span), span),
577 [new ArgumentNode(null, value, value.span)], span), span); 577 [new ArgumentNode(null, value, value.span)], span), span);
578 } 578 }
579 579
580 /** Make the statement: [: f(a, b); :]. */ 580 /** Make the statement: [: f(a, b); :]. */
581 Statement _call2Args(String f, Expression a, Expression b, 581 Statement _call2Args(String f, Expression a, Expression b,
582 SourceSpan span) { 582 SourceSpan span) {
583 if (a == null) a = new NullExpression(span); 583 if (a == null) a = _makeNull(span);
584 if (b == null) b = new NullExpression(span); 584 if (b == null) b = _makeNull(span);
585 return new ExpressionStatement(new CallExpression( 585 return new ExpressionStatement(new CallExpression(
586 new VarExpression(new Identifier(f, span), span), 586 new VarExpression(new Identifier(f, span), span),
587 [new ArgumentNode(null, a, a.span), 587 [new ArgumentNode(null, a, a.span),
588 new ArgumentNode(null, b, b.span)], span), span); 588 new ArgumentNode(null, b, b.span)], span), span);
589 } 589 }
590 590
591 /** Make a return statement for a boolean value. */ 591 /** Make a return statement for a boolean value. */
592 Statement _returnBoolean(SourceSpan span, value) { 592 Statement _returnBoolean(SourceSpan span, bool value) {
593 return new ReturnStatement(new LiteralExpression(value, 593 return new ReturnStatement(
594 new TypeReference(span, world.nonNullBool), "$value", span), span); 594 new LiteralExpression(Value.fromBool(value, span), span), span);
595 }
596
597 Expression _makeNull(SourceSpan span) {
598 return new LiteralExpression(Value.fromNull(span), span);
595 } 599 }
596 } 600 }
597 601
598 // TODO(sigmund): create the following tests: 602 // TODO(sigmund): create the following tests:
599 // - await within the body of getter or setter properties 603 // - await within the body of getter or setter properties
600 // - await in each valid AST construct 604 // - await in each valid AST construct
601 // - exceptions - make some of these fail and propagate errors. 605 // - exceptions - make some of these fail and propagate errors.
602 // - methods with and without returns (are returns added implicitly) 606 // - methods with and without returns (are returns added implicitly)
603 // - await within assignmetns, but not declarations (see what happens with 607 // - await within assignmetns, but not declarations (see what happens with
604 // x = await t; 608 // x = await t;
(...skipping 10 matching lines...) Expand all
615 // if (a) if (b) await t; 2; 619 // if (a) if (b) await t; 2;
616 // becomes: 620 // becomes:
617 // if (a) { if (b) { await t; } } 2; 621 // if (a) { if (b) { await t; } } 2;
618 // which becomes becomes: 622 // which becomes becomes:
619 // _2() { 2; } if (a) { if (b) { t.then((_) { _2(); } } } _2(); 623 // _2() { 2; } if (a) { if (b) { t.then((_) { _2(); } } } _2();
620 // (seems that 'a' doesn't need { }) 624 // (seems that 'a' doesn't need { })
621 // - 'if/while' with only one statement in the continuation (check the 625 // - 'if/while' with only one statement in the continuation (check the
622 // optimization that copies code rather than adding a continuation closure). 626 // optimization that copies code rather than adding a continuation closure).
623 // - await not inside a block (could break error propagation if normalization is 627 // - await not inside a block (could break error propagation if normalization is
624 // done incorrectly). 628 // done incorrectly).
OLDNEW
« no previous file with comments | « frog/await/checker.dart ('k') | frog/gen.dart » ('j') | frog/member.dart » ('J')

Powered by Google App Engine
This is Rietveld 408576698