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 ce3e0a511430a76d55c2782c835149c203c8e6b3..deac111af11d8b401bf6715f6d20704032869028 100644 |
--- a/pkg/compiler/lib/src/kernel/element_map_impl.dart |
+++ b/pkg/compiler/lib/src/kernel/element_map_impl.dart |
@@ -1959,6 +1959,7 @@ class JsKernelToElementMap extends KernelToElementMapBase |
implements |
KernelToWorldBuilder { |
NativeBasicData nativeBasicData; |
+ int fieldNumber = 0; |
JsKernelToElementMap(DiagnosticReporter reporter, Environment environment, |
KernelToElementMapForImpactImpl _elementMap) |
@@ -2156,43 +2157,147 @@ class JsKernelToElementMap extends KernelToElementMapBase |
env.forEachConstructorBody(f); |
} |
+ JRecord _constructBoxedField( |
+ ir.VariableDeclaration variable, |
+ BoxLocal boxLocal, |
+ JClass container, |
+ Map<String, MemberEntity> memberMap, |
+ KernelToLocalsMap localsMap) { |
+ Local local = localsMap.getLocalVariable(variable); |
+ var boxedField = new JRecord( |
+ _getClosureVariableName(local.name, fieldNumber), |
+ _memberData.length, |
+ boxLocal, |
+ container, |
+ variable.isConst, |
+ variable.isFinal || variable.isConst); |
+ _memberList.add(boxedField); |
+ _memberData.add(new ClosureFieldData(new ClosureMemberDefinition( |
+ boxedField, |
+ computeSourceSpanFromTreeNode(variable), |
+ MemberKind.closureField, |
+ variable))); |
+ memberMap[boxedField.name] = boxedField; |
+ |
+ //JsScopeInfo scopeInfo = getScopeInfo(local.memberContext); |
+ //scopeInfo.boxedVariables[local] = boxedField; |
+ return boxedField; |
+ } |
+ |
+ /// Make a container controlling access to records, that is, variables that |
+ /// are accessed in different scopes. This function creates the container as |
+ /// and returns a map of locals to the corresponding records created. |
+ Map<Local, JRecord> makeRecordContainer( |
+ KernelScopeInfo info, MemberEntity member, KernelToLocalsMap localsMap) { |
+ Map<Local, JRecord> boxedFields = {}; |
+ fieldNumber = 0; |
+ if (info.boxedVariables.isNotEmpty) { |
+ Map<Local, JRecord> boxedVariables = new Map<Local, JRecord>(); |
+ NodeBox box = info.capturedVariablesAccessor; |
+ BoxLocal boxLocal = new BoxLocal( |
+ box.name, getMember(box.executableContext.parent), member); |
+ |
+ /// |
+ var container = |
+ new JRecordContainer(member.library, _classEnvs.length, box.name); |
+ _classList.add(container); |
+ Map<String, MemberEntity> memberMap = <String, MemberEntity>{}; |
+ _classEnvs.add(new RecordContainerEnv(memberMap)); |
+ |
+ var containerData = new ClassData( |
+ null, |
+ new ClosureClassDefinition(container, |
+ computeSourceSpanFromTreeNode(getMemberDefinition(member).node))); |
+ containerData |
+ ..isMixinApplication = false |
+ ..thisType = new InterfaceType(container, const <DartType>[]) |
+ ..supertype = commonElements.objectType |
+ ..interfaces = const <InterfaceType>[]; |
+ var setBuilder = new _KernelOrderedTypeSetBuilder(this, container); |
+ _classData.add(containerData); |
+ containerData.orderedTypeSet = setBuilder.createOrderedTypeSet( |
+ containerData.supertype, const Link<InterfaceType>()); |
+ |
+ /// |
+ |
+ for (ir.VariableDeclaration variable in info.boxedVariables) { |
+ boxedFields[localsMap.getLocalVariable(variable)] = |
+ _constructBoxedField( |
+ variable, boxLocal, container, memberMap, localsMap); |
+ fieldNumber++; |
+ } |
+ } |
+ return boxedFields; |
+ } |
+ |
+ Map<Local, JRecord> _makeBoxAndFields( |
+ KernelScopeInfo info, |
+ MemberEntity member, |
+ JClass classEntity, |
+ Map<String, MemberEntity> memberMap, |
+ KernelToLocalsMap localsMap) { |
+ Map<Local, JRecord> boxedFields = {}; |
+ fieldNumber = 0; |
+ if (info.boxedVariables.isNotEmpty) { |
+ Map<Local, JRecord> boxedVariables = new Map<Local, JRecord>(); |
+ NodeBox box = info.capturedVariablesAccessor; |
+ BoxLocal boxLocal = new BoxLocal( |
+ box.name, localsMap.getLocalVariable(box.executableContext), member); |
+ |
+ for (ir.VariableDeclaration variable in info.boxedVariables) { |
+ Local local = localsMap.getLocalVariable(variable); |
+ boxedFields[local] = _constructBoxedField( |
+ variable, boxLocal, classEntity, memberMap, localsMap); |
+ fieldNumber++; |
+ } |
+ } |
+ return boxedFields; |
+ } |
+ |
KernelClosureClass constructClosureClass( |
MemberEntity member, |
ir.FunctionNode node, |
JLibrary enclosingLibrary, |
+ Set<JsCapturedScope> capturedScopes, |
KernelScopeInfo info, |
ir.Location location, |
KernelToLocalsMap localsMap, |
InterfaceType supertype) { |
String name = _computeClosureName(node); |
- KernelClosureClass cls = new KernelClosureClass.fromScopeInfo( |
- node, name, _classEnvs.length, enclosingLibrary, info, localsMap); |
- _classList.add(cls); |
+ JClass clsEntity = |
+ new JClosureClass(localsMap, enclosingLibrary, _classEnvs.length, name); |
+ _classList.add(clsEntity); |
Map<String, MemberEntity> memberMap = <String, MemberEntity>{}; |
_classEnvs.add(new ClosureClassEnv(memberMap)); |
// 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, computeSourceSpanFromTreeNode(node))); |
+ var closureData = new ClassData( |
+ null, |
+ new ClosureClassDefinition( |
+ clsEntity, computeSourceSpanFromTreeNode(node))); |
closureData |
..isMixinApplication = false |
..thisType = |
- closureData.rawType = new InterfaceType(cls, const <DartType>[]) |
+ closureData.rawType = new InterfaceType(clsEntity, const <DartType>[]) |
..supertype = supertype |
..interfaces = const <InterfaceType>[]; |
- var setBuilder = new _KernelOrderedTypeSetBuilder(this, cls); |
+ var setBuilder = new _KernelOrderedTypeSetBuilder(this, clsEntity); |
_classData.add(closureData); |
closureData.orderedTypeSet = setBuilder.createOrderedTypeSet( |
closureData.supertype, const Link<InterfaceType>()); |
- int i = 0; |
+ var boxedFields = |
+ _makeBoxAndFields(info, member, clsEntity, memberMap, localsMap); |
+ KernelClosureClass cls = new KernelClosureClass.fromScopeInfo( |
+ clsEntity, node, boxedFields, capturedScopes, info, localsMap); |
+ |
for (ir.VariableDeclaration variable in info.freeVariables) { |
// Make a corresponding field entity in this closure class for every |
// single freeVariable in the KernelScopeInfo.freeVariable. |
- _constructClosureFields(member, cls, memberMap, variable, i, |
+ _constructClosureField(member, cls, memberMap, variable, |
info.capturedVariablesAccessor, localsMap); |
- i++; |
+ fieldNumber++; |
} |
FunctionEntity callMethod = cls.callMethod = new JClosureCallMethod( |
@@ -2211,36 +2316,16 @@ class JsKernelToElementMap extends KernelToElementMapBase |
return cls; |
} |
- _constructClosureFields( |
+ _constructClosureField( |
MemberEntity member, |
KernelClosureClass cls, |
Map<String, MemberEntity> memberMap, |
ir.VariableDeclaration variable, |
- int fieldNumber, |
NodeBox box, |
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)) { |
- FieldEntity boxedField = new JBoxedField( |
- _getClosureVariableName(capturedLocal.name, fieldNumber), |
- _memberData.length, |
- new BoxLocal(box.name, |
- localsMap.getLocalVariable(box.executableContext), member), |
- cls, |
- variable.isConst, |
- variable.isFinal || variable.isConst); |
- cls.localToFieldMap[capturedLocal] = boxedField; |
- _memberList.add(boxedField); |
- _memberData.add(new ClosureFieldData(new ClosureMemberDefinition( |
- boxedField, |
- computeSourceSpanFromTreeNode(variable), |
- MemberKind.closureField, |
- variable))); |
- memberMap[boxedField.name] = boxedField; |
- } else { |
+ if (!cls.isBoxed(capturedLocal)) { |
+ print('WWWWWWWWWWWWWW $capturedLocal aaaand ${cls.boxedVariables}'); |
FieldEntity closureField = new JClosureField( |
_getClosureVariableName(capturedLocal.name, fieldNumber), |
_memberData.length, |
@@ -2255,6 +2340,11 @@ class JsKernelToElementMap extends KernelToElementMapBase |
MemberKind.closureField, |
variable))); |
memberMap[closureField.name] = closureField; |
+ } else { |
+ // The box field should already be constructed from looping through the |
+ // boxed fields separately. |
+ cls.localToFieldMap[capturedLocal] = cls.boxedVariables[capturedLocal]; |
+ //assert(cls.localToFieldMap[capturedLocal] != null); |
} |
} |