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

Unified Diff: frog/leg/ssa/closure.dart

Issue 9378040: Allow self-referencing closures. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Address comments. Created 8 years, 10 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 | « frog/leg/ssa/builder.dart ('k') | frog/tests/leg_only/src/Closure4Test.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: frog/leg/ssa/closure.dart
diff --git a/frog/leg/ssa/closure.dart b/frog/leg/ssa/closure.dart
index 6964dddb007d8d2de4de2a3ab20b2378e94cefd4..0e0cf7975d35613329be9adaaf2261b193b82c90 100644
--- a/frog/leg/ssa/closure.dart
+++ b/frog/leg/ssa/closure.dart
@@ -22,9 +22,11 @@ class ClosureScope {
}
class ClosureData {
- // The globalizedClosureElement will be null for methods that are not local
+ // The closure's element before any translation. Will be null for methods.
+ final FunctionElement closureElement;
+ // The closureClassElement will be null for methods that are not local
// closures.
- final ClassElement globalizedClosureElement;
+ final ClassElement closureClassElement;
// The callElement will be null for methods that are not local closures.
final FunctionElement callElement;
// The [thisElement] makes handling 'this' easier by treating it like any
@@ -49,11 +51,16 @@ class ClosureData {
final Set<Element> usedVariablesInTry;
- ClosureData(this.globalizedClosureElement, this.callElement, this.thisElement)
+ ClosureData(this.closureElement,
+ this.closureClassElement,
+ this.callElement,
+ this.thisElement)
: this.freeVariableMapping = new Map<Element, Element>(),
this.capturedFieldMapping = new Map<Element, Element>(),
this.capturingScopes = new Map<Node, ClosureScope>(),
this.usedVariablesInTry = new Set<Element>();
+
+ bool isClosure() => closureElement !== null;
}
Map<Node, ClosureData> _closureDataCache;
@@ -136,7 +143,7 @@ class ClosureTranslator extends AbstractVisitor {
fieldCaptures.add(boxElement);
}
});
- ClassElement closureElement = data.globalizedClosureElement;
+ ClassElement closureElement = data.closureClassElement;
assert(closureElement != null || fieldCaptures.isEmpty());
for (Element boxElement in fieldCaptures) {
Element fieldElement =
@@ -266,7 +273,8 @@ class ClosureTranslator extends AbstractVisitor {
// The nested function's 'this' is the same as the one for the outer
// function. It could be [null] if we are inside a static method.
Element thisElement = closureData.thisElement;
- return new ClosureData(globalizedElement, callElement, thisElement);
+ return new ClosureData(element, globalizedElement,
+ callElement, thisElement);
}
visitFunctionExpression(FunctionExpression node) {
@@ -303,7 +311,7 @@ class ClosureTranslator extends AbstractVisitor {
ElementKind.PARAMETER,
thisEnclosingElement);
}
- closureData = new ClosureData(null, null, thisElement);
+ closureData = new ClosureData(null, null, null, thisElement);
}
scopeVariables = new List<Element>();
@@ -334,18 +342,18 @@ class ClosureTranslator extends AbstractVisitor {
List<Element> freeVariables =
savedClosureData.freeVariableMapping.getKeys();
assert(freeVariables.isEmpty() || savedInsideClosure);
- for (Element element in freeVariables) {
- assert(capturedVariableMapping[element] == null ||
- capturedVariableMapping[element] == element);
- capturedVariableMapping[element] = element;
- useLocal(element);
+ for (Element freeElement in freeVariables) {
+ assert(capturedVariableMapping[freeElement] == null ||
+ capturedVariableMapping[freeElement] == freeElement);
+ capturedVariableMapping[freeElement] = freeElement;
+ useLocal(freeElement);
}
// If we just visited a closure we declare it. This is not always correct
// since some closures are used as expressions and don't introduce any
// name. But in this case the added local is simply not used.
if (savedInsideClosure) {
- declareLocal(elements[node]);
+ declareLocal(element);
}
}
« no previous file with comments | « frog/leg/ssa/builder.dart ('k') | frog/tests/leg_only/src/Closure4Test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698