| 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..218b9a4bea21c5cc7595b370687814ba5a33dd43 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, ClosureScope> _scopesCapturedInClosureMap = | 
| +      <ir.Node, ClosureScope>{}; | 
|  | 
| 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; | 
| +    ClosureScopeBuilder translator = new ClosureScopeBuilder( | 
| +        _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; | 
| +    } | 
|  | 
| -  // TODO(efortuna): Eventually closureScopeMap[node] should always be non-null, | 
| -  // and we should just test that with an assert. | 
| -  ClosureScope _getClosureScope(ir.Node node) => | 
| -      _closureScopeMap[node] ?? const ClosureScope(); | 
| +    return _scopeMap[entity] ?? getClosureRepresentationInfo(entity); | 
| +  } | 
|  | 
| +  // TODO(efortuna): Eventually scopesCapturedInClosureMap[node] should always | 
| +  // be non-null, and we should just test that with an assert. | 
| @override | 
| -  ClosureScope getClosureScope(MemberEntity entity) { | 
| -    return _getClosureScope(_elementMap.getMemberNode(entity)); | 
| -  } | 
| +  ClosureScope getClosureScope(MemberEntity entity) => | 
| +      _scopesCapturedInClosureMap[_elementMap.getMemberNode(entity)] ?? | 
| +      const ClosureScope(); | 
|  | 
| @override | 
| -  // TODO(efortuna): Eventually closureScopeMap[node] should always be non-null, | 
| -  // and we should just test that with an assert. | 
| +  // 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(); | 
| +      _scopesCapturedInClosureMap[loopNode] ?? const LoopClosureScope(); | 
|  | 
| @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(); | 
| } | 
|  |