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 4af0821c12d2487c597e9162f5e0e62ba8d35430..5d45001458ce004c198c493d10a818e050236a9e 100644 |
--- a/pkg/compiler/lib/src/kernel/element_map_impl.dart |
+++ b/pkg/compiler/lib/src/kernel/element_map_impl.dart |
@@ -513,9 +513,8 @@ abstract class KernelToElementMapBase extends KernelToElementMapBaseMixin { |
} |
} |
-/// Mixin that implements the abstract methods in [KernelToElementMapBase] by |
-/// creating K-model elements. |
-abstract class KElementCreatorMixin { |
+/// Mixin that implements the abstract methods in [KernelToElementMapBase]. |
+abstract class ElementCreatorMixin { |
ProgramEnv get _env; |
List<LibraryEntity> get _libraryList; |
List<LibraryEnv> get _libraryEnvs; |
@@ -524,15 +523,16 @@ abstract class KElementCreatorMixin { |
List<MemberEntity> get _memberList; |
List<MemberData> get _memberData; |
- Map<ir.Library, KLibrary> _libraryMap = <ir.Library, KLibrary>{}; |
- Map<ir.Class, KClass> _classMap = <ir.Class, KClass>{}; |
- Map<ir.TypeParameter, KTypeVariable> _typeVariableMap = |
- <ir.TypeParameter, KTypeVariable>{}; |
- Map<ir.Member, KConstructor> _constructorMap = <ir.Member, KConstructor>{}; |
- Map<ir.Procedure, KFunction> _methodMap = <ir.Procedure, KFunction>{}; |
- Map<ir.Field, KField> _fieldMap = <ir.Field, KField>{}; |
- Map<ir.TreeNode, KLocalFunction> _localFunctionMap = |
- <ir.TreeNode, KLocalFunction>{}; |
+ Map<ir.Library, IndexedLibrary> _libraryMap = <ir.Library, IndexedLibrary>{}; |
+ Map<ir.Class, IndexedClass> _classMap = <ir.Class, IndexedClass>{}; |
+ Map<ir.TypeParameter, TypeVariableEntity> _typeVariableMap = |
+ <ir.TypeParameter, TypeVariableEntity>{}; |
+ Map<ir.Member, IndexedConstructor> _constructorMap = |
+ <ir.Member, IndexedConstructor>{}; |
+ Map<ir.Procedure, IndexedFunction> _methodMap = |
+ <ir.Procedure, IndexedFunction>{}; |
+ Map<ir.Field, IndexedField> _fieldMap = <ir.Field, IndexedField>{}; |
+ Map<ir.TreeNode, Local> _localFunctionMap = <ir.TreeNode, Local>{}; |
Name getName(ir.Name node); |
FunctionType getFunctionType(ir.FunctionNode node); |
@@ -559,7 +559,7 @@ abstract class KElementCreatorMixin { |
name = path.substring(path.lastIndexOf('/') + 1); |
} |
LibraryEntity library = |
- new KLibrary(_libraryMap.length, name, canonicalUri); |
+ createLibrary(_libraryMap.length, name, canonicalUri); |
_libraryList.add(library); |
return library; |
}); |
@@ -572,7 +572,7 @@ abstract class KElementCreatorMixin { |
classEnv = _libraryEnvs[library.libraryIndex].lookupClass(node.name); |
} |
_classEnvs.add(classEnv); |
- ClassEntity cls = new KClass(library, _classMap.length, node.name, |
+ ClassEntity cls = createClass(library, _classMap.length, node.name, |
isAbstract: node.isAbstract); |
_classList.add(cls); |
return cls; |
@@ -584,7 +584,7 @@ abstract class KElementCreatorMixin { |
if (node.parent is ir.Class) { |
ir.Class cls = node.parent; |
int index = cls.typeParameters.indexOf(node); |
- return new KTypeVariable(_getClass(cls), node.name, index); |
+ return createTypeVariable(_getClass(cls), node.name, index); |
} |
if (node.parent is ir.FunctionNode) { |
ir.FunctionNode func = node.parent; |
@@ -600,7 +600,7 @@ abstract class KElementCreatorMixin { |
ir.Class cls = procedure.enclosingClass; |
return _getTypeVariable(cls.typeParameters[index]); |
} else { |
- return new KTypeVariable(_getMethod(procedure), node.name, index); |
+ return createTypeVariable(_getMethod(procedure), node.name, index); |
} |
} |
} |
@@ -619,7 +619,7 @@ abstract class KElementCreatorMixin { |
ir.FunctionNode functionNode; |
if (node is ir.Constructor) { |
functionNode = node.function; |
- constructor = new KGenerativeConstructor(memberIndex, enclosingClass, |
+ constructor = createGenerativeConstructor(memberIndex, enclosingClass, |
name, _getParameterStructure(functionNode), |
isExternal: isExternal, isConst: node.isConst); |
} else if (node is ir.Procedure) { |
@@ -627,8 +627,8 @@ abstract class KElementCreatorMixin { |
bool isFromEnvironment = isExternal && |
name.text == 'fromEnvironment' && |
const ['int', 'bool', 'String'].contains(enclosingClass.name); |
- constructor = new KFactoryConstructor(memberIndex, enclosingClass, name, |
- _getParameterStructure(functionNode), |
+ constructor = createFactoryConstructor(memberIndex, enclosingClass, |
+ name, _getParameterStructure(functionNode), |
isExternal: isExternal, |
isConst: node.isConst, |
isFromEnvironmentConstructor: isFromEnvironment); |
@@ -658,7 +658,7 @@ abstract class KElementCreatorMixin { |
bool isStatic = node.isStatic; |
bool isExternal = node.isExternal; |
bool isAbstract = node.isAbstract; |
- KFunction function; |
+ IndexedFunction function; |
AsyncMarker asyncMarker; |
switch (node.function.asyncMarker) { |
case ir.AsyncMarker.Async: |
@@ -681,7 +681,7 @@ abstract class KElementCreatorMixin { |
case ir.ProcedureKind.Factory: |
throw new UnsupportedError("Cannot create method from factory."); |
case ir.ProcedureKind.Getter: |
- function = new KGetter( |
+ function = createGetter( |
memberIndex, library, enclosingClass, name, asyncMarker, |
isStatic: isStatic, |
isExternal: isExternal, |
@@ -689,7 +689,7 @@ abstract class KElementCreatorMixin { |
break; |
case ir.ProcedureKind.Method: |
case ir.ProcedureKind.Operator: |
- function = new KMethod(memberIndex, library, enclosingClass, name, |
+ function = createMethod(memberIndex, library, enclosingClass, name, |
_getParameterStructure(node.function), asyncMarker, |
isStatic: isStatic, |
isExternal: isExternal, |
@@ -697,8 +697,8 @@ abstract class KElementCreatorMixin { |
break; |
case ir.ProcedureKind.Setter: |
assert(asyncMarker == AsyncMarker.SYNC); |
- function = new KSetter( |
- memberIndex, library, enclosingClass, getName(node.name).setter, |
+ function = createSetter( |
+ memberIndex, library, enclosingClass, name.setter, |
isStatic: isStatic, |
isExternal: isExternal, |
isAbstract: isAbstract); |
@@ -724,7 +724,8 @@ abstract class KElementCreatorMixin { |
Name name = getName(node.name); |
bool isStatic = node.isStatic; |
_memberData.add(new FieldData(node)); |
- FieldEntity field = new KField(memberIndex, library, enclosingClass, name, |
+ FieldEntity field = createField( |
+ memberIndex, library, enclosingClass, name, |
isStatic: isStatic, |
isAssignable: node.isMutable, |
isConst: node.isConst); |
@@ -755,7 +756,7 @@ abstract class KElementCreatorMixin { |
} |
if (parent is ir.FunctionDeclaration || |
parent is ir.FunctionExpression) { |
- KLocalFunction localFunction = _getLocalFunction(parent); |
+ Local localFunction = _getLocalFunction(parent); |
executableContext = localFunction; |
memberContext = localFunction.memberContext; |
break; |
@@ -770,10 +771,148 @@ abstract class KElementCreatorMixin { |
} else if (node is ir.FunctionExpression) { |
functionType = getFunctionType(node.function); |
} |
- return new KLocalFunction( |
+ return createLocalFunction( |
name, memberContext, executableContext, functionType); |
}); |
} |
+ |
+ IndexedLibrary createLibrary(int libraryIndex, String name, Uri canonicalUri); |
+ |
+ IndexedClass createClass(LibraryEntity library, int classIndex, String name, |
+ {bool isAbstract}); |
+ |
+ TypeVariableEntity createTypeVariable( |
+ Entity typeDeclaration, String name, int index); |
+ |
+ IndexedConstructor createGenerativeConstructor( |
+ int memberIndex, |
+ ClassEntity enclosingClass, |
+ Name name, |
+ ParameterStructure parameterStructure, |
+ {bool isExternal, |
+ bool isConst}); |
+ |
+ IndexedConstructor createFactoryConstructor( |
+ int memberIndex, |
+ ClassEntity enclosingClass, |
+ Name name, |
+ ParameterStructure parameterStructure, |
+ {bool isExternal, |
+ bool isConst, |
+ bool isFromEnvironmentConstructor}); |
+ |
+ IndexedFunction createGetter(int memberIndex, LibraryEntity library, |
+ ClassEntity enclosingClass, Name name, AsyncMarker asyncMarker, |
+ {bool isStatic, bool isExternal, bool isAbstract}); |
+ |
+ IndexedFunction createMethod( |
+ int memberIndex, |
+ LibraryEntity library, |
+ ClassEntity enclosingClass, |
+ Name name, |
+ ParameterStructure parameterStructure, |
+ AsyncMarker asyncMarker, |
+ {bool isStatic, |
+ bool isExternal, |
+ bool isAbstract}); |
+ |
+ IndexedFunction createSetter(int memberIndex, LibraryEntity library, |
+ ClassEntity enclosingClass, Name name, |
+ {bool isStatic, bool isExternal, bool isAbstract}); |
+ |
+ IndexedField createField(int memberIndex, LibraryEntity library, |
+ ClassEntity enclosingClass, Name name, |
+ {bool isStatic, bool isAssignable, bool isConst}); |
+ |
+ Local createLocalFunction(String name, MemberEntity memberContext, |
+ Entity executableContext, FunctionType functionType); |
+} |
+ |
+/// Completes the [ElementCreatorMixin] by creating K-model elements. |
+abstract class KElementCreatorMixin implements ElementCreatorMixin { |
+ IndexedLibrary createLibrary( |
+ int libraryIndex, String name, Uri canonicalUri) { |
+ return new KLibrary(libraryIndex, name, canonicalUri); |
+ } |
+ |
+ IndexedClass createClass(LibraryEntity library, int classIndex, String name, |
+ {bool isAbstract}) { |
+ return new KClass(library, classIndex, name, isAbstract: isAbstract); |
+ } |
+ |
+ TypeVariableEntity createTypeVariable( |
+ Entity typeDeclaration, String name, int index) { |
+ return new KTypeVariable(typeDeclaration, name, index); |
+ } |
+ |
+ IndexedConstructor createGenerativeConstructor( |
+ int memberIndex, |
+ ClassEntity enclosingClass, |
+ Name name, |
+ ParameterStructure parameterStructure, |
+ {bool isExternal, |
+ bool isConst}) { |
+ return new KGenerativeConstructor( |
+ memberIndex, enclosingClass, name, parameterStructure, |
+ isExternal: isExternal, isConst: isConst); |
+ } |
+ |
+ IndexedConstructor createFactoryConstructor( |
+ int memberIndex, |
+ ClassEntity enclosingClass, |
+ Name name, |
+ ParameterStructure parameterStructure, |
+ {bool isExternal, |
+ bool isConst, |
+ bool isFromEnvironmentConstructor}) { |
+ return new KFactoryConstructor( |
+ memberIndex, enclosingClass, name, parameterStructure, |
+ isExternal: isExternal, |
+ isConst: isConst, |
+ isFromEnvironmentConstructor: isFromEnvironmentConstructor); |
+ } |
+ |
+ IndexedFunction createGetter(int memberIndex, LibraryEntity library, |
+ ClassEntity enclosingClass, Name name, AsyncMarker asyncMarker, |
+ {bool isStatic, bool isExternal, bool isAbstract}) { |
+ return new KGetter(memberIndex, library, enclosingClass, name, asyncMarker, |
+ isStatic: isStatic, isExternal: isExternal, isAbstract: isAbstract); |
+ } |
+ |
+ IndexedFunction createMethod( |
+ int memberIndex, |
+ LibraryEntity library, |
+ ClassEntity enclosingClass, |
+ Name name, |
+ ParameterStructure parameterStructure, |
+ AsyncMarker asyncMarker, |
+ {bool isStatic, |
+ bool isExternal, |
+ bool isAbstract}) { |
+ return new KMethod(memberIndex, library, enclosingClass, name, |
+ parameterStructure, asyncMarker, |
+ isStatic: isStatic, isExternal: isExternal, isAbstract: isAbstract); |
+ } |
+ |
+ IndexedFunction createSetter(int memberIndex, LibraryEntity library, |
+ ClassEntity enclosingClass, Name name, |
+ {bool isStatic, bool isExternal, bool isAbstract}) { |
+ return new KSetter(memberIndex, library, enclosingClass, name, |
+ isStatic: isStatic, isExternal: isExternal, isAbstract: isAbstract); |
+ } |
+ |
+ IndexedField createField(int memberIndex, LibraryEntity library, |
+ ClassEntity enclosingClass, Name name, |
+ {bool isStatic, bool isAssignable, bool isConst}) { |
+ return new KField(memberIndex, library, enclosingClass, name, |
+ isStatic: isStatic, isAssignable: isAssignable, isConst: isConst); |
+ } |
+ |
+ Local createLocalFunction(String name, MemberEntity memberContext, |
+ Entity executableContext, FunctionType functionType) { |
+ return new KLocalFunction( |
+ name, memberContext, executableContext, functionType); |
+ } |
} |
/// Implementation of [KernelToElementMapForImpact] that only supports world |
@@ -821,6 +960,7 @@ class KernelToElementMapForImpactImpl2 extends KernelToElementMapBase |
with |
KernelToElementMapForImpactMixin, |
KernelToElementMapForImpactImpl, |
+ ElementCreatorMixin, |
KElementCreatorMixin { |
KernelToElementMapForImpactImpl2( |
DiagnosticReporter reporter, Environment environment) |
@@ -831,7 +971,10 @@ class KernelToElementMapForImpactImpl2 extends KernelToElementMapBase |
/// IR nodes. |
// TODO(johnniwinther): Use this in the JsStrategy |
class KernelToElementMapForBuildingImpl extends KernelToElementMapBase |
- with KernelToElementMapForBuildingMixin, KElementCreatorMixin |
+ with |
+ KernelToElementMapForBuildingMixin, |
+ ElementCreatorMixin, |
+ KElementCreatorMixin |
implements KernelToWorldBuilder { |
KernelToElementMapForBuildingImpl( |
DiagnosticReporter reporter, Environment environment) |
@@ -893,6 +1036,7 @@ class KernelToElementMapImpl extends KernelToElementMapForBuildingImpl |
with |
KernelToElementMapForImpactMixin, |
KernelToElementMapForImpactImpl, |
+ ElementCreatorMixin, |
KElementCreatorMixin |
implements KernelToElementMapForImpactImpl2 { |
KernelToElementMapImpl(DiagnosticReporter reporter, Environment environment) |
@@ -1533,18 +1677,22 @@ class JsToFrontendMapImpl extends JsToFrontendMapBase |
} |
class JsKernelToElementMap extends KernelToElementMapBase |
- with KernelToElementMapForBuildingMixin, JsElementCreatorMixin |
- implements KernelToWorldBuilder { |
+ with |
+ KernelToElementMapForBuildingMixin, |
+ JsElementCreatorMixin, |
+ // TODO(johnniwinther): Avoid mixin in [ElementCreatorMixin]. The |
+ // codegen world should be a strict subset of the resolution world and |
+ // creating elements for IR nodes should therefore not be needed. |
+ // Currently some are created purely for testing (like |
+ // `element == commonElements.foo`, where 'foo' might not be live). |
+ // Others are created because we do a |
+ // `elementEnvironment.forEachLibraryMember(...)` call on each emitted |
+ // library. |
+ ElementCreatorMixin |
+ implements |
+ KernelToWorldBuilder { |
JsToFrontendMap _jsToFrontendMap; |
- Map<ir.Library, JLibrary> _libraryMap = <ir.Library, JLibrary>{}; |
- Map<ir.Class, JClass> _classMap = <ir.Class, JClass>{}; |
- Map<ir.TypeParameter, JTypeVariable> _typeVariableMap = |
- <ir.TypeParameter, JTypeVariable>{}; |
- Map<ir.Member, JConstructor> _constructorMap = <ir.Member, JConstructor>{}; |
- Map<ir.Procedure, JFunction> _methodMap = <ir.Procedure, JFunction>{}; |
- Map<ir.Field, JField> _fieldMap = <ir.Field, JField>{}; |
- |
JsKernelToElementMap(DiagnosticReporter reporter, Environment environment, |
KernelToElementMapForImpactImpl _elementMap) |
: super(reporter, environment) { |
@@ -1555,7 +1703,7 @@ class JsKernelToElementMap extends KernelToElementMapBase |
libraryIndex++) { |
LibraryEnv env = _elementMap._libraryEnvs[libraryIndex]; |
LibraryEntity oldLibrary = _elementMap._libraryList[libraryIndex]; |
- JLibrary newLibrary = createLibrary(oldLibrary); |
+ LibraryEntity newLibrary = convertLibrary(oldLibrary); |
_libraryMap[env.library] = newLibrary; |
_libraryList.add(newLibrary); |
_libraryEnvs.add(env); |
@@ -1566,8 +1714,8 @@ class JsKernelToElementMap extends KernelToElementMapBase |
ClassEnv env = _elementMap._classEnvs[classIndex]; |
ClassEntity oldClass = _elementMap._classList[classIndex]; |
IndexedLibrary oldLibrary = oldClass.library; |
- JLibrary newLibrary = _libraryList[oldLibrary.libraryIndex]; |
- JClass newClass = createClass(newLibrary, oldClass); |
+ LibraryEntity newLibrary = _libraryList[oldLibrary.libraryIndex]; |
+ ClassEntity newClass = convertClass(newLibrary, oldClass); |
_classMap[env.cls] = newClass; |
_classList.add(newClass); |
_classEnvs.add(env); |
@@ -1579,10 +1727,10 @@ class JsKernelToElementMap extends KernelToElementMapBase |
MemberEntity oldMember = _elementMap._memberList[memberIndex]; |
IndexedLibrary oldLibrary = oldMember.library; |
IndexedClass oldClass = oldMember.enclosingClass; |
- JLibrary newLibrary = _libraryList[oldLibrary.libraryIndex]; |
- JClass newClass = |
+ LibraryEntity newLibrary = _libraryList[oldLibrary.libraryIndex]; |
+ ClassEntity newClass = |
oldClass != null ? _classList[oldClass.classIndex] : null; |
- JMember newMember = createMember(newLibrary, newClass, oldMember); |
+ IndexedMember newMember = convertMember(newLibrary, newClass, oldMember); |
_memberList.add(newMember); |
_memberData.add(data); |
if (newMember.isField) { |
@@ -1630,19 +1778,21 @@ class JsKernelToElementMap extends KernelToElementMapBase |
throw new UnsupportedError("JsKernelToElementMap._getTypeVariable"); |
} |
- @override |
+ // TODO(johnniwinther): Reinsert these when [ElementCreatorMixin] is no longer |
+ // mixed in. |
+ /*@override |
FieldEntity _getField(ir.Field node) { |
FieldEntity field = _fieldMap[node]; |
assert(field != null, "No field entity for $node"); |
return field; |
- } |
+ }*/ |
- @override |
+ /*@override |
FunctionEntity _getMethod(ir.Procedure node) { |
FunctionEntity function = _methodMap[node]; |
assert(function != null, "No function entity for $node"); |
return function; |
- } |
+ }*/ |
@override |
ConstructorEntity _getConstructor(ir.Member node) { |