| Index: pkg/compiler/lib/src/js_model/closure.dart
|
| diff --git a/pkg/compiler/lib/src/js_model/closure.dart b/pkg/compiler/lib/src/js_model/closure.dart
|
| index 04611ad1e686c9f951d81e5691bb07bfaafb95ca..9110588b28b44fb73d5abb199b4ec4f8ef241b23 100644
|
| --- a/pkg/compiler/lib/src/js_model/closure.dart
|
| +++ b/pkg/compiler/lib/src/js_model/closure.dart
|
| @@ -31,7 +31,11 @@ import 'locals.dart';
|
| class KernelClosureConversionTask extends ClosureConversionTask<ir.Node> {
|
| final KernelToElementMapForBuilding _elementMap;
|
| final GlobalLocalsMap _globalLocalsMap;
|
| - Map<ir.Node, ClosureScope> _closureScopeMap = <ir.Node, ClosureScope>{};
|
| +
|
| + /// Map of the scoping information that corresponds to a particular entity.
|
| + Map<Entity, ScopeInfo> _scopeMap = <Entity, ScopeInfo>{};
|
| + Map<ir.Node, ScopeInClosure> _scopesCapturedInClosureMap =
|
| + <ir.Node, ScopeInClosure>{};
|
|
|
| Map<Entity, ClosureRepresentationInfo> _closureRepresentationMap =
|
| <Entity, ClosureRepresentationInfo>{};
|
| @@ -81,10 +85,16 @@ class KernelClosureConversionTask extends ClosureConversionTask<ir.Node> {
|
| MemberEntity entity,
|
| Map<ir.TreeNode, ScopeInfo> closuresToGenerate,
|
| ClosedWorldRefiner closedWorldRefiner) {
|
| + if (_scopeMap.keys.contains(entity)) return;
|
| ir.Node node = _elementMap.getMemberNode(entity);
|
| - if (_closureScopeMap.keys.contains(node)) return;
|
| - ClosureScopeBuilder translator = new ClosureScopeBuilder(_closureScopeMap,
|
| - closuresToGenerate, _globalLocalsMap.getLocalsMap(entity), _elementMap);
|
| + if (_scopesCapturedInClosureMap.keys.contains(node)) return;
|
| + ScopeInClosureBuilder translator = new ScopeInClosureBuilder(
|
| + _scopesCapturedInClosureMap,
|
| + _scopeMap,
|
| + entity,
|
| + closuresToGenerate,
|
| + _globalLocalsMap.getLocalsMap(entity),
|
| + _elementMap);
|
| if (entity.isField) {
|
| if (node is ir.Field && node.initializer != null) {
|
| translator.translateLazyInitializer(node);
|
| @@ -129,36 +139,34 @@ class KernelClosureConversionTask extends ClosureConversionTask<ir.Node> {
|
|
|
| @override
|
| ScopeInfo getScopeInfo(Entity entity) {
|
| - return getClosureRepresentationInfo(entity);
|
| + // TODO(johnniwinther): Remove this check when constructor bodies a created
|
| + // eagerly with the J-model; a constructor body should have it's own
|
| + // [ClosureRepresentationInfo].
|
| + if (entity is ConstructorBodyEntity) {
|
| + ConstructorBodyEntity constructorBody = entity;
|
| + entity = constructorBody.constructor;
|
| + }
|
| +
|
| + return _scopeMap[entity] ?? getClosureRepresentationInfo(entity);
|
| }
|
|
|
| - // TODO(efortuna): Eventually closureScopeMap[node] should always be non-null,
|
| + // TODO(efortuna): Eventually scopesCapturedInClosureMap[node] should always be non-null,
|
| // and we should just test that with an assert.
|
| - ClosureScope _getClosureScope(ir.Node node) =>
|
| - _closureScopeMap[node] ?? const ClosureScope();
|
| -
|
| @override
|
| - ClosureScope getClosureScope(MemberEntity entity) {
|
| - return _getClosureScope(_elementMap.getMemberNode(entity));
|
| - }
|
| + ScopeInClosure getScopeInClosure(MemberEntity entity) =>
|
| + _scopesCapturedInClosureMap[_elementMap.getMemberNode(entity)] ??
|
| + const ScopeInClosure();
|
|
|
| @override
|
| - // TODO(efortuna): Eventually closureScopeMap[node] should always be non-null,
|
| + // TODO(efortuna): Eventually scopesCapturedInClosureMap[node] should always be non-null,
|
| // and we should just test that with an assert.
|
| - LoopClosureScope getLoopClosureScope(ir.Node loopNode) =>
|
| - _closureScopeMap[loopNode] ?? const LoopClosureScope();
|
| + LoopScopeInClosure getLoopScopeInClosure(ir.Node loopNode) =>
|
| + _scopesCapturedInClosureMap[loopNode] ?? const LoopScopeInClosure();
|
|
|
| @override
|
| // TODO(efortuna): Eventually closureRepresentationMap[node] should always be
|
| // non-null, and we should just test that with an assert.
|
| ClosureRepresentationInfo getClosureRepresentationInfo(Entity entity) {
|
| - // TODO(johnniwinther): Remove this check when constructor bodies a created
|
| - // eagerly with the J-model; a constructor body should have it's own
|
| - // [ClosureRepresentationInfo].
|
| - if (entity is ConstructorBodyEntity) {
|
| - ConstructorBodyEntity constructorBody = entity;
|
| - entity = constructorBody.constructor;
|
| - }
|
| return _closureRepresentationMap[entity] ??
|
| const ClosureRepresentationInfo();
|
| }
|
| @@ -204,20 +212,20 @@ class KernelScopeInfo extends ScopeInfo {
|
| bool isBoxed(Local variable) => boxedVariables.contains(variable);
|
| }
|
|
|
| -class KernelClosureScope extends KernelScopeInfo implements ClosureScope {
|
| +class KernelScopeInClosure extends KernelScopeInfo implements ScopeInClosure {
|
| final Local context;
|
|
|
| - KernelClosureScope(Set<Local> boxedVariables, this.context, Local thisLocal)
|
| + KernelScopeInClosure(Set<Local> boxedVariables, this.context, Local thisLocal)
|
| : super.withBoxedVariables(boxedVariables, thisLocal);
|
|
|
| bool get requiresContextBox => boxedVariables.isNotEmpty;
|
| }
|
|
|
| -class KernelLoopClosureScope extends KernelClosureScope
|
| - implements LoopClosureScope {
|
| +class KernelLoopScopeInClosure extends KernelScopeInClosure
|
| + implements LoopScopeInClosure {
|
| final List<Local> boxedLoopVariables;
|
|
|
| - KernelLoopClosureScope(Set<Local> boxedVariables, this.boxedLoopVariables,
|
| + KernelLoopScopeInClosure(Set<Local> boxedVariables, this.boxedLoopVariables,
|
| Local context, Local thisLocal)
|
| : super(boxedVariables, context, thisLocal);
|
|
|
|
|