| 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);
|
| }
|
| }
|
|
|
|
|