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

Unified Diff: lib/src/codegen/js_metalet.dart

Issue 1243503007: fixes #221, initial sync*, async, async* implementation (Closed) Base URL: git@github.com:dart-lang/dev_compiler.git@master
Patch Set: Created 5 years, 5 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « lib/src/codegen/js_codegen.dart ('k') | lib/src/info.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: lib/src/codegen/js_metalet.dart
diff --git a/lib/src/codegen/js_metalet.dart b/lib/src/codegen/js_metalet.dart
index a51298e346af0684d3b583c4d59e260d6d9e9737..12f7811c390da883ffce5366c1a9c70b887fe550 100644
--- a/lib/src/codegen/js_metalet.dart
+++ b/lib/src/codegen/js_metalet.dart
@@ -64,7 +64,8 @@ class MetaLet extends Expression {
ExpressionStatement es = s.first;
return es.expression;
}
- return new Call(new ArrowFun([], block), []);
+
+ return _toInvokedFunction(block);
}
Expression toAssignExpression(Expression left) {
@@ -94,8 +95,7 @@ class MetaLet extends Expression {
return _expression = es.value;
}
// Wrap it in an immediately called function to get in expression context.
- // TODO(jmesserly):
- return _expression = new Call(new ArrowFun([], block), []);
+ return _expression = _toInvokedFunction(block);
}
Block toStatement() {
@@ -129,6 +129,19 @@ class MetaLet extends Expression {
/// This generates as either a comma expression or a call.
int get precedenceLevel => variables.isEmpty ? EXPRESSION : CALL;
+ Expression _toInvokedFunction(Statement block) {
+ var finder = new _YieldFinder();
+ block.accept(finder);
+ if (!finder.hasYield) {
+ return new Call(new ArrowFun([], block), []);
+ }
+ // If we have a yield, it's more tricky. We'll create a `function*`, which
+ // we `yield*` to immediately invoke. We also may need to bind this:
+ Expression fn = new Fun([], block, isGenerator: true);
+ if (finder.hasThis) fn = js.call('#.bind(this)', fn);
+ return new Yield(new Call(fn, []), star: true);
+ }
+
Block _finishStatement(List<Statement> statements) {
var params = <TemporaryId>[];
var values = <Expression>[];
@@ -230,7 +243,7 @@ class MetaLet extends Expression {
class _VariableUseCounter extends BaseVisitor {
final counts = <String, int>{};
- visitInterpolatedExpression(InterpolatedExpression node) {
+ @override visitInterpolatedExpression(InterpolatedExpression node) {
int n = counts[node.nameOrPosition];
counts[node.nameOrPosition] = n == null ? 1 : n + 1;
}
@@ -241,10 +254,31 @@ class _IdentFinder extends BaseVisitor {
bool found = false;
_IdentFinder(this.name);
- visitIdentifier(Identifier node) {
+ @override visitIdentifier(Identifier node) {
if (node.name == name) found = true;
}
- visitNode(Node node) {
+ @override visitNode(Node node) {
if (!found) super.visitNode(node);
}
}
+
+class _YieldFinder extends BaseVisitor {
+ bool hasYield = false;
+ bool hasThis = false;
+ bool _nestedFunction = false;
+ @override visitThis(This node) {
+ hasThis = true;
+ }
+ @override visitFunctionExpression(FunctionExpression node) {
+ var savedNested = _nestedFunction;
+ _nestedFunction = true;
+ super.visitFunctionExpression(node);
+ _nestedFunction = savedNested;
+ }
+ @override visitYield(Yield node) {
+ if (!_nestedFunction) hasYield = true;
+ }
+ @override visitNode(Node node) {
+ if (!hasYield) super.visitNode(node);
+ }
+}
« no previous file with comments | « lib/src/codegen/js_codegen.dart ('k') | lib/src/info.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698