Index: pkg/compiler/lib/src/js_model/closure_visitors.dart |
diff --git a/pkg/compiler/lib/src/js_model/closure_visitors.dart b/pkg/compiler/lib/src/js_model/closure_visitors.dart |
index 8589ff25e038eb8306e8852d481948b8c1b606ec..b611685189b9700a9c280e22761cf2219ac32381 100644 |
--- a/pkg/compiler/lib/src/js_model/closure_visitors.dart |
+++ b/pkg/compiler/lib/src/js_model/closure_visitors.dart |
@@ -5,32 +5,28 @@ |
import 'package:kernel/ast.dart' as ir; |
import '../closure.dart'; |
-import '../elements/entities.dart'; |
-import '../kernel/element_map.dart'; |
import 'closure.dart'; |
/// This builder walks the code to determine what variables are captured/free at |
/// various points to build CapturedScope that can respond to queries |
/// about how a particular variable is being used at any point in the code. |
class CapturedScopeBuilder extends ir.Visitor { |
- final MemberEntity _currentMember; |
- Local _currentLocalFunction; |
+ ir.TreeNode _currentLocalFunction; |
+ |
+ ClosureModel _model; |
/// A map of each visited call node with the associated information about what |
/// variables are captured/used. Each ir.Node key corresponds to a scope that |
/// was encountered while visiting a closure (initially called through |
/// [translateLazyIntializer] or [translateConstructorOrProcedure]). |
- final Map<ir.Node, CapturedScope> _scopesCapturedInClosureMap; |
- |
- /// Map entities to their corresponding scope information (such as what |
- /// variables are captured/used). |
- final Map<Entity, ScopeInfo> _scopeInfoMap; |
+ Map<ir.Node, KernelCapturedScope> get _scopesCapturedInClosureMap => |
+ _model.capturedScopesMap; |
/// A map of the nodes that we have flagged as necessary to generate closure |
/// classes for in a later stage. We map that node to information ascertained |
/// about variable usage in the surrounding scope. |
- final Map<ir.TreeNode /* ir.Field | ir.FunctionNode */, ScopeInfo> |
- _closuresToGenerate; |
+ Map<ir.TreeNode /* ir.Field | ir.FunctionNode */, KernelScopeInfo> |
+ get _closuresToGenerate => _model.closuresToGenerate; |
/// The local variables that have been declared in the current scope. |
List<ir.VariableDeclaration> _scopeVariables; |
@@ -60,44 +56,38 @@ class CapturedScopeBuilder extends ir.Visitor { |
/// try block. |
bool _inTry = false; |
- /// Lookup the local entity that corresponds to a kernel variable declaration. |
- final KernelToLocalsMap _localsMap; |
- |
/// The current scope we are in. |
KernelScopeInfo _currentScopeInfo; |
- final Entity _thisLocal; |
+ final bool _hasThisLocal; |
- CapturedScopeBuilder(this._currentMember, this._scopesCapturedInClosureMap, |
- this._scopeInfoMap, this._closuresToGenerate, this._localsMap) |
- : this._thisLocal = |
- _currentMember.isInstanceMember || _currentMember.isConstructor |
- ? new ThisLocal(_currentMember) |
- : null; |
+ CapturedScopeBuilder(this._model, {bool hasThisLocal}) |
+ : this._hasThisLocal = hasThisLocal; |
/// Update the [CapturedScope] object corresponding to |
/// this node if any variables are captured. |
void attachCapturedScopeVariables(ir.Node node) { |
- Set<Local> capturedVariablesForScope = new Set<Local>(); |
+ Set<ir.VariableDeclaration> capturedVariablesForScope = |
+ new Set<ir.VariableDeclaration>(); |
for (ir.VariableDeclaration variable in _scopeVariables) { |
// No need to box non-assignable elements. |
if (variable.isFinal || variable.isConst) continue; |
if (!_mutatedVariables.contains(variable)) continue; |
if (_capturedVariables.contains(variable)) { |
- capturedVariablesForScope.add(_localsMap.getLocalVariable(variable)); |
+ capturedVariablesForScope.add(variable); |
} |
} |
if (!capturedVariablesForScope.isEmpty) { |
- assert(_scopeInfoMap[_currentMember] != null); |
+ assert(_model.scopeInfo != null); |
assert(_currentLocalFunction != null); |
- KernelScopeInfo from = _scopeInfoMap[_currentMember]; |
+ KernelScopeInfo from = _model.scopeInfo; |
_scopesCapturedInClosureMap[node] = new KernelCapturedScope( |
capturedVariablesForScope, |
_currentLocalFunction, |
from.localsUsedInTryOrSync, |
from.freeVariables, |
- _thisLocal); |
+ _hasThisLocal); |
} |
} |
@@ -158,14 +148,14 @@ class CapturedScopeBuilder extends ir.Visitor { |
_currentScopeInfo.freeVariables.add(variable); |
} |
if (_inTry) { |
- _currentScopeInfo.localsUsedInTryOrSync |
- .add(_localsMap.getLocalVariable(variable)); |
+ _currentScopeInfo.localsUsedInTryOrSync.add(variable); |
} |
} |
@override |
void visitForStatement(ir.ForStatement node) { |
- List<Local> boxedLoopVariables = <Local>[]; |
+ List<ir.VariableDeclaration> boxedLoopVariables = |
+ <ir.VariableDeclaration>[]; |
enterNewScope(node, () { |
// First visit initialized variables and update steps so we can easily |
// check if a loop variable was captured in one of these subexpressions. |
@@ -194,7 +184,7 @@ class CapturedScopeBuilder extends ir.Visitor { |
// gets cleared when `enterNewScope` returns, so check it here. |
if (_capturedVariables.contains(variable) && |
_mutatedVariables.contains(variable)) { |
- boxedLoopVariables.add(_localsMap.getLocalVariable(variable)); |
+ boxedLoopVariables.add(variable); |
} |
} |
}); |
@@ -206,27 +196,27 @@ class CapturedScopeBuilder extends ir.Visitor { |
scope.context, |
scope.localsUsedInTryOrSync, |
scope.freeVariables, |
- scope.thisLocal); |
+ scope.hasThisLocal); |
} |
void visitInvokable(ir.TreeNode node) { |
bool oldIsInsideClosure = _isInsideClosure; |
ir.Node oldExecutableContext = _executableContext; |
KernelScopeInfo oldScopeInfo = _currentScopeInfo; |
- Local oldLocalFunction = _currentLocalFunction; |
+ ir.TreeNode oldLocalFunction = _currentLocalFunction; |
// _outermostNode is only null the first time we enter the body of the |
// field, constructor, or method that is being analyzed. |
_isInsideClosure = _outermostNode != null; |
_executableContext = node; |
- _currentScopeInfo = new KernelScopeInfo(_thisLocal); |
+ _currentScopeInfo = new KernelScopeInfo(_hasThisLocal); |
if (_isInsideClosure) { |
_closuresToGenerate[node] = _currentScopeInfo; |
- _currentLocalFunction = _localsMap.getLocalFunction(node.parent); |
+ _currentLocalFunction = node.parent; |
} else { |
_outermostNode = node; |
- _scopeInfoMap[_currentMember] = _currentScopeInfo; |
+ _model.scopeInfo = _currentScopeInfo; |
} |
enterNewScope(node, () { |