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

Unified Diff: pkg/compiler/lib/src/closure.dart

Issue 2915523003: Create new interface instead of ClosureClassMap for variable usage information that is not Element-…
Patch Set: . Created 3 years, 7 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 | « no previous file | pkg/compiler/lib/src/dump_info.dart » ('j') | pkg/compiler/lib/src/dump_info.dart » ('J')
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: pkg/compiler/lib/src/closure.dart
diff --git a/pkg/compiler/lib/src/closure.dart b/pkg/compiler/lib/src/closure.dart
index f7a0af62c9a1992e5d94f3c2630e72c066970a9e..9075e92c861527f3cb874b52f1dbe167a76bfe1f 100644
--- a/pkg/compiler/lib/src/closure.dart
+++ b/pkg/compiler/lib/src/closure.dart
@@ -23,14 +23,47 @@ import 'tree/tree.dart';
import 'util/util.dart';
import 'world.dart' show ClosedWorldRefiner;
-abstract class ClosureClassMaps {
- ClosureClassMap getMemberMap(MemberEntity member);
- ClosureClassMap getLocalFunctionMap(Local localFunction);
+/// Where T is ir.Node or Node.
+// TODO(efortuna): Rename this class.
+abstract class ClosureClassMaps<T> {
Johnni Winther 2017/05/31 12:39:51 I'd prefer if these new methods (eventually) are o
+ /// Currently, closures are rewritten in the form of classes that
Siggi Cherem (dart-lang) 2017/05/31 20:44:38 Small suggestion: to make the docs a bit more comp
+ /// have fields to control the redirection and editing of variables that are
+ /// "captured" inside a scope (declared in an outer scope but used in an
+ /// inside scope).
+ ClassEntity getClosureClassEntity(Local member);
Siggi Cherem (dart-lang) 2017/05/31 20:44:39 minor naming ideas: these are totally optional, so
+
+ // TODO(efortuna): This should probably be renamed to something like
+ // forEachCapturedVariable or something that's less implementation specific.
Siggi Cherem (dart-lang) 2017/05/31 20:44:39 +1 I like that, also possible `forEachCapturedVari
+ void forEachClosureClassFieldEntity(Local entity, void f(FieldEntity field));
+
+ /// Closures are rewritten as classes with fields representing the local
Siggi Cherem (dart-lang) 2017/05/31 20:44:39 Another though - we can explore moving the docs up
+ /// variables that the closure has "captured. Return the actual local
Johnni Winther 2017/05/31 12:39:51 "captured -> captured
+ /// variable that a particular closure field is emulating.
+ Local getLocalVarForClosureField(Local member, FieldEntity field);
+
+ /// The method representing calling the closure to execute, provided the
Johnni Winther 2017/05/31 12:39:51 Maybe rephrase as: The function that implements t
+ /// original local entity.
+ FunctionEntity getCallEntity(Local member);
+
+ /// Accessor to the local environment in which a particular closure node is
+ /// executed. This will encapsulate the value of any variables that have been
+ /// scoped into this context from outside.
Siggi Cherem (dart-lang) 2017/05/31 20:44:39 is "scoped" the same as captured here? or somethin
+ Local getExecutableContext(T node);
Siggi Cherem (dart-lang) 2017/05/31 20:44:38 Open question: I wonder if we should introduce thi
+
+ // TODO(efortuna): Finish removing this method by exposing remining info in
Siggi Cherem (dart-lang) 2017/05/31 20:44:39 remining => remaining
+ // this interface.
+ ClosureClassMap getMemberMap(MemberElement member);
+
+ /// Look up information about what variables are have been mutated that are
Johnni Winther 2017/05/31 12:39:51 are have ... inside the -> have been mutated insid
+ /// used inside the scope of [node].
+ CapturedVariableInfo getCapturedVariableInfo(T node);
}
-class ClosureTask extends CompilerTask implements ClosureClassMaps {
+class ClosureTask extends CompilerTask implements ClosureClassMaps<Node> {
Map<Element, ClosureClassMap> _closureMappingCache =
<Element, ClosureClassMap>{};
+ Map<Node, Local> _executableContextCache = <Node, Local>{};
+ Map<Node, ClosureScope> _closureScopeCache = <Node, ClosureScope>{};
Compiler compiler;
ClosureTask(Compiler compiler)
: compiler = compiler,
@@ -40,14 +73,52 @@ class ClosureTask extends CompilerTask implements ClosureClassMaps {
DiagnosticReporter get reporter => compiler.reporter;
+ CapturedVariableInfo getCapturedVariableInfo(Node node) {
+ ClosureScope scopeData = _closureScopeCache[node];
+ if (scopeData == null) return new CapturedVariableInfo();
Siggi Cherem (dart-lang) 2017/06/01 15:40:30 consider adding a const constructor to CapturedVar
+ return scopeData;
+ }
+
ClosureClassMap getMemberMap(MemberElement member) {
return getClosureToClassMapping(member.resolvedAst);
}
- ClosureClassMap getLocalFunctionMap(LocalFunctionElement localFunction) {
+ ClosureClassMap _getLocalFunctionMap(LocalFunctionElement localFunction) {
return getClosureToClassMapping(localFunction.resolvedAst);
}
+ void forEachClosureClassFieldEntity(
+ LocalFunctionElement entity, void f(FieldEntity field)) {
+ ClosureClassElement classEntity = getClosureClassEntity(entity);
+ classEntity.closureFields.forEach(f);
+ }
+
+ Local getExecutableContext(Node node) {
+ return _executableContextCache[node];
+ }
+
+ Local getLocalVarForClosureField(
+ LocalFunctionElement member, FieldEntity field) {
+ ClosureClassMap memberMap = _getLocalFunctionMap(member);
+ assert(memberMap != null);
+ assert(memberMap.closureClassElement != null);
+ return memberMap.getLocalVariableForClosureField(field);
+ }
+
+ ClassEntity getClosureClassEntity(LocalFunctionElement member) {
+ ClosureClassMap memberMap = _getLocalFunctionMap(member);
+ assert(memberMap != null);
+ assert(memberMap.closureClassElement != null);
+ return memberMap.closureClassElement;
+ }
+
+ FunctionEntity getCallEntity(LocalFunctionElement member) {
+ ClosureClassMap memberMap = _getLocalFunctionMap(member);
+ assert(memberMap != null);
+ assert(memberMap.closureClassElement != null);
+ return memberMap.callElement;
+ }
+
/// Returns the [ClosureClassMap] computed for [resolvedAst].
ClosureClassMap getClosureToClassMapping(ResolvedAst resolvedAst) {
return measure(() {
@@ -94,7 +165,12 @@ class ClosureTask extends CompilerTask implements ClosureClassMaps {
TreeElements elements = resolvedAst.elements;
ClosureTranslator translator = new ClosureTranslator(
- compiler, closedWorldRefiner, elements, _closureMappingCache);
+ compiler,
+ closedWorldRefiner,
+ elements,
+ _closureMappingCache,
+ _executableContextCache,
+ _closureScopeCache);
// The translator will store the computed closure-mappings inside the
// cache. One for given node and one for each nested closure.
@@ -411,9 +487,21 @@ class SynthesizedCallMethodElementX extends BaseFunctionElementX
}
}
+/// Interface external classes can use to query information about what variables
+/// are mutated inside a scope.
+class CapturedVariableInfo {
+ bool hasCapturedVariables() => false;
Siggi Cherem (dart-lang) 2017/05/31 20:44:39 nit: turn these two into getters: bool get hasCap
+ bool hasBoxedLoopVariables() => false;
+
+ /// True if the specified variable has been mutated inside the scope of this
+ /// closure.
+ bool isCaptured(Local variable) => false;
+ void forEachCapturedVariable(f(Entity from, Entity to)) {}
+}
+
// The box-element for a scope, and the captured variables that need to be
// stored in the box.
-class ClosureScope {
+class ClosureScope implements CapturedVariableInfo {
final BoxLocal boxElement;
final Map<Local, BoxFieldElement> capturedVariables;
@@ -424,9 +512,11 @@ class ClosureScope {
ClosureScope(this.boxElement, this.capturedVariables);
+ bool hasCapturedVariables() => capturedVariables.keys.isNotEmpty;
+
bool hasBoxedLoopVariables() => !boxedLoopVariables.isEmpty;
- bool isCapturedVariable(VariableElement variable) {
+ bool isCaptured(VariableElement variable) {
Johnni Winther 2017/05/31 12:39:51 [VariableElement] -> [LocalVariableElement] to mak
return capturedVariables.containsKey(variable);
}
@@ -591,8 +681,16 @@ class ClosureTranslator extends Visitor {
bool insideClosure = false;
- ClosureTranslator(this.compiler, this.closedWorldRefiner, this.elements,
- this.closureMappingCache);
+ Map<Node, Local> executableContextCache;
+ Map<Node, ClosureScopeCache> closureScopeCache;
+
+ ClosureTranslator(
+ this.compiler,
+ this.closedWorldRefiner,
+ this.elements,
+ this.closureMappingCache,
+ this.executableContextCache,
+ this.closureScopeCache);
DiagnosticReporter get reporter => compiler.reporter;
@@ -976,6 +1074,10 @@ class ClosureTranslator extends Visitor {
if (!scopeMapping.isEmpty) {
ClosureScope scope = new ClosureScope(box, scopeMapping);
closureData.capturingScopes[node] = scope;
+ assert(executableContextCache[node] == null);
+ executableContextCache[node] = box;
+ assert(closureScopeCache[node] == null);
+ closureScopeCache[node] = scope;
}
}
« no previous file with comments | « no previous file | pkg/compiler/lib/src/dump_info.dart » ('j') | pkg/compiler/lib/src/dump_info.dart » ('J')

Powered by Google App Engine
This is Rietveld 408576698