| 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 16cfea58c6bd51109c12b82fbe8312d233aaf629..1d067792809db0bda33bfcdfea1dff317ad5e3b4 100644
|
| --- a/pkg/compiler/lib/src/js_model/closure.dart
|
| +++ b/pkg/compiler/lib/src/js_model/closure.dart
|
| @@ -70,11 +70,15 @@ class KernelClosureConversionTask extends ClosureConversionTask<ir.Node> {
|
| final Map<MemberEntity, ScopeModel> _closureModels;
|
|
|
| /// Map of the scoping information that corresponds to a particular entity.
|
| - Map<Entity, ScopeInfo> _scopeMap = <Entity, ScopeInfo>{};
|
| + Map<MemberEntity, ScopeInfo> _scopeMap = <MemberEntity, ScopeInfo>{};
|
| Map<ir.Node, CapturedScope> _capturedScopesMap = <ir.Node, CapturedScope>{};
|
|
|
| - Map<Entity, ClosureRepresentationInfo> _closureRepresentationMap =
|
| - <Entity, ClosureRepresentationInfo>{};
|
| + Map<MemberEntity, ClosureRepresentationInfo> _memberClosureRepresentationMap =
|
| + <MemberEntity, ClosureRepresentationInfo>{};
|
| +
|
| + // The key is either a [ir.FunctionDeclaration] or [ir.FunctionExpression].
|
| + Map<ir.Node, ClosureRepresentationInfo> _localClosureRepresentationMap =
|
| + <ir.Node, ClosureRepresentationInfo>{};
|
|
|
| KernelClosureConversionTask(Measurer measurer, this._elementMap,
|
| this._globalLocalsMap, this._closureModels)
|
| @@ -138,20 +142,20 @@ class KernelClosureConversionTask extends ClosureConversionTask<ir.Node> {
|
|
|
| // We want the original declaration where that function is used to point
|
| // to the correct closure class.
|
| - _closureRepresentationMap[closureClass.callMethod] = closureClass;
|
| - Entity entity;
|
| + _memberClosureRepresentationMap[closureClass.callMethod] = closureClass;
|
| if (node.parent is ir.Member) {
|
| - entity = _elementMap.getMember(node.parent);
|
| + assert(_elementMap.getMember(node.parent) == member);
|
| + _memberClosureRepresentationMap[member] = closureClass;
|
| } else {
|
| - entity = localsMap.getLocalFunction(node.parent);
|
| + assert(node.parent is ir.FunctionExpression ||
|
| + node.parent is ir.FunctionDeclaration);
|
| + _localClosureRepresentationMap[node.parent] = closureClass;
|
| }
|
| - assert(entity != null);
|
| - _closureRepresentationMap[entity] = closureClass;
|
| return closureClass;
|
| }
|
|
|
| @override
|
| - ScopeInfo getScopeInfo(Entity entity) {
|
| + ScopeInfo getScopeInfo(MemberEntity 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].
|
| @@ -160,7 +164,7 @@ class KernelClosureConversionTask extends ClosureConversionTask<ir.Node> {
|
| entity = constructorBody.constructor;
|
| }
|
|
|
| - return _scopeMap[entity] ?? getClosureRepresentationInfo(entity);
|
| + return _scopeMap[entity] ?? getClosureInfoForMember(entity);
|
| }
|
|
|
| // TODO(efortuna): Eventually capturedScopesMap[node] should always
|
| @@ -186,19 +190,34 @@ class KernelClosureConversionTask extends ClosureConversionTask<ir.Node> {
|
| _capturedScopesMap[loopNode] ?? const CapturedLoopScope();
|
|
|
| @override
|
| - ClosureRepresentationInfo getClosureRepresentationInfo(Entity entity) {
|
| - var closure = _closureRepresentationMap[entity];
|
| + ClosureRepresentationInfo getClosureInfoForMember(MemberEntity entity) {
|
| + var closure = _memberClosureRepresentationMap[entity];
|
| assert(
|
| closure != null,
|
| "Corresponding closure class not found for $entity. "
|
| - "Closures found for ${_closureRepresentationMap.keys}");
|
| + "Closures found for ${_memberClosureRepresentationMap.keys}");
|
| + return closure;
|
| + }
|
| +
|
| + @override
|
| + ClosureRepresentationInfo getClosureInfo(ir.Node node) {
|
| + var closure = _localClosureRepresentationMap[node];
|
| + assert(
|
| + closure != null,
|
| + "Corresponding closure class not found for $node. "
|
| + "Closures found for ${_localClosureRepresentationMap.keys}");
|
| return closure;
|
| }
|
|
|
| @override
|
| - ClosureRepresentationInfo getClosureRepresentationInfoForTesting(
|
| - Entity member) {
|
| - return _closureRepresentationMap[member];
|
| + ClosureRepresentationInfo getClosureInfoForMemberTesting(
|
| + MemberEntity entity) {
|
| + return _memberClosureRepresentationMap[entity];
|
| + }
|
| +
|
| + @override
|
| + ClosureRepresentationInfo getClosureInfoForTesting(ir.Node node) {
|
| + return _localClosureRepresentationMap[node];
|
| }
|
| }
|
|
|
| @@ -355,6 +374,14 @@ class KernelClosureClass extends JsScopeInfo
|
| KernelToLocalsMap localsMap)
|
| : closureEntity = closureSourceNode.parent is ir.Member
|
| ? null
|
| + // TODO(johnniwinther,efortuna): This is the only place we call
|
| + // [getLocalFunction]. Therefore the [closureEntity] doesn't need
|
| + // to be derived from the node.
|
| + //
|
| + // What we should do instead: If `closureSourceNode.parent` is
|
| + // an [ir.FunctionDeclaration] we should use the local for its
|
| + // variable. If `closureSourceNode.parent` is an
|
| + // [ir.FunctionExpression], we should create a fresh local.
|
| : localsMap.getLocalFunction(closureSourceNode.parent),
|
| thisLocal =
|
| info.hasThisLocal ? new ThisLocal(localsMap.currentMember) : null,
|
|
|