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 58fa5c777e5b33559dbec10642bceec1a056b490..bd8cafbec349605493088faf96ba71db12b6a679 100644 |
--- a/pkg/compiler/lib/src/js_model/closure.dart |
+++ b/pkg/compiler/lib/src/js_model/closure.dart |
@@ -5,6 +5,7 @@ |
import 'package:kernel/ast.dart' as ir; |
import '../closure.dart'; |
+import '../common.dart'; |
import '../common/tasks.dart'; |
import '../elements/entities.dart'; |
import '../kernel/element_map.dart'; |
@@ -66,7 +67,10 @@ class KernelClosureConversionTask extends ClosureConversionTask<ir.Node> { |
} |
if (entity.isAbstract) return; |
if (entity.isField && !entity.isInstanceMember) { |
- ir.Field field = _elementMap.getMemberNode(entity); |
+ MemberDefinition definition = _elementMap.getMemberDefinition(entity); |
+ assert(definition.kind == MemberKind.regular, |
+ failedAt(entity, "Unexpected member definition $definition")); |
+ ir.Field field = definition.node; |
// Skip top-level/static fields without an initializer. |
if (field.initializer == null) return; |
} |
@@ -86,7 +90,15 @@ class KernelClosureConversionTask extends ClosureConversionTask<ir.Node> { |
Map<ir.TreeNode, ScopeInfo> closuresToGenerate, |
ClosedWorldRefiner closedWorldRefiner) { |
if (_scopeMap.keys.contains(entity)) return; |
- ir.Node node = _elementMap.getMemberNode(entity); |
+ MemberDefinition definition = _elementMap.getMemberDefinition(entity); |
+ switch (definition.kind) { |
+ case MemberKind.regular: |
+ case MemberKind.constructor: |
+ break; |
+ default: |
+ failedAt(entity, "Unexpected member definition $definition"); |
+ } |
+ ir.Node node = definition.node; |
if (_scopesCapturedInClosureMap.keys.contains(node)) return; |
CapturedScopeBuilder translator = new CapturedScopeBuilder( |
_scopesCapturedInClosureMap, |
@@ -114,7 +126,7 @@ class KernelClosureConversionTask extends ClosureConversionTask<ir.Node> { |
ClosedWorldRefiner closedWorldRefiner) { |
Entity entity; |
KernelClosureClass closureClass = |
- new KernelClosureClass.fromScopeInfo(info); |
+ new KernelClosureClass.fromScopeInfo(info, node.location); |
if (node is ir.FunctionNode) { |
// We want the original declaration where that function is used to point |
// to the correct closure class. |
@@ -153,9 +165,18 @@ class KernelClosureConversionTask extends ClosureConversionTask<ir.Node> { |
// TODO(efortuna): Eventually scopesCapturedInClosureMap[node] should always |
// be non-null, and we should just test that with an assert. |
@override |
- CapturedScope getCapturedScope(MemberEntity entity) => |
- _scopesCapturedInClosureMap[_elementMap.getMemberNode(entity)] ?? |
- const CapturedScope(); |
+ CapturedScope getCapturedScope(MemberEntity entity) { |
+ MemberDefinition definition = _elementMap.getMemberDefinition(entity); |
+ switch (definition.kind) { |
+ case MemberKind.regular: |
+ case MemberKind.constructor: |
+ case MemberKind.constructorBody: |
+ return _scopesCapturedInClosureMap[definition.node] ?? |
+ const CapturedScope(); |
+ default: |
+ throw failedAt(entity, "Unexpected member definition $definition"); |
+ } |
+ } |
@override |
// TODO(efortuna): Eventually scopesCapturedInClosureMap[node] should always |
@@ -235,6 +256,8 @@ class KernelCapturedLoopScope extends KernelCapturedScope |
// TODO(johnniwinther): Add unittest for the computed [ClosureClass]. |
class KernelClosureClass extends KernelScopeInfo |
implements ClosureRepresentationInfo, JClass { |
+ final ir.Location location; |
+ |
// TODO(efortuna): Generate unique name for each closure class. |
final String name = 'ClosureClass'; |
@@ -244,7 +267,7 @@ class KernelClosureClass extends KernelScopeInfo |
final Map<Local, JField> localToFieldMap = new Map<Local, JField>(); |
- KernelClosureClass.fromScopeInfo(KernelScopeInfo info) |
+ KernelClosureClass.fromScopeInfo(KernelScopeInfo info, this.location) |
: super.from(info.thisLocal, info); |
// TODO(efortuna): Implement. |
@@ -288,3 +311,18 @@ class KernelClosureClass extends KernelScopeInfo |
String toString() => '${jsElementPrefix}class($name)'; |
} |
+ |
+class ClosureClassDefinition implements ClassDefinition { |
+ final ClassEntity cls; |
+ final ir.Location location; |
+ |
+ ClosureClassDefinition(this.cls, this.location); |
+ |
+ ClassKind get kind => ClassKind.closure; |
+ |
+ ir.Node get node => |
+ throw new UnsupportedError('ClosureClassDefinition.node for $cls'); |
+ |
+ String toString() => |
+ 'ClosureClassDefinition(kind:$kind,cls:$cls,location:$location)'; |
+} |