Index: pkg/compiler/lib/src/kernel/element_map_impl.dart |
diff --git a/pkg/compiler/lib/src/kernel/element_map_impl.dart b/pkg/compiler/lib/src/kernel/element_map_impl.dart |
index 018651b242f13088ca6aae48c600d5bdb580e9b3..97de7bf767f2a3397563f5d1613ebc38aad10e3f 100644 |
--- a/pkg/compiler/lib/src/kernel/element_map_impl.dart |
+++ b/pkg/compiler/lib/src/kernel/element_map_impl.dart |
@@ -663,38 +663,6 @@ abstract class ElementCreatorMixin { |
}); |
} |
- // TODO(johnniwinther,efortuna): Create the class index and data together with |
- // the [KernelClosureClass]. |
- void addClosureClass(KernelClosureClass cls, InterfaceType supertype) { |
- cls.classIndex = _classEnvs.length; |
- _classEnvs.add(new ClassEnv.closureClass()); |
- _classList.add(cls); |
- |
- // Create a classData and set up the interfaces and subclass |
- // relationships that _ensureSupertypes and _ensureThisAndRawType are doing |
- var closureData = |
- new ClassData(null, new ClosureClassDefinition(cls, cls.location)); |
- closureData |
- ..isMixinApplication = false |
- ..thisType = |
- closureData.rawType = new InterfaceType(cls, const/*<DartType>*/ []) |
- ..supertype = supertype |
- ..interfaces = const <InterfaceType>[]; |
- var setBuilder = |
- new _KernelOrderedTypeSetBuilder((this as KernelToElementMapBase), cls); |
- _classData.add(closureData); |
- closureData.orderedTypeSet = setBuilder.createOrderedTypeSet( |
- closureData.supertype, const Link<InterfaceType>()); |
- |
- cls.forEachCapturedVariable((Local local, JField field) { |
- field.setClosureMemberIndex = _memberData.length; |
- // TODO(efortuna): Uncomment this line after Johnni's added in his CL |
- // about Class/MemberDefinition. |
- //_memberData.add(field); |
- }); |
- // TODO(efortuna): Does getMetadata get called in ClassData for this object? |
- } |
- |
ClassEntity _getClass(ir.Class node, [ClassEnv classEnv]) { |
return _classMap.putIfAbsent(node, () { |
KLibrary library = _getLibrary(node.enclosingLibrary); |
@@ -1999,6 +1967,89 @@ class JsKernelToElementMap extends KernelToElementMapBase |
}); |
} |
+ KernelClosureClass constructClosureClass( |
+ String name, |
+ JLibrary enclosingLibrary, |
+ KernelScopeInfo info, |
+ ir.Location location, |
+ KernelToLocalsMap localsMap, |
+ InterfaceType supertype) { |
+ KernelClosureClass cls = new KernelClosureClass.fromScopeInfo( |
+ name, _classEnvs.length, enclosingLibrary, info, location, localsMap); |
+ _classList.add(cls); |
+ _classEnvs.add(new ClassEnv.closureClass()); |
+ |
+ // Create a classData and set up the interfaces and subclass |
+ // relationships that _ensureSupertypes and _ensureThisAndRawType are doing |
+ var closureData = |
+ new ClassData(null, new ClosureClassDefinition(cls, cls.location)); |
+ closureData |
+ ..isMixinApplication = false |
+ ..thisType = |
+ closureData.rawType = new InterfaceType(cls, const/*<DartType>*/ []) |
+ ..supertype = supertype |
+ ..interfaces = const <InterfaceType>[]; |
+ var setBuilder = new _KernelOrderedTypeSetBuilder(this, cls); |
+ _classData.add(closureData); |
+ closureData.orderedTypeSet = setBuilder.createOrderedTypeSet( |
+ closureData.supertype, const Link<InterfaceType>()); |
+ |
+ for (ir.VariableDeclaration variable in info.freeVariables) { |
+ // Make a corresponding field entity in this closure class for every |
+ // single freeVariable in the KernelScopeInfo.freeVariable. |
+ int i = 0; |
sra1
2017/07/27 19:41:16
should this be outside the loop?
Emily Fortuna
2017/07/28 20:10:04
doh. yes
|
+ _constructClosureFields(cls, variable, i, localsMap); |
+ i++; |
+ } |
+ |
+ // TODO(efortuna): Does getMetadata get called in ClassData for this object? |
+ return cls; |
+ } |
+ |
+ _constructClosureFields( |
+ KernelClosureClass cls, |
+ ir.VariableDeclaration variable, |
+ int fieldNumber, |
+ KernelToLocalsMap localsMap) { |
+ // NOTE: This construction order may be slightly different than the |
+ // old Element version. The old version did all the boxed items and then |
+ // all the others. |
+ Local capturedLocal = localsMap.getLocalVariable(variable); |
+ if (cls.isBoxed(capturedLocal)) { |
+ // TODO(efortuna): Coming soon. |
+ } else { |
+ cls.localToFieldMap[capturedLocal] = new ClosureField( |
+ _getClosureVariableName(capturedLocal.name, fieldNumber), |
+ _memberData.length, |
+ cls, |
+ variable.isConst, |
+ variable.isFinal || variable.isConst); |
+ // PROBLEM: the type of ir.Node that we want to pass in |
Emily Fortuna
2017/07/27 16:40:02
Johnni, please take a look at this issue. What do
Johnni Winther
2017/07/28 15:18:40
You need to add the field to `_memberList` as well
Emily Fortuna
2017/07/28 20:10:04
ahhh got it. Yeah, that branch shouldn't be hit no
|
+ // ClosureMemberDefinition is a *field*, not a VariableDeclaration, so |
+ // that in the build() method of builder_kernel.dart we can generate the |
+ // correct code. But that requires inventing a fake ir.Field..... |
+ // TODO(efortuna): Talk to johnniwinther. |
+ //_memberData.add(new MemberData(null, new ClosureMemberDefinition( |
+ // cls.localToFieldMap[capturedLocal], variable.location, |
+ // MemberKind.closureField, variable))); |
+ } |
+ } |
+ |
+ /// Generate a unique name for the [id]th closure field, with proposed name |
+ /// [name]. |
+ /// |
+ /// The result is used as the name of [ClosureFieldElement]s, and must |
+ /// therefore be unique to avoid breaking an invariant in the element model |
+ /// (classes cannot declare multiple fields with the same name). |
+ /// |
+ /// Also, the names should be distinct from real field names to prevent |
+ /// clashes with selectors for those fields. |
+ /// |
+ /// These names are not used in generated code, just as element name. |
+ String _getClosureVariableName(String name, int id) { |
+ return "_captured_${name}_$id"; |
+ } |
+ |
String getDeferredUri(ir.LibraryDependency node) { |
throw new UnimplementedError('JsKernelToElementMap.getDeferredUri'); |
} |