| 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 35c5ca186372c6ab6c6fb0130ba46070a1efaca7..fc663e4fd02d2c885c3808680ae67f60ed7ae59d 100644
|
| --- a/pkg/compiler/lib/src/kernel/element_map_impl.dart
|
| +++ b/pkg/compiler/lib/src/kernel/element_map_impl.dart
|
| @@ -62,21 +62,12 @@ abstract class KernelToWorldBuilder implements KernelToElementMapForBuilding {
|
| void f(DartType type, String name, ConstantValue defaultValue));
|
| }
|
|
|
| -abstract class KernelToElementMapBase extends KernelToElementMapBaseMixin {}
|
| -
|
| -/// Element builder used for creating elements and types corresponding to Kernel
|
| -/// IR nodes.
|
| -class KernelToElementMapImpl extends KernelToElementMapBase
|
| - with KernelToElementMapForBuildingMixin, KernelToElementMapForImpactMixin
|
| - implements KernelToWorldBuilder {
|
| - final Environment _environment;
|
| - CommonElements _commonElements;
|
| - native.BehaviorBuilder _nativeBehaviorBuilder;
|
| +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();
|
| @@ -103,22 +94,18 @@ class KernelToElementMapImpl extends KernelToElementMapBase
|
| Map<ir.TreeNode, KLocalFunction> _localFunctionMap =
|
| <ir.TreeNode, KLocalFunction>{};
|
|
|
| - KernelToElementMapImpl(this.reporter, this._environment) {
|
| + KernelToElementMapBase(this.reporter, Environment environment) {
|
| _elementEnvironment = new KernelElementEnvironment(this);
|
| _commonElements = new CommonElements(_elementEnvironment);
|
| - _constantEnvironment = new KernelConstantEnvironment(this);
|
| - _nativeBehaviorBuilder = new KernelBehaviorBuilder(_commonElements);
|
| - _types = new _KernelDartTypes(this);
|
| + _constantEnvironment = new KernelConstantEnvironment(this, environment);
|
| _typeConverter = new DartTypeConverter(this);
|
| }
|
|
|
| - /// Adds libraries in [program] to the set of libraries.
|
| - ///
|
| - /// The main method of the first program is used as the main method for the
|
| - /// compilation.
|
| - void addProgram(ir.Program program) {
|
| - _env.addProgram(program);
|
| - }
|
| + @override
|
| + ElementEnvironment get elementEnvironment => _elementEnvironment;
|
| +
|
| + @override
|
| + CommonElements get commonElements => _commonElements;
|
|
|
| KMethod get _mainFunction {
|
| return _env.mainMethod != null ? _getMethod(_env.mainMethod) : null;
|
| @@ -140,52 +127,12 @@ class KernelToElementMapImpl extends KernelToElementMapBase
|
| return _libraryMap.values;
|
| }
|
|
|
| - @override
|
| - CommonElements get commonElements => _commonElements;
|
| -
|
| - @override
|
| - ElementEnvironment get elementEnvironment => _elementEnvironment;
|
| -
|
| - ConstantEnvironment get constantEnvironment => _constantEnvironment;
|
| -
|
| - DartTypes get types => _types;
|
| -
|
| - @override
|
| - native.BehaviorBuilder get nativeBehaviorBuilder => _nativeBehaviorBuilder;
|
| -
|
| - @override
|
| - ConstantValue computeConstantValue(ConstantExpression constant,
|
| - {bool requireConstant: true}) {
|
| - return _constantEnvironment.getConstantValue(constant);
|
| - }
|
| -
|
| - @override
|
| - ConstantValue getFieldConstantValue(ir.Field field) {
|
| - // TODO(johnniwinther): Cache the result in [_FieldData].
|
| - return getConstantValue(field.initializer,
|
| - requireConstant: field.isConst, implicitNull: !field.isConst);
|
| - }
|
| -
|
| LibraryEntity lookupLibrary(Uri uri) {
|
| _KLibraryEnv libraryEnv = _env.lookupLibrary(uri);
|
| if (libraryEnv == null) return null;
|
| return _getLibrary(libraryEnv.library, libraryEnv);
|
| }
|
|
|
| - 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);
|
| - });
|
| - }
|
| -
|
| String _getLibraryName(KLibrary library) {
|
| _KLibraryEnv libraryEnv = _libraryEnvs[library.libraryIndex];
|
| return libraryEnv.library.name ?? '';
|
| @@ -236,6 +183,31 @@ class KernelToElementMapImpl extends KernelToElementMapBase
|
| return member != null ? getConstructor(member) : null;
|
| }
|
|
|
| + @override
|
| + InterfaceType createInterfaceType(
|
| + ir.Class cls, List<ir.DartType> typeArguments) {
|
| + return new InterfaceType(getClass(cls), getDartTypes(typeArguments));
|
| + }
|
| +
|
| + 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);
|
| + });
|
| + }
|
| +
|
| + @override
|
| + ClassEntity getClass(ir.Class node) => _getClass(node);
|
| +
|
| KClass _getClass(ir.Class node, [_KClassEnv classEnv]) {
|
| return _classMap.putIfAbsent(node, () {
|
| KLibrary library = _getLibrary(node.enclosingLibrary);
|
| @@ -248,10 +220,39 @@ class KernelToElementMapImpl extends KernelToElementMapBase
|
| });
|
| }
|
|
|
| - Iterable<ConstantValue> _getClassMetadata(KClass cls) {
|
| - return _classEnvs[cls.classIndex].getMetadata(this);
|
| + InterfaceType _getSuperType(KClass cls) {
|
| + _KClassEnv env = _classEnvs[cls.classIndex];
|
| + _ensureSupertypes(cls, env);
|
| + return env.supertype;
|
| }
|
|
|
| + void _ensureThisAndRawType(KClass cls, _KClassEnv env) {
|
| + if (env.thisType == null) {
|
| + ir.Class node = env.cls;
|
| + // TODO(johnniwinther): Add the type argument to the list literal when we
|
| + // no longer use resolution types.
|
| + if (node.typeParameters.isEmpty) {
|
| + env.thisType =
|
| + env.rawType = new InterfaceType(cls, const/*<DartType>*/ []);
|
| + } else {
|
| + env.thisType = new InterfaceType(
|
| + cls,
|
| + new List/*<DartType>*/ .generate(node.typeParameters.length,
|
| + (int index) {
|
| + return new TypeVariableType(
|
| + _getTypeVariable(node.typeParameters[index]));
|
| + }));
|
| + env.rawType = new InterfaceType(
|
| + cls,
|
| + new List/*<DartType>*/ .filled(
|
| + node.typeParameters.length, const DynamicType()));
|
| + }
|
| + }
|
| + }
|
| +
|
| + TypeVariableEntity getTypeVariable(ir.TypeParameter node) =>
|
| + _getTypeVariable(node);
|
| +
|
| KTypeVariable _getTypeVariable(ir.TypeParameter node) {
|
| return _typeVariableMap.putIfAbsent(node, () {
|
| if (node.parent is ir.Class) {
|
| @@ -281,16 +282,86 @@ class KernelToElementMapImpl extends KernelToElementMapBase
|
| });
|
| }
|
|
|
| - 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);
|
| + void _ensureSupertypes(KClass cls, _KClassEnv env) {
|
| + if (env.orderedTypeSet == null) {
|
| + _ensureThisAndRawType(cls, env);
|
| +
|
| + ir.Class node = env.cls;
|
| +
|
| + if (node.supertype == null) {
|
| + env.orderedTypeSet = new OrderedTypeSet.singleton(env.thisType);
|
| + env.isMixinApplication = false;
|
| + env.interfaces = const <InterfaceType>[];
|
| + } else {
|
| + InterfaceType processSupertype(ir.Supertype node) {
|
| + InterfaceType type = _typeConverter.visitSupertype(node);
|
| + KClass superclass = type.element;
|
| + _KClassEnv env = _classEnvs[superclass.classIndex];
|
| + _ensureSupertypes(superclass, env);
|
| + return type;
|
| + }
|
| +
|
| + env.supertype = processSupertype(node.supertype);
|
| + LinkBuilder<InterfaceType> linkBuilder =
|
| + new LinkBuilder<InterfaceType>();
|
| + if (node.mixedInType != null) {
|
| + env.isMixinApplication = true;
|
| + linkBuilder
|
| + .addLast(env.mixedInType = processSupertype(node.mixedInType));
|
| + } else {
|
| + env.isMixinApplication = false;
|
| + }
|
| + node.implementedTypes.forEach((ir.Supertype supertype) {
|
| + linkBuilder.addLast(processSupertype(supertype));
|
| + });
|
| + Link<InterfaceType> interfaces = linkBuilder.toLink();
|
| + OrderedTypeSetBuilder setBuilder =
|
| + new _KernelOrderedTypeSetBuilder(this, cls);
|
| + env.orderedTypeSet =
|
| + setBuilder.createOrderedTypeSet(env.supertype, interfaces);
|
| + env.interfaces = new List<InterfaceType>.from(interfaces.toList());
|
| + }
|
| + }
|
| + }
|
| +
|
| + @override
|
| + MemberEntity getMember(ir.Member node) {
|
| + if (node is ir.Field) {
|
| + return _getField(node);
|
| + } else if (node is ir.Constructor) {
|
| + return _getConstructor(node);
|
| + } else if (node is ir.Procedure) {
|
| + if (node.kind == ir.ProcedureKind.Factory) {
|
| + return _getConstructor(node);
|
| + } else {
|
| + return _getMethod(node);
|
| + }
|
| + }
|
| + throw new UnsupportedError("Unexpected member: $node");
|
| }
|
|
|
| + MemberEntity getSuperMember(ir.Member context, ir.Name name, ir.Member target,
|
| + {bool setter: false}) {
|
| + if (target != null) {
|
| + return getMember(target);
|
| + }
|
| + KClass cls = getMember(context).enclosingClass;
|
| + KClass superclass = _getSuperType(cls)?.element;
|
| + while (superclass != null) {
|
| + _KClassEnv env = _classEnvs[superclass.classIndex];
|
| + ir.Member superMember = env.lookupMember(name.name, setter: setter);
|
| + if (superMember != null) {
|
| + return getMember(superMember);
|
| + }
|
| + superclass = _getSuperType(superclass)?.element;
|
| + }
|
| + throw new SpannableAssertionFailure(
|
| + cls, "No super method member found for ${name} in $cls.");
|
| + }
|
| +
|
| + @override
|
| + ConstructorEntity getConstructor(ir.Member node) => _getConstructor(node);
|
| +
|
| KConstructor _getConstructor(ir.Member node) {
|
| return _constructorMap.putIfAbsent(node, () {
|
| int memberIndex = _memberList.length;
|
| @@ -325,6 +396,28 @@ class KernelToElementMapImpl extends KernelToElementMapBase
|
| });
|
| }
|
|
|
| + 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;
|
| + if (superClass == targetClass) {
|
| + return target;
|
| + }
|
| + _KClassEnv env = _classEnvs[superClass.classIndex];
|
| + ir.Member member = env.lookupConstructor(target.name);
|
| + if (member != null) {
|
| + return getConstructor(member);
|
| + }
|
| + throw new SpannableAssertionFailure(
|
| + source, "Super constructor for $source not found.");
|
| + }
|
| +
|
| + @override
|
| + FunctionEntity getMethod(ir.Procedure node) => _getMethod(node);
|
| +
|
| KFunction _getMethod(ir.Procedure node) {
|
| return _methodMap.putIfAbsent(node, () {
|
| int memberIndex = _memberList.length;
|
| @@ -391,29 +484,8 @@ class KernelToElementMapImpl extends KernelToElementMapBase
|
| });
|
| }
|
|
|
| - MemberEntity getSuperMember(ir.Member context, ir.Name name, ir.Member target,
|
| - {bool setter: false}) {
|
| - if (target != null) {
|
| - return getMember(target);
|
| - }
|
| - KClass cls = getMember(context).enclosingClass;
|
| - KClass superclass = _getSuperType(cls)?.element;
|
| - while (superclass != null) {
|
| - _KClassEnv env = _classEnvs[superclass.classIndex];
|
| - ir.Member superMember = env.lookupMember(name.name, setter: setter);
|
| - if (superMember != null) {
|
| - return getMember(superMember);
|
| - }
|
| - superclass = _getSuperType(superclass)?.element;
|
| - }
|
| - throw new SpannableAssertionFailure(
|
| - cls, "No super method member found for ${name} in $cls.");
|
| - }
|
| -
|
| - /// Returns the kernel [ir.Procedure] node for the [method].
|
| - ir.Procedure _lookupProcedure(KFunction method) {
|
| - return _memberList[method.memberIndex].node;
|
| - }
|
| + @override
|
| + FieldEntity getField(ir.Field node) => _getField(node);
|
|
|
| KField _getField(ir.Field node) {
|
| return _fieldMap.putIfAbsent(node, () {
|
| @@ -436,6 +508,19 @@ class KernelToElementMapImpl extends KernelToElementMapBase
|
| });
|
| }
|
|
|
| + 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);
|
| + }
|
| +
|
| + @override
|
| + Local getLocalFunction(ir.TreeNode node) => _getLocal(node);
|
| +
|
| KLocalFunction _getLocal(ir.TreeNode node) {
|
| return _localFunctionMap.putIfAbsent(node, () {
|
| MemberEntity memberContext;
|
| @@ -471,17 +556,6 @@ class KernelToElementMapImpl extends KernelToElementMapBase
|
| @override
|
| DartType getDartType(ir.DartType type) => _typeConverter.convert(type);
|
|
|
| - @override
|
| - InterfaceType createInterfaceType(
|
| - ir.Class cls, List<ir.DartType> typeArguments) {
|
| - return new InterfaceType(getClass(cls), getDartTypes(typeArguments));
|
| - }
|
| -
|
| - @override
|
| - InterfaceType getInterfaceType(ir.InterfaceType type) =>
|
| - _typeConverter.convert(type);
|
| -
|
| - @override
|
| List<DartType> getDartTypes(List<ir.DartType> types) {
|
| // TODO(johnniwinther): Add the type argument to the list literal when we
|
| // no longer use resolution types.
|
| @@ -492,28 +566,43 @@ class KernelToElementMapImpl extends KernelToElementMapBase
|
| return list;
|
| }
|
|
|
| - void _ensureThisAndRawType(KClass cls, _KClassEnv env) {
|
| - if (env.thisType == null) {
|
| - ir.Class node = env.cls;
|
| - // TODO(johnniwinther): Add the type argument to the list literal when we
|
| - // no longer use resolution types.
|
| - if (node.typeParameters.isEmpty) {
|
| - env.thisType =
|
| - env.rawType = new InterfaceType(cls, const/*<DartType>*/ []);
|
| + @override
|
| + InterfaceType getInterfaceType(ir.InterfaceType type) =>
|
| + _typeConverter.convert(type);
|
| +
|
| + @override
|
| + FunctionType getFunctionType(ir.FunctionNode node) {
|
| + DartType returnType = getDartType(node.returnType);
|
| + List<DartType> parameterTypes = /*<DartType>*/ [];
|
| + List<DartType> optionalParameterTypes = /*<DartType>*/ [];
|
| + for (ir.VariableDeclaration variable in node.positionalParameters) {
|
| + if (parameterTypes.length == node.requiredParameterCount) {
|
| + optionalParameterTypes.add(getDartType(variable.type));
|
| } else {
|
| - env.thisType = new InterfaceType(
|
| - cls,
|
| - new List/*<DartType>*/ .generate(node.typeParameters.length,
|
| - (int index) {
|
| - return new TypeVariableType(
|
| - _getTypeVariable(node.typeParameters[index]));
|
| - }));
|
| - env.rawType = new InterfaceType(
|
| - cls,
|
| - new List/*<DartType>*/ .filled(
|
| - node.typeParameters.length, const DynamicType()));
|
| + parameterTypes.add(getDartType(variable.type));
|
| }
|
| }
|
| + List<String> namedParameters = <String>[];
|
| + List<DartType> namedParameterTypes = /*<DartType>*/ [];
|
| + List<ir.VariableDeclaration> sortedNamedParameters =
|
| + node.namedParameters.toList()..sort((a, b) => a.name.compareTo(b.name));
|
| + for (ir.VariableDeclaration variable in sortedNamedParameters) {
|
| + namedParameters.add(variable.name);
|
| + namedParameterTypes.add(getDartType(variable.type));
|
| + }
|
| + return new FunctionType(returnType, parameterTypes, optionalParameterTypes,
|
| + namedParameters, namedParameterTypes);
|
| + }
|
| +
|
| + @override
|
| + ConstantValue computeConstantValue(ConstantExpression constant,
|
| + {bool requireConstant: true}) {
|
| + return _constantEnvironment.getConstantValue(constant);
|
| + }
|
| +
|
| + DartType _substByContext(DartType type, InterfaceType context) {
|
| + return type.subst(
|
| + context.typeArguments, _getThisType(context.element).typeArguments);
|
| }
|
|
|
| InterfaceType _getThisType(KClass cls) {
|
| @@ -528,68 +617,9 @@ class KernelToElementMapImpl extends KernelToElementMapBase
|
| return env.rawType;
|
| }
|
|
|
| - 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;
|
| - }
|
| -
|
| - void _ensureSupertypes(KClass cls, _KClassEnv env) {
|
| - if (env.orderedTypeSet == null) {
|
| - _ensureThisAndRawType(cls, env);
|
| -
|
| - ir.Class node = env.cls;
|
| -
|
| - if (node.supertype == null) {
|
| - env.orderedTypeSet = new OrderedTypeSet.singleton(env.thisType);
|
| - env.isMixinApplication = false;
|
| - env.interfaces = const <InterfaceType>[];
|
| - } else {
|
| - InterfaceType processSupertype(ir.Supertype node) {
|
| - InterfaceType type = _typeConverter.visitSupertype(node);
|
| - KClass superclass = type.element;
|
| - _KClassEnv env = _classEnvs[superclass.classIndex];
|
| - _ensureSupertypes(superclass, env);
|
| - return type;
|
| - }
|
| -
|
| - env.supertype = processSupertype(node.supertype);
|
| - LinkBuilder<InterfaceType> linkBuilder =
|
| - new LinkBuilder<InterfaceType>();
|
| - if (node.mixedInType != null) {
|
| - env.isMixinApplication = true;
|
| - linkBuilder
|
| - .addLast(env.mixedInType = processSupertype(node.mixedInType));
|
| - } else {
|
| - env.isMixinApplication = false;
|
| - }
|
| - node.implementedTypes.forEach((ir.Supertype supertype) {
|
| - linkBuilder.addLast(processSupertype(supertype));
|
| - });
|
| - Link<InterfaceType> interfaces = linkBuilder.toLink();
|
| - OrderedTypeSetBuilder setBuilder =
|
| - new _KernelOrderedTypeSetBuilder(this, cls);
|
| - env.orderedTypeSet =
|
| - setBuilder.createOrderedTypeSet(env.supertype, interfaces);
|
| - env.interfaces = new List<InterfaceType>.from(interfaces.toList());
|
| - }
|
| - }
|
| - }
|
| -
|
| - OrderedTypeSet _getOrderedTypeSet(KClass cls) {
|
| - _KClassEnv env = _classEnvs[cls.classIndex];
|
| - _ensureSupertypes(cls, env);
|
| - return env.orderedTypeSet;
|
| - }
|
| -
|
| - int _getHierarchyDepth(KClass cls) {
|
| - _KClassEnv env = _classEnvs[cls.classIndex];
|
| - _ensureSupertypes(cls, env);
|
| - return env.orderedTypeSet.maxDepth;
|
| + FunctionType _getFunctionType(KFunction function) {
|
| + _FunctionData data = _memberList[function.memberIndex];
|
| + return data.getFunctionType(this);
|
| }
|
|
|
| ClassEntity _getAppliedMixin(KClass cls) {
|
| @@ -598,17 +628,6 @@ class KernelToElementMapImpl extends KernelToElementMapBase
|
| return env.mixedInType?.element;
|
| }
|
|
|
| - DartType _substByContext(DartType type, InterfaceType context) {
|
| - return type.subst(
|
| - context.typeArguments, _getThisType(context.element).typeArguments);
|
| - }
|
| -
|
| - InterfaceType _getSuperType(KClass cls) {
|
| - _KClassEnv env = _classEnvs[cls.classIndex];
|
| - _ensureSupertypes(cls, env);
|
| - return env.supertype;
|
| - }
|
| -
|
| bool _isMixinApplication(KClass cls) {
|
| _KClassEnv env = _classEnvs[cls.classIndex];
|
| _ensureSupertypes(cls, env);
|
| @@ -621,12 +640,6 @@ class KernelToElementMapImpl extends KernelToElementMapBase
|
| return env.isUnnamedMixinApplication;
|
| }
|
|
|
| - Iterable<InterfaceType> _getInterfaces(KClass cls) {
|
| - _KClassEnv env = _classEnvs[cls.classIndex];
|
| - _ensureSupertypes(cls, env);
|
| - return env.interfaces;
|
| - }
|
| -
|
| void _forEachSupertype(KClass cls, void f(InterfaceType supertype)) {
|
| _KClassEnv env = _classEnvs[cls.classIndex];
|
| _ensureSupertypes(cls, env);
|
| @@ -663,123 +676,121 @@ class KernelToElementMapImpl extends KernelToElementMapBase
|
| }
|
| }
|
|
|
| - @override
|
| - FunctionType getFunctionType(ir.FunctionNode node) {
|
| - DartType returnType = getDartType(node.returnType);
|
| - List<DartType> parameterTypes = /*<DartType>*/ [];
|
| - List<DartType> optionalParameterTypes = /*<DartType>*/ [];
|
| - for (ir.VariableDeclaration variable in node.positionalParameters) {
|
| - if (parameterTypes.length == node.requiredParameterCount) {
|
| - optionalParameterTypes.add(getDartType(variable.type));
|
| - } else {
|
| - parameterTypes.add(getDartType(variable.type));
|
| - }
|
| - }
|
| - List<String> namedParameters = <String>[];
|
| - List<DartType> namedParameterTypes = /*<DartType>*/ [];
|
| - List<ir.VariableDeclaration> sortedNamedParameters =
|
| - node.namedParameters.toList()..sort((a, b) => a.name.compareTo(b.name));
|
| - for (ir.VariableDeclaration variable in sortedNamedParameters) {
|
| - namedParameters.add(variable.name);
|
| - namedParameterTypes.add(getDartType(variable.type));
|
| - }
|
| - return new FunctionType(returnType, parameterTypes, optionalParameterTypes,
|
| - namedParameters, namedParameterTypes);
|
| + ConstantConstructor _getConstructorConstant(KConstructor constructor) {
|
| + _ConstructorData data = _memberList[constructor.memberIndex];
|
| + return data.getConstructorConstant(this, constructor);
|
| }
|
|
|
| - LibraryEntity getLibrary(ir.Library node) => _getLibrary(node);
|
| -
|
| - ir.Library getKernelLibrary(KLibrary entity) =>
|
| - _libraryEnvs[entity.libraryIndex].library;
|
| + ConstantExpression _getFieldConstant(KField field) {
|
| + _FieldData data = _memberList[field.memberIndex];
|
| + return data.getFieldConstant(this, field);
|
| + }
|
| +}
|
|
|
| - ir.Class getKernelClass(KClass entity) => _classEnvs[entity.classIndex].cls;
|
| +class KernelToElementMapForImpactImpl extends KernelToElementMapBase
|
| + with KernelToElementMapForImpactMixin {
|
| + native.BehaviorBuilder _nativeBehaviorBuilder;
|
|
|
| - @override
|
| - Local getLocalFunction(ir.TreeNode node) => _getLocal(node);
|
| + KernelToElementMapForImpactImpl(
|
| + DiagnosticReporter reporter, Environment environment)
|
| + : super(reporter, environment) {
|
| + _nativeBehaviorBuilder = new KernelBehaviorBuilder(_commonElements);
|
| + }
|
|
|
| @override
|
| - ClassEntity getClass(ir.Class node) => _getClass(node);
|
| + native.BehaviorBuilder get nativeBehaviorBuilder => _nativeBehaviorBuilder;
|
| +}
|
|
|
| - @override
|
| - FieldEntity getField(ir.Field node) => _getField(node);
|
| +/// Element builder used for creating elements and types corresponding to Kernel
|
| +/// IR nodes.
|
| +class KernelToElementMapImpl extends KernelToElementMapForImpactImpl
|
| + with KernelToElementMapForBuildingMixin
|
| + implements KernelToWorldBuilder {
|
| + _KernelDartTypes _types;
|
|
|
| - bool hasConstantFieldInitializer(covariant KField field) {
|
| - _FieldData data = _memberList[field.memberIndex];
|
| - return getFieldConstantValue(data.node) != null;
|
| + KernelToElementMapImpl(DiagnosticReporter reporter, Environment environment)
|
| + : super(reporter, environment) {
|
| + _types = new _KernelDartTypes(this);
|
| }
|
|
|
| - ConstantValue getConstantFieldInitializer(covariant KField field) {
|
| - _FieldData data = _memberList[field.memberIndex];
|
| - ConstantValue value = getFieldConstantValue(data.node);
|
| - assert(value != null,
|
| - failedAt(field, "Field $field doesn't have a constant initial value."));
|
| - return value;
|
| + /// Adds libraries in [program] to the set of libraries.
|
| + ///
|
| + /// The main method of the first program is used as the main method for the
|
| + /// compilation.
|
| + void addProgram(ir.Program program) {
|
| + _env.addProgram(program);
|
| }
|
|
|
| - TypeVariableEntity getTypeVariable(ir.TypeParameter node) =>
|
| - _getTypeVariable(node);
|
| + ConstantEnvironment get constantEnvironment => _constantEnvironment;
|
| +
|
| + DartTypes get types => _types;
|
|
|
| @override
|
| - FunctionEntity getMethod(ir.Procedure node) => _getMethod(node);
|
| + ConstantValue getFieldConstantValue(ir.Field field) {
|
| + // TODO(johnniwinther): Cache the result in [_FieldData].
|
| + return getConstantValue(field.initializer,
|
| + requireConstant: field.isConst, implicitNull: !field.isConst);
|
| + }
|
|
|
| - void forEachParameter(covariant KFunction function,
|
| - void f(DartType type, String name, ConstantValue defaultValue)) {
|
| - _FunctionData data = _memberList[function.memberIndex];
|
| - data.forEachParameter(this, f);
|
| + Iterable<ConstantValue> _getClassMetadata(KClass cls) {
|
| + return _classEnvs[cls.classIndex].getMetadata(this);
|
| }
|
|
|
| - @override
|
| - MemberEntity getMember(ir.Member node) {
|
| - if (node is ir.Field) {
|
| - return _getField(node);
|
| - } else if (node is ir.Constructor) {
|
| - return _getConstructor(node);
|
| - } else if (node is ir.Procedure) {
|
| - if (node.kind == ir.ProcedureKind.Factory) {
|
| - return _getConstructor(node);
|
| - } else {
|
| - return _getMethod(node);
|
| - }
|
| + /// Returns the kernel [ir.Procedure] node for the [method].
|
| + ir.Procedure _lookupProcedure(KFunction method) {
|
| + 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);
|
| }
|
| - throw new UnsupportedError("Unexpected member: $node");
|
| + return supertype;
|
| }
|
|
|
| - @override
|
| - ConstructorEntity getConstructor(ir.Member node) => _getConstructor(node);
|
| + OrderedTypeSet _getOrderedTypeSet(KClass cls) {
|
| + _KClassEnv env = _classEnvs[cls.classIndex];
|
| + _ensureSupertypes(cls, env);
|
| + return env.orderedTypeSet;
|
| + }
|
|
|
| - @override
|
| - 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;
|
| - if (superClass == targetClass) {
|
| - return target;
|
| - }
|
| - _KClassEnv env = _classEnvs[superClass.classIndex];
|
| - ir.Member member = env.lookupConstructor(target.name);
|
| - if (member != null) {
|
| - return getConstructor(member);
|
| - }
|
| - throw new SpannableAssertionFailure(
|
| - source, "Super constructor for $source not found.");
|
| + int _getHierarchyDepth(KClass cls) {
|
| + _KClassEnv env = _classEnvs[cls.classIndex];
|
| + _ensureSupertypes(cls, env);
|
| + return env.orderedTypeSet.maxDepth;
|
| }
|
|
|
| - ConstantConstructor _getConstructorConstant(KConstructor constructor) {
|
| - _ConstructorData data = _memberList[constructor.memberIndex];
|
| - return data.getConstructorConstant(this, constructor);
|
| + Iterable<InterfaceType> _getInterfaces(KClass cls) {
|
| + _KClassEnv env = _classEnvs[cls.classIndex];
|
| + _ensureSupertypes(cls, env);
|
| + return env.interfaces;
|
| }
|
|
|
| - ConstantExpression _getFieldConstant(KField field) {
|
| + ir.Library getKernelLibrary(KLibrary entity) =>
|
| + _libraryEnvs[entity.libraryIndex].library;
|
| +
|
| + ir.Class getKernelClass(KClass entity) => _classEnvs[entity.classIndex].cls;
|
| +
|
| + bool hasConstantFieldInitializer(covariant KField field) {
|
| _FieldData data = _memberList[field.memberIndex];
|
| - return data.getFieldConstant(this, field);
|
| + return getFieldConstantValue(data.node) != null;
|
| }
|
|
|
| - FunctionType _getFunctionType(KFunction function) {
|
| + ConstantValue getConstantFieldInitializer(covariant KField field) {
|
| + _FieldData data = _memberList[field.memberIndex];
|
| + ConstantValue value = getFieldConstantValue(data.node);
|
| + assert(value != null,
|
| + failedAt(field, "Field $field doesn't have a constant initial value."));
|
| + return value;
|
| + }
|
| +
|
| + void forEachParameter(covariant KFunction function,
|
| + void f(DartType type, String name, ConstantValue defaultValue)) {
|
| _FunctionData data = _memberList[function.memberIndex];
|
| - return data.getFunctionType(this);
|
| + data.forEachParameter(this, f);
|
| }
|
|
|
| ResolutionImpact computeWorldImpact(KMember member) {
|
| @@ -1190,7 +1201,7 @@ class _FieldData extends _MemberData {
|
| }
|
|
|
| class KernelElementEnvironment implements ElementEnvironment {
|
| - final KernelToElementMapImpl elementMap;
|
| + final KernelToElementMapBase elementMap;
|
|
|
| KernelElementEnvironment(this.elementMap);
|
|
|
| @@ -1389,10 +1400,10 @@ class KernelElementEnvironment implements ElementEnvironment {
|
|
|
| /// Visitor that converts kernel dart types into [DartType].
|
| class DartTypeConverter extends ir.DartTypeVisitor<DartType> {
|
| - final KernelToElementMapImpl elementAdapter;
|
| + final KernelToElementMapBase elementMap;
|
| bool topLevel = true;
|
|
|
| - DartTypeConverter(this.elementAdapter);
|
| + DartTypeConverter(this.elementMap);
|
|
|
| DartType convert(ir.DartType type) {
|
| topLevel = true;
|
| @@ -1406,7 +1417,7 @@ class DartTypeConverter extends ir.DartTypeVisitor<DartType> {
|
| }
|
|
|
| InterfaceType visitSupertype(ir.Supertype node) {
|
| - ClassEntity cls = elementAdapter.getClass(node.classNode);
|
| + ClassEntity cls = elementMap.getClass(node.classNode);
|
| return new InterfaceType(cls, visitTypes(node.typeArguments));
|
| }
|
|
|
| @@ -1418,7 +1429,7 @@ class DartTypeConverter extends ir.DartTypeVisitor<DartType> {
|
|
|
| @override
|
| DartType visitTypeParameterType(ir.TypeParameterType node) {
|
| - return new TypeVariableType(elementAdapter.getTypeVariable(node.parameter));
|
| + return new TypeVariableType(elementMap.getTypeVariable(node.parameter));
|
| }
|
|
|
| @override
|
| @@ -1437,7 +1448,7 @@ class DartTypeConverter extends ir.DartTypeVisitor<DartType> {
|
|
|
| @override
|
| DartType visitInterfaceType(ir.InterfaceType node) {
|
| - ClassEntity cls = elementAdapter.getClass(node.classNode);
|
| + ClassEntity cls = elementMap.getClass(node.classNode);
|
| return new InterfaceType(cls, visitTypes(node.typeArguments));
|
| }
|
|
|
| @@ -1485,11 +1496,13 @@ class KernelBehaviorBuilder extends native.BehaviorBuilder {
|
| /// Constant environment mapping [ConstantExpression]s to [ConstantValue]s using
|
| /// [_EvaluationEnvironment] for the evaluation.
|
| class KernelConstantEnvironment implements ConstantEnvironment {
|
| - KernelToElementMapForBuilding _worldBuilder;
|
| + final KernelToElementMapBase _elementMap;
|
| + final Environment _environment;
|
| +
|
| Map<ConstantExpression, ConstantValue> _valueMap =
|
| <ConstantExpression, ConstantValue>{};
|
|
|
| - KernelConstantEnvironment(this._worldBuilder);
|
| + KernelConstantEnvironment(this._elementMap, this._environment);
|
|
|
| @override
|
| ConstantSystem get constantSystem => const JavaScriptConstantSystem();
|
| @@ -1504,7 +1517,8 @@ class KernelConstantEnvironment implements ConstantEnvironment {
|
| ConstantValue getConstantValue(ConstantExpression expression) {
|
| return _valueMap.putIfAbsent(expression, () {
|
| return expression.evaluate(
|
| - new _EvaluationEnvironment(_worldBuilder), constantSystem);
|
| + new _EvaluationEnvironment(_elementMap, _environment),
|
| + constantSystem);
|
| });
|
| }
|
|
|
| @@ -1517,9 +1531,10 @@ class KernelConstantEnvironment implements ConstantEnvironment {
|
| /// Evaluation environment used for computing [ConstantValue]s for
|
| /// kernel based [ConstantExpression]s.
|
| class _EvaluationEnvironment implements EvaluationEnvironment {
|
| - final KernelToElementMapImpl _elementMap;
|
| + final KernelToElementMapBase _elementMap;
|
| + final Environment _environment;
|
|
|
| - _EvaluationEnvironment(this._elementMap);
|
| + _EvaluationEnvironment(this._elementMap, this._environment);
|
|
|
| @override
|
| CommonElements get commonElements => _elementMap.commonElements;
|
| @@ -1546,7 +1561,7 @@ class _EvaluationEnvironment implements EvaluationEnvironment {
|
|
|
| @override
|
| String readFromEnvironment(String name) {
|
| - return _elementMap._environment.valueOf(name);
|
| + return _environment.valueOf(name);
|
| }
|
| }
|
|
|
| @@ -1794,8 +1809,14 @@ class JsKernelToElementMap extends KernelToElementMapBase
|
| final CommonElements _commonElements;
|
| final KernelToElementMapImpl _elementMap;
|
|
|
| - JsKernelToElementMap(this._map, this._elementEnvironment,
|
| - this._commonElements, this._elementMap);
|
| + JsKernelToElementMap(
|
| + DiagnosticReporter reporter,
|
| + Environment environment,
|
| + this._map,
|
| + this._elementEnvironment,
|
| + this._commonElements,
|
| + this._elementMap)
|
| + : super(reporter, environment);
|
|
|
| @override
|
| Spannable getSpannable(MemberEntity member, ir.Node node) {
|
|
|