Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1215)

Unified Diff: pkg/compiler/lib/src/kernel/element_map_impl.dart

Issue 2964683003: Split implementation of KernelToElementMapImpl (Closed)
Patch Set: Updated cf. comments Created 3 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « pkg/compiler/lib/src/kernel/element_map.dart ('k') | pkg/compiler/lib/src/kernel/element_map_mixins.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 fc663e4fd02d2c885c3808680ae67f60ed7ae59d..f638db42bcc5c22ac7ba82e92e1d92e6a6ccc296 100644
--- a/pkg/compiler/lib/src/kernel/element_map_impl.dart
+++ b/pkg/compiler/lib/src/kernel/element_map_impl.dart
@@ -5,8 +5,6 @@
library dart2js.kernel.element_map;
import 'package:kernel/ast.dart' as ir;
-import 'package:kernel/clone.dart';
-import 'package:kernel/type_algebra.dart';
import '../common.dart';
import '../common/names.dart' show Identifiers;
@@ -33,7 +31,6 @@ import '../js_model/elements.dart';
import '../native/native.dart' as native;
import '../native/resolver.dart';
import '../ordered_typeset.dart';
-import '../ssa/kernel_impact.dart';
import '../universe/class_set.dart';
import '../universe/function_set.dart';
import '../universe/selector.dart';
@@ -43,6 +40,8 @@ import '../util/util.dart' show Link, LinkBuilder;
import 'element_map.dart';
import 'element_map_mixins.dart';
import 'elements.dart';
+import 'env.dart';
+import 'kelements.dart';
part 'native_basic_data.dart';
part 'no_such_method_resolver.dart';
@@ -62,99 +61,85 @@ abstract class KernelToWorldBuilder implements KernelToElementMapForBuilding {
void f(DartType type, String name, ConstantValue defaultValue));
}
-class KernelToElementMapBase extends KernelToElementMapBaseMixin {
+abstract class KernelToElementMapBase extends KernelToElementMapBaseMixin {
final DiagnosticReporter reporter;
CommonElements _commonElements;
ElementEnvironment _elementEnvironment;
DartTypeConverter _typeConverter;
KernelConstantEnvironment _constantEnvironment;
+ _KernelDartTypes _types;
/// Library environment. Used for fast lookup.
- _KEnv _env = new _KEnv();
+ ProgramEnv _env = new ProgramEnv();
- /// List of library environments by `KLibrary.libraryIndex`. This is used for
- /// fast lookup into library classes and members.
- List<_KLibraryEnv> _libraryEnvs = <_KLibraryEnv>[];
+ /// List of library environments by `IndexedLibrary.libraryIndex`. This is
+ /// used for fast lookup into library classes and members.
+ List<LibraryEnv> _libraryEnvs = <LibraryEnv>[];
- /// List of class environments by `KClass.classIndex`. This is used for
+ /// List of class environments by `IndexedClass.classIndex`. This is used for
/// fast lookup into class members.
- List<_KClassEnv> _classEnvs = <_KClassEnv>[];
-
- Map<ir.Library, KLibrary> _libraryMap = <ir.Library, KLibrary>{};
- Map<ir.Class, KClass> _classMap = <ir.Class, KClass>{};
- Map<ir.TypeParameter, KTypeVariable> _typeVariableMap =
- <ir.TypeParameter, KTypeVariable>{};
-
- List<_MemberData> _memberList = <_MemberData>[];
+ List<ClassEnv> _classEnvs = <ClassEnv>[];
- 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>{};
+ /// List of member data by `IndexedMember.classIndex`. This is used for
+ /// fast lookup into member properties.
+ List<MemberData> _memberList = <MemberData>[];
KernelToElementMapBase(this.reporter, Environment environment) {
_elementEnvironment = new KernelElementEnvironment(this);
_commonElements = new CommonElements(_elementEnvironment);
_constantEnvironment = new KernelConstantEnvironment(this, environment);
_typeConverter = new DartTypeConverter(this);
+ _types = new _KernelDartTypes(this);
}
+ DartTypes get types => _types;
+
@override
ElementEnvironment get elementEnvironment => _elementEnvironment;
@override
CommonElements get commonElements => _commonElements;
- KMethod get _mainFunction {
+ FunctionEntity get _mainFunction {
return _env.mainMethod != null ? _getMethod(_env.mainMethod) : null;
}
- KLibrary get _mainLibrary {
+ LibraryEntity get _mainLibrary {
return _env.mainMethod != null
? _getLibrary(_env.mainMethod.enclosingLibrary)
: null;
}
- Iterable<LibraryEntity> get _libraries {
- if (_env.length != _libraryMap.length) {
- // Create a [KLibrary] for each library.
- _env.forEachLibrary((_KLibraryEnv env) {
- _getLibrary(env.library, env);
- });
- }
- return _libraryMap.values;
- }
+ Iterable<LibraryEntity> get _libraries;
LibraryEntity lookupLibrary(Uri uri) {
- _KLibraryEnv libraryEnv = _env.lookupLibrary(uri);
+ LibraryEnv libraryEnv = _env.lookupLibrary(uri);
if (libraryEnv == null) return null;
return _getLibrary(libraryEnv.library, libraryEnv);
}
String _getLibraryName(KLibrary library) {
- _KLibraryEnv libraryEnv = _libraryEnvs[library.libraryIndex];
+ LibraryEnv libraryEnv = _libraryEnvs[library.libraryIndex];
return libraryEnv.library.name ?? '';
}
MemberEntity lookupLibraryMember(KLibrary library, String name,
{bool setter: false}) {
- _KLibraryEnv libraryEnv = _libraryEnvs[library.libraryIndex];
+ LibraryEnv libraryEnv = _libraryEnvs[library.libraryIndex];
ir.Member member = libraryEnv.lookupMember(name, setter: setter);
return member != null ? getMember(member) : null;
}
void _forEachLibraryMember(KLibrary library, void f(MemberEntity member)) {
- _KLibraryEnv libraryEnv = _libraryEnvs[library.libraryIndex];
+ LibraryEnv libraryEnv = _libraryEnvs[library.libraryIndex];
libraryEnv.forEachMember((ir.Member node) {
f(getMember(node));
});
}
ClassEntity lookupClass(KLibrary library, String name) {
- _KLibraryEnv libraryEnv = _libraryEnvs[library.libraryIndex];
- _KClassEnv classEnv = libraryEnv.lookupClass(name);
+ LibraryEnv libraryEnv = _libraryEnvs[library.libraryIndex];
+ ClassEnv classEnv = libraryEnv.lookupClass(name);
if (classEnv != null) {
return _getClass(classEnv.cls, classEnv);
}
@@ -162,23 +147,23 @@ class KernelToElementMapBase extends KernelToElementMapBaseMixin {
}
void _forEachClass(KLibrary library, void f(ClassEntity cls)) {
- _KLibraryEnv libraryEnv = _libraryEnvs[library.libraryIndex];
- libraryEnv.forEachClass((_KClassEnv classEnv) {
+ LibraryEnv libraryEnv = _libraryEnvs[library.libraryIndex];
+ libraryEnv.forEachClass((ClassEnv classEnv) {
if (!classEnv.isUnnamedMixinApplication) {
f(_getClass(classEnv.cls, classEnv));
}
});
}
- MemberEntity lookupClassMember(KClass cls, String name,
+ MemberEntity lookupClassMember(IndexedClass cls, String name,
{bool setter: false}) {
- _KClassEnv classEnv = _classEnvs[cls.classIndex];
+ ClassEnv classEnv = _classEnvs[cls.classIndex];
ir.Member member = classEnv.lookupMember(name, setter: setter);
return member != null ? getMember(member) : null;
}
- ConstructorEntity lookupConstructor(KClass cls, String name) {
- _KClassEnv classEnv = _classEnvs[cls.classIndex];
+ ConstructorEntity lookupConstructor(IndexedClass cls, String name) {
+ ClassEnv classEnv = _classEnvs[cls.classIndex];
ir.Member member = classEnv.lookupConstructor(name);
return member != null ? getConstructor(member) : null;
}
@@ -191,42 +176,20 @@ class KernelToElementMapBase extends KernelToElementMapBaseMixin {
LibraryEntity getLibrary(ir.Library node) => _getLibrary(node);
- KLibrary _getLibrary(ir.Library node, [_KLibraryEnv libraryEnv]) {
- return _libraryMap.putIfAbsent(node, () {
- Uri canonicalUri = node.importUri;
- _libraryEnvs.add(libraryEnv ?? _env.lookupLibrary(canonicalUri));
- String name = node.name;
- if (name == null) {
- // Use the file name as script name.
- String path = canonicalUri.path;
- name = path.substring(path.lastIndexOf('/') + 1);
- }
- return new KLibrary(_libraryMap.length, name, canonicalUri);
- });
- }
+ LibraryEntity _getLibrary(ir.Library node, [LibraryEnv libraryEnv]);
@override
ClassEntity getClass(ir.Class node) => _getClass(node);
- KClass _getClass(ir.Class node, [_KClassEnv classEnv]) {
- return _classMap.putIfAbsent(node, () {
- KLibrary library = _getLibrary(node.enclosingLibrary);
- if (classEnv == null) {
- classEnv = _libraryEnvs[library.libraryIndex].lookupClass(node.name);
- }
- _classEnvs.add(classEnv);
- return new KClass(library, _classMap.length, node.name,
- isAbstract: node.isAbstract);
- });
- }
+ ClassEntity _getClass(ir.Class node, [ClassEnv classEnv]);
- InterfaceType _getSuperType(KClass cls) {
- _KClassEnv env = _classEnvs[cls.classIndex];
+ InterfaceType _getSuperType(IndexedClass cls) {
+ ClassEnv env = _classEnvs[cls.classIndex];
_ensureSupertypes(cls, env);
return env.supertype;
}
- void _ensureThisAndRawType(KClass cls, _KClassEnv env) {
+ void _ensureThisAndRawType(ClassEntity cls, ClassEnv env) {
if (env.thisType == null) {
ir.Class node = env.cls;
// TODO(johnniwinther): Add the type argument to the list literal when we
@@ -253,36 +216,9 @@ class KernelToElementMapBase extends KernelToElementMapBaseMixin {
TypeVariableEntity getTypeVariable(ir.TypeParameter node) =>
_getTypeVariable(node);
- KTypeVariable _getTypeVariable(ir.TypeParameter node) {
- return _typeVariableMap.putIfAbsent(node, () {
- 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);
- }
- if (node.parent is ir.FunctionNode) {
- ir.FunctionNode func = node.parent;
- int index = func.typeParameters.indexOf(node);
- if (func.parent is ir.Constructor) {
- ir.Constructor constructor = func.parent;
- ir.Class cls = constructor.enclosingClass;
- return _getTypeVariable(cls.typeParameters[index]);
- }
- if (func.parent is ir.Procedure) {
- ir.Procedure procedure = func.parent;
- if (procedure.kind == ir.ProcedureKind.Factory) {
- ir.Class cls = procedure.enclosingClass;
- return _getTypeVariable(cls.typeParameters[index]);
- } else {
- return new KTypeVariable(_getMethod(procedure), node.name, index);
- }
- }
- }
- throw new UnsupportedError('Unsupported type parameter type node $node.');
- });
- }
+ TypeVariableEntity _getTypeVariable(ir.TypeParameter node);
- void _ensureSupertypes(KClass cls, _KClassEnv env) {
+ void _ensureSupertypes(ClassEntity cls, ClassEnv env) {
if (env.orderedTypeSet == null) {
_ensureThisAndRawType(cls, env);
@@ -295,8 +231,8 @@ class KernelToElementMapBase extends KernelToElementMapBaseMixin {
} else {
InterfaceType processSupertype(ir.Supertype node) {
InterfaceType type = _typeConverter.visitSupertype(node);
- KClass superclass = type.element;
- _KClassEnv env = _classEnvs[superclass.classIndex];
+ IndexedClass superclass = type.element;
+ ClassEnv env = _classEnvs[superclass.classIndex];
_ensureSupertypes(superclass, env);
return type;
}
@@ -345,10 +281,10 @@ class KernelToElementMapBase extends KernelToElementMapBaseMixin {
if (target != null) {
return getMember(target);
}
- KClass cls = getMember(context).enclosingClass;
- KClass superclass = _getSuperType(cls)?.element;
+ ClassEntity cls = getMember(context).enclosingClass;
+ IndexedClass superclass = _getSuperType(cls)?.element;
while (superclass != null) {
- _KClassEnv env = _classEnvs[superclass.classIndex];
+ ClassEnv env = _classEnvs[superclass.classIndex];
ir.Member superMember = env.lookupMember(name.name, setter: setter);
if (superMember != null) {
return getMember(superMember);
@@ -362,51 +298,19 @@ class KernelToElementMapBase extends KernelToElementMapBaseMixin {
@override
ConstructorEntity getConstructor(ir.Member node) => _getConstructor(node);
- KConstructor _getConstructor(ir.Member node) {
- return _constructorMap.putIfAbsent(node, () {
- int memberIndex = _memberList.length;
- KConstructor constructor;
- KClass enclosingClass = _getClass(node.enclosingClass);
- Name name = getName(node.name);
- bool isExternal = node.isExternal;
-
- ir.FunctionNode functionNode;
- if (node is ir.Constructor) {
- functionNode = node.function;
- constructor = new KGenerativeConstructor(memberIndex, enclosingClass,
- name, _getParameterStructure(functionNode),
- isExternal: isExternal, isConst: node.isConst);
- } else if (node is ir.Procedure) {
- functionNode = node.function;
- bool isFromEnvironment = isExternal &&
- name.text == 'fromEnvironment' &&
- const ['int', 'bool', 'String'].contains(enclosingClass.name);
- constructor = new KFactoryConstructor(memberIndex, enclosingClass, name,
- _getParameterStructure(functionNode),
- isExternal: isExternal,
- isConst: node.isConst,
- isFromEnvironmentConstructor: isFromEnvironment);
- } else {
- // TODO(johnniwinther): Convert `node.location` to a [SourceSpan].
- throw new SpannableAssertionFailure(
- NO_LOCATION_SPANNABLE, "Unexpected constructor node: ${node}.");
- }
- _memberList.add(new _ConstructorData(node, functionNode));
- return constructor;
- });
- }
+ ConstructorEntity _getConstructor(ir.Member node);
ConstructorEntity getSuperConstructor(
ir.Constructor sourceNode, ir.Member targetNode) {
- KConstructor source = getConstructor(sourceNode);
- KClass sourceClass = source.enclosingClass;
- KConstructor target = getConstructor(targetNode);
- KClass targetClass = target.enclosingClass;
- KClass superClass = _getSuperType(sourceClass)?.element;
+ ConstructorEntity source = getConstructor(sourceNode);
+ ClassEntity sourceClass = source.enclosingClass;
+ ConstructorEntity target = getConstructor(targetNode);
+ ClassEntity targetClass = target.enclosingClass;
+ IndexedClass superClass = _getSuperType(sourceClass)?.element;
if (superClass == targetClass) {
return target;
}
- _KClassEnv env = _classEnvs[superClass.classIndex];
+ ClassEnv env = _classEnvs[superClass.classIndex];
ir.Member member = env.lookupConstructor(target.name);
if (member != null) {
return getConstructor(member);
@@ -418,140 +322,17 @@ class KernelToElementMapBase extends KernelToElementMapBaseMixin {
@override
FunctionEntity getMethod(ir.Procedure node) => _getMethod(node);
- KFunction _getMethod(ir.Procedure node) {
- return _methodMap.putIfAbsent(node, () {
- int memberIndex = _memberList.length;
- KLibrary library;
- KClass enclosingClass;
- if (node.enclosingClass != null) {
- enclosingClass = _getClass(node.enclosingClass);
- library = enclosingClass.library;
- } else {
- library = _getLibrary(node.enclosingLibrary);
- }
- Name name = getName(node.name);
- bool isStatic = node.isStatic;
- bool isExternal = node.isExternal;
- bool isAbstract = node.isAbstract;
- KFunction function;
- AsyncMarker asyncMarker;
- switch (node.function.asyncMarker) {
- case ir.AsyncMarker.Async:
- asyncMarker = AsyncMarker.ASYNC;
- break;
- case ir.AsyncMarker.AsyncStar:
- asyncMarker = AsyncMarker.ASYNC_STAR;
- break;
- case ir.AsyncMarker.Sync:
- asyncMarker = AsyncMarker.SYNC;
- break;
- case ir.AsyncMarker.SyncStar:
- asyncMarker = AsyncMarker.SYNC_STAR;
- break;
- case ir.AsyncMarker.SyncYielding:
- throw new UnsupportedError(
- "Async marker ${node.function.asyncMarker} is not supported.");
- }
- switch (node.kind) {
- case ir.ProcedureKind.Factory:
- throw new UnsupportedError("Cannot create method from factory.");
- case ir.ProcedureKind.Getter:
- function = new KGetter(
- memberIndex, library, enclosingClass, name, asyncMarker,
- isStatic: isStatic,
- isExternal: isExternal,
- isAbstract: isAbstract);
- break;
- case ir.ProcedureKind.Method:
- case ir.ProcedureKind.Operator:
- function = new KMethod(memberIndex, library, enclosingClass, name,
- _getParameterStructure(node.function), asyncMarker,
- isStatic: isStatic,
- isExternal: isExternal,
- isAbstract: isAbstract);
- break;
- case ir.ProcedureKind.Setter:
- assert(asyncMarker == AsyncMarker.SYNC);
- function = new KSetter(
- memberIndex, library, enclosingClass, getName(node.name).setter,
- isStatic: isStatic,
- isExternal: isExternal,
- isAbstract: isAbstract);
- break;
- }
- _memberList.add(new _FunctionData(node, node.function));
- return function;
- });
- }
+ FunctionEntity _getMethod(ir.Procedure node);
@override
FieldEntity getField(ir.Field node) => _getField(node);
- KField _getField(ir.Field node) {
- return _fieldMap.putIfAbsent(node, () {
- int memberIndex = _memberList.length;
- KLibrary library;
- KClass enclosingClass;
- if (node.enclosingClass != null) {
- enclosingClass = _getClass(node.enclosingClass);
- library = enclosingClass.library;
- } else {
- library = _getLibrary(node.enclosingLibrary);
- }
- Name name = getName(node.name);
- bool isStatic = node.isStatic;
- _memberList.add(new _FieldData(node));
- return new KField(memberIndex, library, enclosingClass, name,
- isStatic: isStatic,
- isAssignable: node.isMutable,
- isConst: node.isConst);
- });
- }
-
- ParameterStructure _getParameterStructure(ir.FunctionNode node) {
- // TODO(johnniwinther): Cache the computed function type.
- int requiredParameters = node.requiredParameterCount;
- int positionalParameters = node.positionalParameters.length;
- List<String> namedParameters =
- node.namedParameters.map((p) => p.name).toList()..sort();
- return new ParameterStructure(
- requiredParameters, positionalParameters, namedParameters);
- }
+ FieldEntity _getField(ir.Field node);
@override
- Local getLocalFunction(ir.TreeNode node) => _getLocal(node);
+ Local getLocalFunction(ir.TreeNode node) => _getLocalFunction(node);
- KLocalFunction _getLocal(ir.TreeNode node) {
- return _localFunctionMap.putIfAbsent(node, () {
- MemberEntity memberContext;
- Entity executableContext;
- ir.TreeNode parent = node.parent;
- while (parent != null) {
- if (parent is ir.Member) {
- executableContext = memberContext = getMember(parent);
- break;
- }
- if (parent is ir.FunctionDeclaration ||
- parent is ir.FunctionExpression) {
- KLocalFunction localFunction = _getLocal(parent);
- executableContext = localFunction;
- memberContext = localFunction.memberContext;
- break;
- }
- parent = parent.parent;
- }
- String name;
- FunctionType functionType;
- if (node is ir.FunctionDeclaration) {
- name = node.variable.name;
- functionType = getFunctionType(node.function);
- } else if (node is ir.FunctionExpression) {
- functionType = getFunctionType(node.function);
- }
- return new KLocalFunction(
- name, memberContext, executableContext, functionType);
- });
- }
+ Local _getLocalFunction(ir.TreeNode node);
@override
DartType getDartType(ir.DartType type) => _typeConverter.convert(type);
@@ -605,50 +386,50 @@ class KernelToElementMapBase extends KernelToElementMapBaseMixin {
context.typeArguments, _getThisType(context.element).typeArguments);
}
- InterfaceType _getThisType(KClass cls) {
- _KClassEnv env = _classEnvs[cls.classIndex];
+ InterfaceType _getThisType(IndexedClass cls) {
+ ClassEnv env = _classEnvs[cls.classIndex];
_ensureThisAndRawType(cls, env);
return env.thisType;
}
- InterfaceType _getRawType(KClass cls) {
- _KClassEnv env = _classEnvs[cls.classIndex];
+ InterfaceType _getRawType(IndexedClass cls) {
+ ClassEnv env = _classEnvs[cls.classIndex];
_ensureThisAndRawType(cls, env);
return env.rawType;
}
- FunctionType _getFunctionType(KFunction function) {
- _FunctionData data = _memberList[function.memberIndex];
+ FunctionType _getFunctionType(IndexedMember function) {
+ FunctionData data = _memberList[function.memberIndex];
return data.getFunctionType(this);
}
- ClassEntity _getAppliedMixin(KClass cls) {
- _KClassEnv env = _classEnvs[cls.classIndex];
+ ClassEntity _getAppliedMixin(IndexedClass cls) {
+ ClassEnv env = _classEnvs[cls.classIndex];
_ensureSupertypes(cls, env);
return env.mixedInType?.element;
}
- bool _isMixinApplication(KClass cls) {
- _KClassEnv env = _classEnvs[cls.classIndex];
+ bool _isMixinApplication(IndexedClass cls) {
+ ClassEnv env = _classEnvs[cls.classIndex];
_ensureSupertypes(cls, env);
return env.isMixinApplication;
}
- bool _isUnnamedMixinApplication(KClass cls) {
- _KClassEnv env = _classEnvs[cls.classIndex];
+ bool _isUnnamedMixinApplication(IndexedClass cls) {
+ ClassEnv env = _classEnvs[cls.classIndex];
_ensureSupertypes(cls, env);
return env.isUnnamedMixinApplication;
}
- void _forEachSupertype(KClass cls, void f(InterfaceType supertype)) {
- _KClassEnv env = _classEnvs[cls.classIndex];
+ void _forEachSupertype(IndexedClass cls, void f(InterfaceType supertype)) {
+ ClassEnv env = _classEnvs[cls.classIndex];
_ensureSupertypes(cls, env);
env.orderedTypeSet.supertypes.forEach(f);
}
- void _forEachMixin(KClass cls, void f(ClassEntity mixin)) {
+ void _forEachMixin(IndexedClass cls, void f(ClassEntity mixin)) {
while (cls != null) {
- _KClassEnv env = _classEnvs[cls.classIndex];
+ ClassEnv env = _classEnvs[cls.classIndex];
_ensureSupertypes(cls, env);
if (env.mixedInType != null) {
f(env.mixedInType.element);
@@ -657,16 +438,16 @@ class KernelToElementMapBase extends KernelToElementMapBaseMixin {
}
}
- void _forEachConstructor(KClass cls, void f(ConstructorEntity member)) {
- _KClassEnv env = _classEnvs[cls.classIndex];
+ void _forEachConstructor(IndexedClass cls, void f(ConstructorEntity member)) {
+ ClassEnv env = _classEnvs[cls.classIndex];
env.forEachConstructor((ir.Member member) {
f(getConstructor(member));
});
}
void _forEachClassMember(
- KClass cls, void f(ClassEntity cls, MemberEntity member)) {
- _KClassEnv env = _classEnvs[cls.classIndex];
+ IndexedClass cls, void f(ClassEntity cls, MemberEntity member)) {
+ ClassEnv env = _classEnvs[cls.classIndex];
env.forEachMember((ir.Member member) {
f(cls, getMember(member));
});
@@ -676,42 +457,318 @@ class KernelToElementMapBase extends KernelToElementMapBaseMixin {
}
}
- ConstantConstructor _getConstructorConstant(KConstructor constructor) {
- _ConstructorData data = _memberList[constructor.memberIndex];
- return data.getConstructorConstant(this, constructor);
+ ConstantConstructor _getConstructorConstant(IndexedConstructor constructor) {
+ ConstructorData data = _memberList[constructor.memberIndex];
+ return data.getConstructorConstant(this, constructor);
+ }
+
+ ConstantExpression _getFieldConstant(IndexedField field) {
+ FieldData data = _memberList[field.memberIndex];
+ return data.getFieldConstant(this, field);
+ }
+
+ InterfaceType _asInstanceOf(InterfaceType type, ClassEntity cls) {
+ OrderedTypeSet orderedTypeSet = _getOrderedTypeSet(type.element);
+ InterfaceType supertype =
+ orderedTypeSet.asInstanceOf(cls, _getHierarchyDepth(cls));
+ if (supertype != null) {
+ supertype = _substByContext(supertype, type);
+ }
+ return supertype;
+ }
+
+ OrderedTypeSet _getOrderedTypeSet(IndexedClass cls) {
+ ClassEnv env = _classEnvs[cls.classIndex];
+ _ensureSupertypes(cls, env);
+ return env.orderedTypeSet;
+ }
+
+ int _getHierarchyDepth(IndexedClass cls) {
+ ClassEnv env = _classEnvs[cls.classIndex];
+ _ensureSupertypes(cls, env);
+ return env.orderedTypeSet.maxDepth;
+ }
+
+ Iterable<InterfaceType> _getInterfaces(IndexedClass cls) {
+ ClassEnv env = _classEnvs[cls.classIndex];
+ _ensureSupertypes(cls, env);
+ return env.interfaces;
+ }
+
+ Spannable _getSpannable(MemberEntity member, ir.Node node) {
+ return member;
+ }
+
+ ir.Member _getMemberNode(covariant IndexedMember member) {
+ return _memberList[member.memberIndex].node;
+ }
+
+ ir.Class _getClassNode(covariant IndexedClass cls) {
+ return _classEnvs[cls.classIndex].cls;
+ }
+}
+
+/// Mixin that implements the abstract methods in [KernelToElementMapBase] by
+/// creating K-model elements.
+abstract class KElementCreatorMixin {
+ ProgramEnv get _env;
+ List<LibraryEnv> get _libraryEnvs;
+ List<ClassEnv> get _classEnvs;
+ List<MemberData> get _memberList;
+
+ 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>{};
+
+ Name getName(ir.Name node);
+ FunctionType getFunctionType(ir.FunctionNode node);
+ MemberEntity getMember(ir.Member node);
+
+ Iterable<LibraryEntity> get _libraries {
+ if (_env.length != _libraryMap.length) {
+ // Create a [KLibrary] for each library.
+ _env.forEachLibrary((LibraryEnv env) {
+ _getLibrary(env.library, env);
+ });
+ }
+ return _libraryMap.values;
+ }
+
+ LibraryEntity _getLibrary(ir.Library node, [LibraryEnv libraryEnv]) {
+ return _libraryMap.putIfAbsent(node, () {
+ Uri canonicalUri = node.importUri;
+ _libraryEnvs.add(libraryEnv ?? _env.lookupLibrary(canonicalUri));
+ String name = node.name;
+ if (name == null) {
+ // Use the file name as script name.
+ String path = canonicalUri.path;
+ name = path.substring(path.lastIndexOf('/') + 1);
+ }
+ return new KLibrary(_libraryMap.length, name, canonicalUri);
+ });
+ }
+
+ ClassEntity _getClass(ir.Class node, [ClassEnv classEnv]) {
+ return _classMap.putIfAbsent(node, () {
+ KLibrary library = _getLibrary(node.enclosingLibrary);
+ if (classEnv == null) {
+ classEnv = _libraryEnvs[library.libraryIndex].lookupClass(node.name);
+ }
+ _classEnvs.add(classEnv);
+ return new KClass(library, _classMap.length, node.name,
+ isAbstract: node.isAbstract);
+ });
+ }
+
+ TypeVariableEntity _getTypeVariable(ir.TypeParameter node) {
+ return _typeVariableMap.putIfAbsent(node, () {
+ 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);
+ }
+ if (node.parent is ir.FunctionNode) {
+ ir.FunctionNode func = node.parent;
+ int index = func.typeParameters.indexOf(node);
+ if (func.parent is ir.Constructor) {
+ ir.Constructor constructor = func.parent;
+ ir.Class cls = constructor.enclosingClass;
+ return _getTypeVariable(cls.typeParameters[index]);
+ }
+ if (func.parent is ir.Procedure) {
+ ir.Procedure procedure = func.parent;
+ if (procedure.kind == ir.ProcedureKind.Factory) {
+ ir.Class cls = procedure.enclosingClass;
+ return _getTypeVariable(cls.typeParameters[index]);
+ } else {
+ return new KTypeVariable(_getMethod(procedure), node.name, index);
+ }
+ }
+ }
+ throw new UnsupportedError('Unsupported type parameter type node $node.');
+ });
+ }
+
+ ConstructorEntity _getConstructor(ir.Member node) {
+ return _constructorMap.putIfAbsent(node, () {
+ int memberIndex = _memberList.length;
+ KConstructor constructor;
+ KClass enclosingClass = _getClass(node.enclosingClass);
+ Name name = getName(node.name);
+ bool isExternal = node.isExternal;
+
+ ir.FunctionNode functionNode;
+ if (node is ir.Constructor) {
+ functionNode = node.function;
+ constructor = new KGenerativeConstructor(memberIndex, enclosingClass,
+ name, _getParameterStructure(functionNode),
+ isExternal: isExternal, isConst: node.isConst);
+ } else if (node is ir.Procedure) {
+ functionNode = node.function;
+ bool isFromEnvironment = isExternal &&
+ name.text == 'fromEnvironment' &&
+ const ['int', 'bool', 'String'].contains(enclosingClass.name);
+ constructor = new KFactoryConstructor(memberIndex, enclosingClass, name,
+ _getParameterStructure(functionNode),
+ isExternal: isExternal,
+ isConst: node.isConst,
+ isFromEnvironmentConstructor: isFromEnvironment);
+ } else {
+ // TODO(johnniwinther): Convert `node.location` to a [SourceSpan].
+ throw new SpannableAssertionFailure(
+ NO_LOCATION_SPANNABLE, "Unexpected constructor node: ${node}.");
+ }
+ _memberList.add(new ConstructorData(node, functionNode));
+ return constructor;
+ });
+ }
+
+ FunctionEntity _getMethod(ir.Procedure node) {
+ return _methodMap.putIfAbsent(node, () {
+ int memberIndex = _memberList.length;
+ LibraryEntity library;
+ ClassEntity enclosingClass;
+ if (node.enclosingClass != null) {
+ enclosingClass = _getClass(node.enclosingClass);
+ library = enclosingClass.library;
+ } else {
+ library = _getLibrary(node.enclosingLibrary);
+ }
+ Name name = getName(node.name);
+ bool isStatic = node.isStatic;
+ bool isExternal = node.isExternal;
+ bool isAbstract = node.isAbstract;
+ KFunction function;
+ AsyncMarker asyncMarker;
+ switch (node.function.asyncMarker) {
+ case ir.AsyncMarker.Async:
+ asyncMarker = AsyncMarker.ASYNC;
+ break;
+ case ir.AsyncMarker.AsyncStar:
+ asyncMarker = AsyncMarker.ASYNC_STAR;
+ break;
+ case ir.AsyncMarker.Sync:
+ asyncMarker = AsyncMarker.SYNC;
+ break;
+ case ir.AsyncMarker.SyncStar:
+ asyncMarker = AsyncMarker.SYNC_STAR;
+ break;
+ case ir.AsyncMarker.SyncYielding:
+ throw new UnsupportedError(
+ "Async marker ${node.function.asyncMarker} is not supported.");
+ }
+ switch (node.kind) {
+ case ir.ProcedureKind.Factory:
+ throw new UnsupportedError("Cannot create method from factory.");
+ case ir.ProcedureKind.Getter:
+ function = new KGetter(
+ memberIndex, library, enclosingClass, name, asyncMarker,
+ isStatic: isStatic,
+ isExternal: isExternal,
+ isAbstract: isAbstract);
+ break;
+ case ir.ProcedureKind.Method:
+ case ir.ProcedureKind.Operator:
+ function = new KMethod(memberIndex, library, enclosingClass, name,
+ _getParameterStructure(node.function), asyncMarker,
+ isStatic: isStatic,
+ isExternal: isExternal,
+ isAbstract: isAbstract);
+ break;
+ case ir.ProcedureKind.Setter:
+ assert(asyncMarker == AsyncMarker.SYNC);
+ function = new KSetter(
+ memberIndex, library, enclosingClass, getName(node.name).setter,
+ isStatic: isStatic,
+ isExternal: isExternal,
+ isAbstract: isAbstract);
+ break;
+ }
+ _memberList.add(new FunctionData(node, node.function));
+ return function;
+ });
+ }
+
+ FieldEntity _getField(ir.Field node) {
+ return _fieldMap.putIfAbsent(node, () {
+ int memberIndex = _memberList.length;
+ LibraryEntity library;
+ ClassEntity enclosingClass;
+ if (node.enclosingClass != null) {
+ enclosingClass = _getClass(node.enclosingClass);
+ library = enclosingClass.library;
+ } else {
+ library = _getLibrary(node.enclosingLibrary);
+ }
+ Name name = getName(node.name);
+ bool isStatic = node.isStatic;
+ _memberList.add(new FieldData(node));
+ return new KField(memberIndex, library, enclosingClass, name,
+ isStatic: isStatic,
+ isAssignable: node.isMutable,
+ isConst: node.isConst);
+ });
}
- ConstantExpression _getFieldConstant(KField field) {
- _FieldData data = _memberList[field.memberIndex];
- return data.getFieldConstant(this, field);
+ ParameterStructure _getParameterStructure(ir.FunctionNode node) {
+ // TODO(johnniwinther): Cache the computed function type.
+ int requiredParameters = node.requiredParameterCount;
+ int positionalParameters = node.positionalParameters.length;
+ List<String> namedParameters =
+ node.namedParameters.map((p) => p.name).toList()..sort();
+ return new ParameterStructure(
+ requiredParameters, positionalParameters, namedParameters);
}
-}
-
-class KernelToElementMapForImpactImpl extends KernelToElementMapBase
- with KernelToElementMapForImpactMixin {
- native.BehaviorBuilder _nativeBehaviorBuilder;
- KernelToElementMapForImpactImpl(
- DiagnosticReporter reporter, Environment environment)
- : super(reporter, environment) {
- _nativeBehaviorBuilder = new KernelBehaviorBuilder(_commonElements);
+ Local _getLocalFunction(ir.TreeNode node) {
+ return _localFunctionMap.putIfAbsent(node, () {
+ MemberEntity memberContext;
+ Entity executableContext;
+ ir.TreeNode parent = node.parent;
+ while (parent != null) {
+ if (parent is ir.Member) {
+ executableContext = memberContext = getMember(parent);
+ break;
+ }
+ if (parent is ir.FunctionDeclaration ||
+ parent is ir.FunctionExpression) {
+ KLocalFunction localFunction = _getLocalFunction(parent);
+ executableContext = localFunction;
+ memberContext = localFunction.memberContext;
+ break;
+ }
+ parent = parent.parent;
+ }
+ String name;
+ FunctionType functionType;
+ if (node is ir.FunctionDeclaration) {
+ name = node.variable.name;
+ functionType = getFunctionType(node.function);
+ } else if (node is ir.FunctionExpression) {
+ functionType = getFunctionType(node.function);
+ }
+ return new KLocalFunction(
+ name, memberContext, executableContext, functionType);
+ });
}
-
- @override
- native.BehaviorBuilder get nativeBehaviorBuilder => _nativeBehaviorBuilder;
}
-/// Element builder used for creating elements and types corresponding to Kernel
-/// IR nodes.
-class KernelToElementMapImpl extends KernelToElementMapForImpactImpl
- with KernelToElementMapForBuildingMixin
- implements KernelToWorldBuilder {
- _KernelDartTypes _types;
-
- KernelToElementMapImpl(DiagnosticReporter reporter, Environment environment)
- : super(reporter, environment) {
- _types = new _KernelDartTypes(this);
- }
+/// Implementation of [KernelToElementMapForImpact] that only supports world
+/// impact computation.
+// TODO(johnniwinther): Merge this with [KernelToElementMapForImpactImpl] when
+// [JsStrategy] is the default.
+abstract class KernelToElementMapForImpactImpl
+ implements
+ KernelToElementMapBase,
+ KernelToElementMapForImpact,
+ KernelToElementMapForImpactMixin {
+ native.BehaviorBuilder _nativeBehaviorBuilder;
/// Adds libraries in [program] to the set of libraries.
///
@@ -721,19 +778,12 @@ class KernelToElementMapImpl extends KernelToElementMapForImpactImpl
_env.addProgram(program);
}
- ConstantEnvironment get constantEnvironment => _constantEnvironment;
-
- DartTypes get types => _types;
-
@override
- ConstantValue getFieldConstantValue(ir.Field field) {
- // TODO(johnniwinther): Cache the result in [_FieldData].
- return getConstantValue(field.initializer,
- requireConstant: field.isConst, implicitNull: !field.isConst);
- }
+ native.BehaviorBuilder get nativeBehaviorBuilder =>
+ _nativeBehaviorBuilder ??= new KernelBehaviorBuilder(commonElements);
- Iterable<ConstantValue> _getClassMetadata(KClass cls) {
- return _classEnvs[cls.classIndex].getMetadata(this);
+ ResolutionImpact computeWorldImpact(KMember member) {
+ return _memberList[member.memberIndex].getWorldImpact(this);
}
/// Returns the kernel [ir.Procedure] node for the [method].
@@ -741,32 +791,42 @@ class KernelToElementMapImpl extends KernelToElementMapForImpactImpl
return _memberList[method.memberIndex].node;
}
- InterfaceType _asInstanceOf(InterfaceType type, KClass cls) {
- OrderedTypeSet orderedTypeSet = _getOrderedTypeSet(type.element);
- InterfaceType supertype =
- orderedTypeSet.asInstanceOf(cls, _getHierarchyDepth(cls));
- if (supertype != null) {
- supertype = _substByContext(supertype, type);
- }
- return supertype;
+ Iterable<ConstantValue> _getClassMetadata(KClass cls) {
+ return _classEnvs[cls.classIndex].getMetadata(this);
}
+}
- OrderedTypeSet _getOrderedTypeSet(KClass cls) {
- _KClassEnv env = _classEnvs[cls.classIndex];
- _ensureSupertypes(cls, env);
- return env.orderedTypeSet;
- }
+/// Implementation of [KernelToElementMapForImpact] that only supports world
+/// impact computation.
+// TODO(johnniwinther): Merge this with [KernelToElementMapForImpactImpl] when
+// [JsStrategy] is the default.
+class KernelToElementMapForImpactImpl2 extends KernelToElementMapBase
+ with
+ KernelToElementMapForImpactMixin,
+ KernelToElementMapForImpactImpl,
+ KElementCreatorMixin {
+ KernelToElementMapForImpactImpl2(
+ DiagnosticReporter reporter, Environment environment)
+ : super(reporter, environment);
+}
- int _getHierarchyDepth(KClass cls) {
- _KClassEnv env = _classEnvs[cls.classIndex];
- _ensureSupertypes(cls, env);
- return env.orderedTypeSet.maxDepth;
- }
+/// Element builder used for creating elements and types corresponding to Kernel
+/// IR nodes.
+// TODO(johnniwinther): Use this in the JsStrategy
+class KernelToElementMapForBuildingImpl extends KernelToElementMapBase
+ with KernelToElementMapForBuildingMixin, KElementCreatorMixin
+ implements KernelToWorldBuilder {
+ KernelToElementMapForBuildingImpl(
+ DiagnosticReporter reporter, Environment environment)
+ : super(reporter, environment);
- Iterable<InterfaceType> _getInterfaces(KClass cls) {
- _KClassEnv env = _classEnvs[cls.classIndex];
- _ensureSupertypes(cls, env);
- return env.interfaces;
+ ConstantEnvironment get constantEnvironment => _constantEnvironment;
+
+ @override
+ ConstantValue getFieldConstantValue(ir.Field field) {
+ // TODO(johnniwinther): Cache the result in [FieldData].
+ return getConstantValue(field.initializer,
+ requireConstant: field.isConst, implicitNull: !field.isConst);
}
ir.Library getKernelLibrary(KLibrary entity) =>
@@ -775,12 +835,12 @@ class KernelToElementMapImpl extends KernelToElementMapForImpactImpl
ir.Class getKernelClass(KClass entity) => _classEnvs[entity.classIndex].cls;
bool hasConstantFieldInitializer(covariant KField field) {
- _FieldData data = _memberList[field.memberIndex];
+ FieldData data = _memberList[field.memberIndex];
return getFieldConstantValue(data.node) != null;
}
ConstantValue getConstantFieldInitializer(covariant KField field) {
- _FieldData data = _memberList[field.memberIndex];
+ FieldData data = _memberList[field.memberIndex];
ConstantValue value = getFieldConstantValue(data.node);
assert(value != null,
failedAt(field, "Field $field doesn't have a constant initial value."));
@@ -789,415 +849,37 @@ class KernelToElementMapImpl extends KernelToElementMapForImpactImpl
void forEachParameter(covariant KFunction function,
void f(DartType type, String name, ConstantValue defaultValue)) {
- _FunctionData data = _memberList[function.memberIndex];
+ FunctionData data = _memberList[function.memberIndex];
data.forEachParameter(this, f);
}
- ResolutionImpact computeWorldImpact(KMember member) {
- return _memberList[member.memberIndex].getWorldImpact(this);
- }
-
@override
Spannable getSpannable(MemberEntity member, ir.Node node) {
- return member;
+ return _getSpannable(member, node);
}
@override
- ir.Member getMemberNode(covariant KMember member) {
- return _memberList[member.memberIndex].node;
- }
-
- /// Returns the kernel IR node that defines the [cls].
- ir.Class getClassNode(KClass cls) {
- return _classEnvs[cls.classIndex].cls;
- }
-}
-
-/// Environment for fast lookup of program libraries.
-class _KEnv {
- final Set<ir.Program> programs = new Set<ir.Program>();
-
- Map<Uri, _KLibraryEnv> _libraryMap;
-
- /// TODO(johnniwinther): Handle arbitrary load order if needed.
- ir.Member get mainMethod => programs.first?.mainMethod;
-
- void addProgram(ir.Program program) {
- if (programs.add(program)) {
- if (_libraryMap != null) {
- _addLibraries(program);
- }
- }
- }
-
- void _addLibraries(ir.Program program) {
- for (ir.Library library in program.libraries) {
- _libraryMap[library.importUri] = new _KLibraryEnv(library);
- }
- }
-
- void _ensureLibraryMap() {
- if (_libraryMap == null) {
- _libraryMap = <Uri, _KLibraryEnv>{};
- for (ir.Program program in programs) {
- _addLibraries(program);
- }
- }
- }
-
- /// Return the [_KLibraryEnv] for the library with the canonical [uri].
- _KLibraryEnv lookupLibrary(Uri uri) {
- _ensureLibraryMap();
- return _libraryMap[uri];
- }
-
- /// Calls [f] for each library in this environment.
- void forEachLibrary(void f(_KLibraryEnv library)) {
- _ensureLibraryMap();
- _libraryMap.values.forEach(f);
- }
-
- /// Returns the number of libraries in this environment.
- int get length {
- _ensureLibraryMap();
- return _libraryMap.length;
- }
-}
-
-/// Environment for fast lookup of library classes and members.
-class _KLibraryEnv {
- final ir.Library library;
-
- Map<String, _KClassEnv> _classMap;
- Map<String, ir.Member> _memberMap;
- Map<String, ir.Member> _setterMap;
-
- _KLibraryEnv(this.library);
-
- void _ensureClassMap() {
- if (_classMap == null) {
- _classMap = <String, _KClassEnv>{};
- for (ir.Class cls in library.classes) {
- _classMap[cls.name] = new _KClassEnv(cls);
- }
- }
- }
-
- /// Return the [_KClassEnv] for the class [name] in [library].
- _KClassEnv lookupClass(String name) {
- _ensureClassMap();
- return _classMap[name];
- }
-
- /// Calls [f] for each class in this library.
- void forEachClass(void f(_KClassEnv cls)) {
- _ensureClassMap();
- _classMap.values.forEach(f);
- }
-
- void _ensureMemberMaps() {
- if (_memberMap == null) {
- _memberMap = <String, ir.Member>{};
- _setterMap = <String, ir.Member>{};
- for (ir.Member member in library.members) {
- if (member is ir.Procedure) {
- if (member.kind == ir.ProcedureKind.Setter) {
- _setterMap[member.name.name] = member;
- } else {
- _memberMap[member.name.name] = member;
- }
- } else if (member is ir.Field) {
- _memberMap[member.name.name] = member;
- if (member.isMutable) {
- _setterMap[member.name.name] = member;
- }
- } else {
- throw new SpannableAssertionFailure(
- NO_LOCATION_SPANNABLE, "Unexpected library member node: $member");
- }
- }
- }
- }
-
- /// Return the [ir.Member] for the member [name] in [library].
- ir.Member lookupMember(String name, {bool setter: false}) {
- _ensureMemberMaps();
- return setter ? _setterMap[name] : _memberMap[name];
- }
-
- void forEachMember(void f(ir.Member member)) {
- _ensureMemberMaps();
- _memberMap.values.forEach(f);
- for (ir.Member member in _setterMap.values) {
- if (member is ir.Procedure) {
- f(member);
- } else {
- // Skip fields; these are also in _memberMap.
- }
- }
- }
-}
-
-/// Environment for fast lookup of class members.
-class _KClassEnv {
- final ir.Class cls;
- bool isMixinApplication;
- final bool isUnnamedMixinApplication;
-
- InterfaceType thisType;
- InterfaceType rawType;
- InterfaceType supertype;
- InterfaceType mixedInType;
- List<InterfaceType> interfaces;
- OrderedTypeSet orderedTypeSet;
-
- Map<String, ir.Member> _constructorMap;
- Map<String, ir.Member> _memberMap;
- Map<String, ir.Member> _setterMap;
-
- Iterable<ConstantValue> _metadata;
-
- _KClassEnv(this.cls)
- // TODO(johnniwinther): Change this to use a property on [cls] when such
- // is added to kernel.
- : isUnnamedMixinApplication =
- cls.name.contains('+') || cls.name.contains('&');
-
- /// Copied from 'package:kernel/transformations/mixin_full_resolution.dart'.
- ir.Constructor _buildForwardingConstructor(
- CloneVisitor cloner, ir.Constructor superclassConstructor) {
- var superFunction = superclassConstructor.function;
-
- // We keep types and default values for the parameters but always mark the
- // parameters as final (since we just forward them to the super
- // constructor).
- ir.VariableDeclaration cloneVariable(ir.VariableDeclaration variable) {
- ir.VariableDeclaration clone = cloner.clone(variable);
- clone.isFinal = true;
- return clone;
- }
-
- // Build a [FunctionNode] which has the same parameters as the one in the
- // superclass constructor.
- var positionalParameters =
- superFunction.positionalParameters.map(cloneVariable).toList();
- var namedParameters =
- superFunction.namedParameters.map(cloneVariable).toList();
- var function = new ir.FunctionNode(new ir.EmptyStatement(),
- positionalParameters: positionalParameters,
- namedParameters: namedParameters,
- requiredParameterCount: superFunction.requiredParameterCount,
- returnType: const ir.VoidType());
-
- // Build a [SuperInitializer] which takes all positional/named parameters
- // and forward them to the super class constructor.
- var positionalArguments = <ir.Expression>[];
- for (var variable in positionalParameters) {
- positionalArguments.add(new ir.VariableGet(variable));
- }
- var namedArguments = <ir.NamedExpression>[];
- for (var variable in namedParameters) {
- namedArguments.add(
- new ir.NamedExpression(variable.name, new ir.VariableGet(variable)));
- }
- var superInitializer = new ir.SuperInitializer(superclassConstructor,
- new ir.Arguments(positionalArguments, named: namedArguments));
-
- // Assemble the constructor.
- return new ir.Constructor(function,
- name: superclassConstructor.name,
- initializers: <ir.Initializer>[superInitializer]);
- }
-
- void _ensureMaps() {
- if (_memberMap == null) {
- _memberMap = <String, ir.Member>{};
- _setterMap = <String, ir.Member>{};
- _constructorMap = <String, ir.Member>{};
-
- void addMembers(ir.Class c, {bool includeStatic}) {
- for (ir.Member member in c.members) {
- if (member is ir.Constructor ||
- member is ir.Procedure &&
- member.kind == ir.ProcedureKind.Factory) {
- if (!includeStatic) continue;
- _constructorMap[member.name.name] = member;
- } else if (member is ir.Procedure) {
- if (!includeStatic && member.isStatic) continue;
- if (member.kind == ir.ProcedureKind.Setter) {
- _setterMap[member.name.name] = member;
- } else {
- _memberMap[member.name.name] = member;
- }
- } else if (member is ir.Field) {
- if (!includeStatic && member.isStatic) continue;
- _memberMap[member.name.name] = member;
- if (member.isMutable) {
- _setterMap[member.name.name] = member;
- }
- _memberMap[member.name.name] = member;
- } else {
- throw new SpannableAssertionFailure(
- NO_LOCATION_SPANNABLE, "Unexpected class member node: $member");
- }
- }
- }
-
- if (cls.mixedInClass != null) {
- addMembers(cls.mixedInClass, includeStatic: false);
- }
- addMembers(cls, includeStatic: true);
-
- if (isUnnamedMixinApplication && _constructorMap.isEmpty) {
- // Unnamed mixin applications have no constructors when read from .dill.
- // For each generative constructor in the superclass we make a
- // corresponding forwarding constructor in the subclass.
- //
- // This code is copied from
- // 'package:kernel/transformations/mixin_full_resolution.dart'
- var superclassSubstitution = getSubstitutionMap(cls.supertype);
- var superclassCloner =
- new CloneVisitor(typeSubstitution: superclassSubstitution);
- for (var superclassConstructor in cls.superclass.constructors) {
- var forwardingConstructor = _buildForwardingConstructor(
- superclassCloner, superclassConstructor);
- cls.addMember(forwardingConstructor);
- _constructorMap[forwardingConstructor.name.name] =
- forwardingConstructor;
- }
- }
- }
- }
-
- /// Return the [ir.Member] for the member [name] in [library].
- ir.Member lookupMember(String name, {bool setter: false}) {
- _ensureMaps();
- return setter ? _setterMap[name] : _memberMap[name];
- }
-
- /// Return the [ir.Member] for the member [name] in [library].
- ir.Member lookupConstructor(String name) {
- _ensureMaps();
- return _constructorMap[name];
- }
-
- void forEachMember(void f(ir.Member member)) {
- _ensureMaps();
- _memberMap.values.forEach(f);
- for (ir.Member member in _setterMap.values) {
- if (member is ir.Procedure) {
- f(member);
- } else {
- // Skip fields; these are also in _memberMap.
- }
- }
- }
-
- void forEachConstructor(void f(ir.Member member)) {
- _ensureMaps();
- _constructorMap.values.forEach(f);
- }
-
- Iterable<ConstantValue> getMetadata(KernelToElementMapImpl elementMap) {
- return _metadata ??= elementMap.getMetadata(cls.annotations);
- }
-}
-
-class _MemberData {
- final ir.Member node;
- Iterable<ConstantValue> _metadata;
-
- _MemberData(this.node);
-
- ResolutionImpact getWorldImpact(KernelToElementMapImpl elementMap) {
- return buildKernelImpact(node, elementMap);
- }
-
- Iterable<ConstantValue> getMetadata(KernelToElementMapImpl elementMap) {
- return _metadata ??= elementMap.getMetadata(node.annotations);
- }
-}
-
-class _FunctionData extends _MemberData {
- final ir.FunctionNode functionNode;
- FunctionType _type;
-
- _FunctionData(ir.Member node, this.functionNode) : super(node);
-
- FunctionType getFunctionType(KernelToElementMapImpl elementMap) {
- return _type ??= elementMap.getFunctionType(functionNode);
- }
-
- void forEachParameter(KernelToElementMapForBuilding elementMap,
- void f(DartType type, String name, ConstantValue defaultValue)) {
- void handleParameter(ir.VariableDeclaration node, {bool isOptional: true}) {
- DartType type = elementMap.getDartType(node.type);
- String name = node.name;
- ConstantValue defaultValue;
- if (isOptional) {
- if (node.initializer != null) {
- defaultValue = elementMap.getConstantValue(node.initializer);
- } else {
- defaultValue = new NullConstantValue();
- }
- }
- f(type, name, defaultValue);
- }
-
- for (int i = 0; i < functionNode.positionalParameters.length; i++) {
- handleParameter(functionNode.positionalParameters[i],
- isOptional: i < functionNode.requiredParameterCount);
- }
- functionNode.namedParameters.toList()
- ..sort(namedOrdering)
- ..forEach(handleParameter);
+ ir.Member getMemberNode(MemberEntity member) {
+ return _getMemberNode(member);
}
-}
-
-class _ConstructorData extends _FunctionData {
- ConstantConstructor _constantConstructor;
-
- _ConstructorData(ir.Member node, ir.FunctionNode functionNode)
- : super(node, functionNode);
- ConstantConstructor getConstructorConstant(
- KernelToElementMapImpl elementMap, KConstructor constructor) {
- if (_constantConstructor == null) {
- if (node is ir.Constructor && constructor.isConst) {
- _constantConstructor =
- new Constantifier(elementMap).computeConstantConstructor(node);
- } else {
- throw new SpannableAssertionFailure(
- constructor,
- "Unexpected constructor $constructor in "
- "KernelWorldBuilder._getConstructorConstant");
- }
- }
- return _constantConstructor;
+ @override
+ ir.Class getClassNode(ClassEntity cls) {
+ return _getClassNode(cls);
}
}
-class _FieldData extends _MemberData {
- ConstantExpression _constant;
-
- _FieldData(ir.Field node) : super(node);
-
- ir.Field get node => super.node;
-
- ConstantExpression getFieldConstant(
- KernelToElementMapImpl elementMap, KField field) {
- if (_constant == null) {
- if (node.isConst) {
- _constant = new Constantifier(elementMap).visit(node.initializer);
- } else {
- throw new SpannableAssertionFailure(
- field,
- "Unexpected field $field in "
- "KernelWorldBuilder._getConstructorConstant");
- }
- }
- return _constant;
- }
+/// [KernelToElementMap] implementation used for both world impact computation
+/// and SSA building.
+// TODO(johnniwinther): Remove this when [JsStrategy] is the default.
+class KernelToElementMapImpl extends KernelToElementMapForBuildingImpl
+ with
+ KernelToElementMapForImpactMixin,
+ KernelToElementMapForImpactImpl,
+ KElementCreatorMixin
+ implements KernelToElementMapForImpactImpl2 {
+ KernelToElementMapImpl(DiagnosticReporter reporter, Environment environment)
+ : super(reporter, environment);
}
class KernelElementEnvironment implements ElementEnvironment {
@@ -1393,7 +1075,7 @@ class KernelElementEnvironment implements ElementEnvironment {
@override
Iterable<ConstantValue> getMemberMetadata(covariant KMember member) {
- _MemberData memberData = elementMap._memberList[member.memberIndex];
+ MemberData memberData = elementMap._memberList[member.memberIndex];
return memberData.getMetadata(elementMap);
}
}
@@ -1566,7 +1248,7 @@ class _EvaluationEnvironment implements EvaluationEnvironment {
}
class KernelResolutionWorldBuilder extends KernelResolutionWorldBuilderBase {
- final KernelToElementMapImpl elementMap;
+ final KernelToElementMapForImpactImpl elementMap;
KernelResolutionWorldBuilder(
this.elementMap,
@@ -1620,7 +1302,7 @@ class KernelResolutionWorldBuilder extends KernelResolutionWorldBuilderBase {
}
class KernelClosedWorld extends ClosedWorldBase {
- final KernelToElementMapImpl _elementMap;
+ final KernelToElementMapForImpactImpl _elementMap;
KernelClosedWorld(this._elementMap,
{ElementEnvironment elementEnvironment,
@@ -1724,12 +1406,12 @@ class KernelClosedWorld extends ClosedWorldBase {
// Interface for testing equivalence of Kernel-based entities.
class WorldDeconstructionForTesting {
- final KernelToElementMapImpl elementMap;
+ final KernelToElementMapBase elementMap;
WorldDeconstructionForTesting(this.elementMap);
KClass getSuperclassForClass(KClass cls) {
- _KClassEnv env = elementMap._classEnvs[cls.classIndex];
+ ClassEnv env = elementMap._classEnvs[cls.classIndex];
ir.Supertype supertype = env.cls.supertype;
if (supertype == null) return null;
return elementMap.getClass(supertype.classNode);
@@ -1740,7 +1422,7 @@ class WorldDeconstructionForTesting {
}
InterfaceType getMixinTypeForClass(KClass cls) {
- _KClassEnv env = elementMap._classEnvs[cls.classIndex];
+ ClassEnv env = elementMap._classEnvs[cls.classIndex];
ir.Supertype mixedInType = env.cls.mixedInType;
if (mixedInType == null) return null;
return elementMap.createInterfaceType(
@@ -1749,7 +1431,7 @@ class WorldDeconstructionForTesting {
}
class KernelNativeMemberResolver extends NativeMemberResolverBase {
- final KernelToElementMapImpl elementMap;
+ final KernelToElementMapForImpactImpl elementMap;
final NativeBasicData nativeBasicData;
final NativeDataBuilder nativeDataBuilder;
@@ -1807,7 +1489,7 @@ class JsKernelToElementMap extends KernelToElementMapBase
final JsToFrontendMap _map;
final ElementEnvironment _elementEnvironment;
final CommonElements _commonElements;
- final KernelToElementMapImpl _elementMap;
+ final KernelToElementMapForImpactImpl _elementMap;
JsKernelToElementMap(
DiagnosticReporter reporter,
@@ -1820,54 +1502,56 @@ class JsKernelToElementMap extends KernelToElementMapBase
@override
Spannable getSpannable(MemberEntity member, ir.Node node) {
- return _elementMap.getSpannable(_map.toFrontendMember(member), node);
+ return _elementMap._getSpannable(_map.toFrontendMember(member), node);
+ }
+
+ Iterable<LibraryEntity> get _libraries {
+ return _elementMap._libraries.map(_map.toBackendLibrary);
}
@override
- LibraryEntity getLibrary(ir.Library node) {
+ LibraryEntity _getLibrary(ir.Library node, [LibraryEnv env]) {
return _map.toBackendLibrary(_elementMap.getLibrary(node));
}
@override
- Local getLocalFunction(ir.TreeNode node) {
+ Local _getLocalFunction(ir.TreeNode node) {
throw new UnsupportedError("JsKernelToElementMap.getLocalFunction");
}
@override
- ClassEntity getClass(ir.Class node) {
+ ClassEntity _getClass(ir.Class node, [ClassEnv env]) {
return _map.toBackendClass(_elementMap.getClass(node));
}
@override
- FieldEntity getField(ir.Field node) {
- return _map.toBackendMember(_elementMap.getField(node));
+ TypeVariableEntity _getTypeVariable(ir.TypeParameter node) {
+ throw new UnsupportedError("JsKernelToElementMap._getTypeVariable");
}
@override
- MemberEntity getSuperMember(ir.Member context, ir.Name name, ir.Member target,
- {bool setter: false}) {
- return _map.toBackendMember(
- _elementMap.getSuperMember(context, name, target, setter: setter));
+ FieldEntity _getField(ir.Field node) {
+ return _map.toBackendMember(_elementMap.getField(node));
}
@override
- FunctionEntity getMethod(ir.Procedure node) {
+ FunctionEntity _getMethod(ir.Procedure node) {
return _map.toBackendMember(_elementMap.getMethod(node));
}
@override
- ir.Member getMemberNode(MemberEntity member) {
- return _elementMap.getMemberNode(_map.toFrontendMember(member));
+ ConstructorEntity _getConstructor(ir.Member node) {
+ return _map.toBackendMember(_elementMap.getConstructor(node));
}
@override
- MemberEntity getMember(ir.Member node) {
- return _map.toBackendMember(_elementMap.getMember(node));
+ ir.Member getMemberNode(MemberEntity member) {
+ return _elementMap._getMemberNode(_map.toFrontendMember(member));
}
@override
- ConstructorEntity getConstructor(ir.Member node) {
- return _map.toBackendMember(_elementMap.getConstructor(node));
+ ir.Class getClassNode(ClassEntity cls) {
+ return _elementMap._getClassNode(_map.toFrontendClass(cls));
}
@override
« no previous file with comments | « pkg/compiler/lib/src/kernel/element_map.dart ('k') | pkg/compiler/lib/src/kernel/element_map_mixins.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698