Index: pkg/compiler/lib/src/universe/resolution_world_builder.dart |
diff --git a/pkg/compiler/lib/src/universe/resolution_world_builder.dart b/pkg/compiler/lib/src/universe/resolution_world_builder.dart |
index 7347bf30ab06261152cc1da41e468c8be855a0f2..cd2593ed383f7d8bd73dd1d639fa60d515e54818 100644 |
--- a/pkg/compiler/lib/src/universe/resolution_world_builder.dart |
+++ b/pkg/compiler/lib/src/universe/resolution_world_builder.dart |
@@ -7,39 +7,40 @@ part of world_builder; |
abstract class ResolutionWorldBuilder implements WorldBuilder, OpenWorld { |
/// Set of all local functions in the program. Used by the mirror tracking |
/// system to find all live closure instances. |
- Iterable<LocalFunctionElement> get localFunctions; |
+ Iterable<Local> get localFunctions; |
/// Set of (live) local functions (closures) whose signatures reference type |
/// variables. |
/// |
/// A live function is one whose enclosing member function has been enqueued. |
- Iterable<LocalFunctionElement> get localFunctionsWithFreeTypeVariables; |
+ Iterable<Local> get localFunctionsWithFreeTypeVariables; |
/// Set of methods in instantiated classes that are potentially closurized. |
- Iterable<MethodElement> get closurizedMembers; |
+ Iterable<FunctionEntity> get closurizedMembers; |
/// Set of live closurized members whose signatures reference type variables. |
/// |
/// A closurized method is considered live if the enclosing class has been |
/// instantiated. |
- Iterable<MethodElement> get closurizedMembersWithFreeTypeVariables; |
+ Iterable<FunctionEntity> get closurizedMembersWithFreeTypeVariables; |
/// Returns `true` if [cls] is considered to be implemented by an |
/// instantiated class, either directly, through subclasses or through |
/// subtypes. The latter case only contains spurious information from |
/// instantiations through factory constructors and mixins. |
- bool isImplemented(ClassElement cls); |
+ // TODO(johnniwinther): Improve semantic precision. |
+ bool isImplemented(ClassEntity cls); |
/// Set of all fields that are statically known to be written to. |
- Iterable<Element> get fieldSetters; |
+ Iterable<FieldEntity> get fieldSetters; |
/// Call [f] for all classes with instantiated types. This includes the |
/// directly and abstractly instantiated classes but also classes whose type |
/// arguments are used in live factory constructors. |
- void forEachInstantiatedClass(f(ClassElement cls, InstantiationInfo info)); |
+ void forEachInstantiatedClass(f(ClassEntity cls, InstantiationInfo info)); |
/// Returns `true` if [member] is invoked as a setter. |
- bool hasInvokedSetter(Element member); |
+ bool hasInvokedSetter(MemberEntity member); |
/// Returns `true` if [member] has been marked as used (called, read, etc.) in |
/// this world builder. |
@@ -93,7 +94,7 @@ abstract class ResolutionEnqueuerWorldBuilder extends ResolutionWorldBuilder { |
/// The type and kind of an instantiation registered through |
/// `ResolutionWorldBuilder.registerTypeInstantiation`. |
class Instance { |
- final ResolutionInterfaceType type; |
+ final InterfaceType type; |
final Instantiation kind; |
final bool isRedirection; |
@@ -191,13 +192,13 @@ class InstantiationInfo { |
/// |
/// If the constructor is unknown, for instance for native or mirror usage, |
/// `null` is used as key. |
- Map<ConstructorElement, Set<Instance>> instantiationMap; |
+ Map<ConstructorEntity, Set<Instance>> instantiationMap; |
/// Register [type] as the instantiation [kind] using [constructor]. |
- void addInstantiation(ConstructorElement constructor, |
- ResolutionInterfaceType type, Instantiation kind, |
+ void addInstantiation( |
+ ConstructorEntity constructor, InterfaceType type, Instantiation kind, |
{bool isRedirection: false}) { |
- instantiationMap ??= <ConstructorElement, Set<Instance>>{}; |
+ instantiationMap ??= <ConstructorEntity, Set<Instance>>{}; |
instantiationMap |
.putIfAbsent(constructor, () => new Set<Instance>()) |
.add(new Instance(type, kind, isRedirection: isRedirection)); |
@@ -231,7 +232,7 @@ class InstantiationInfo { |
if (instantiationMap != null) { |
bool needsComma = false; |
instantiationMap |
- .forEach((ConstructorElement constructor, Set<Instance> set) { |
+ .forEach((ConstructorEntity constructor, Set<Instance> set) { |
if (needsComma) { |
sb.write(', '); |
} |
@@ -250,29 +251,30 @@ class InstantiationInfo { |
} |
} |
-/// [ResolutionEnqueuerWorldBuilder] based on the [Element] model. |
-class ElementResolutionWorldBuilder implements ResolutionEnqueuerWorldBuilder { |
+/// Base implementation of [ResolutionEnqueuerWorldBuilder]. |
+abstract class ResolutionWorldBuilderBase |
+ implements ResolutionEnqueuerWorldBuilder { |
/// Instantiation information for all classes with instantiated types. |
/// |
/// Invariant: Elements are declaration elements. |
- final Map<ClassElement, InstantiationInfo> _instantiationInfo = |
- <ClassElement, InstantiationInfo>{}; |
+ final Map<ClassEntity, InstantiationInfo> _instantiationInfo = |
+ <ClassEntity, InstantiationInfo>{}; |
/// Classes implemented by directly instantiated classes. |
- final Set<ClassElement> _implementedClasses = new Set<ClassElement>(); |
+ final Set<ClassEntity> _implementedClasses = new Set<ClassEntity>(); |
/// The set of all referenced static fields. |
/// |
/// Invariant: Elements are declaration elements. |
- final Set<FieldElement> allReferencedStaticFields = new Set<FieldElement>(); |
+ final Set<FieldEntity> allReferencedStaticFields = new Set<FieldEntity>(); |
/** |
* Documentation wanted -- johnniwinther |
* |
* Invariant: Elements are declaration elements. |
*/ |
- final Set<FunctionElement> methodsNeedingSuperGetter = |
- new Set<FunctionElement>(); |
+ final Set<FunctionEntity> methodsNeedingSuperGetter = |
+ new Set<FunctionEntity>(); |
final Map<String, Map<Selector, SelectorConstraints>> _invokedNames = |
<String, Map<Selector, SelectorConstraints>>{}; |
final Map<String, Map<Selector, SelectorConstraints>> _invokedGetters = |
@@ -280,8 +282,8 @@ class ElementResolutionWorldBuilder implements ResolutionEnqueuerWorldBuilder { |
final Map<String, Map<Selector, SelectorConstraints>> _invokedSetters = |
<String, Map<Selector, SelectorConstraints>>{}; |
- final Map<ClassElement, _ClassUsage> _processedClasses = |
- <ClassElement, _ClassUsage>{}; |
+ final Map<ClassEntity, _ClassUsage> _processedClasses = |
+ <ClassEntity, _ClassUsage>{}; |
/// Map of registered usage of static members of live classes. |
final Map<Entity, _StaticMemberUsage> _staticMemberUsage = |
@@ -302,31 +304,35 @@ class ElementResolutionWorldBuilder implements ResolutionEnqueuerWorldBuilder { |
<String, Set<_MemberUsage>>{}; |
/// Fields set. |
- final Set<Element> fieldSetters = new Set<Element>(); |
- final Set<ResolutionDartType> isChecks = new Set<ResolutionDartType>(); |
+ final Set<FieldEntity> fieldSetters = new Set<FieldEntity>(); |
+ final Set<DartType> isChecks = new Set<DartType>(); |
/// Set of all closures in the program. Used by the mirror tracking system |
/// to find all live closure instances. |
- final Set<LocalFunctionElement> localFunctions = |
- new Set<LocalFunctionElement>(); |
+ final Set<Local> localFunctions = new Set<Local>(); |
/// Set of live local functions (closures) whose signatures reference type |
/// variables. |
/// |
/// A local function is considered live if the enclosing member function is |
/// live. |
- final Set<LocalFunctionElement> localFunctionsWithFreeTypeVariables = |
- new Set<LocalFunctionElement>(); |
+ final Set<Local> localFunctionsWithFreeTypeVariables = new Set<Local>(); |
/// Set of methods in instantiated classes that are potentially closurized. |
- final Set<MethodElement> closurizedMembers = new Set<MethodElement>(); |
+ final Set<FunctionEntity> closurizedMembers = new Set<FunctionEntity>(); |
/// Set of live closurized members whose signatures reference type variables. |
/// |
/// A closurized method is considered live if the enclosing class has been |
/// instantiated. |
- final Set<MethodElement> closurizedMembersWithFreeTypeVariables = |
- new Set<MethodElement>(); |
+ final Set<FunctionEntity> closurizedMembersWithFreeTypeVariables = |
+ new Set<FunctionEntity>(); |
+ |
+ final ElementEnvironment _elementEnvironment; |
+ |
+ final CommonElements _commonElements; |
+ |
+ final NativeBasicData _nativeBasicData; |
final SelectorConstraintsStrategy selectorConstraintsStrategy; |
@@ -334,41 +340,33 @@ class ElementResolutionWorldBuilder implements ResolutionEnqueuerWorldBuilder { |
bool hasIsolateSupport = false; |
bool hasFunctionApplySupport = false; |
- /// Used for testing the new more precise computation of instantiated types |
- /// and classes. |
- static bool useInstantiationMap = false; |
- |
- final JavaScriptBackend _backend; |
- final Resolution _resolution; |
bool _closed = false; |
ClosedWorld _closedWorldCache; |
FunctionSetBuilder _allFunctions; |
final Set<TypedefElement> _allTypedefs = new Set<TypedefElement>(); |
- final Map<ClassElement, Set<MixinApplicationElement>> _mixinUses = |
- new Map<ClassElement, Set<MixinApplicationElement>>(); |
+ final Map<ClassEntity, Set<ClassEntity>> _mixinUses = |
+ new Map<ClassEntity, Set<ClassEntity>>(); |
// We keep track of subtype and subclass relationships in four |
// distinct sets to make class hierarchy analysis faster. |
- final Map<ClassElement, ClassHierarchyNode> _classHierarchyNodes = |
- <ClassElement, ClassHierarchyNode>{}; |
- final Map<ClassElement, ClassSet> _classSets = <ClassElement, ClassSet>{}; |
+ final Map<ClassEntity, ClassHierarchyNode> _classHierarchyNodes = |
+ <ClassEntity, ClassHierarchyNode>{}; |
+ final Map<ClassEntity, ClassSet> _classSets = <ClassEntity, ClassSet>{}; |
final Set<ConstantValue> _constantValues = new Set<ConstantValue>(); |
bool get isClosed => _closed; |
- ElementResolutionWorldBuilder( |
- this._backend, this._resolution, this.selectorConstraintsStrategy) { |
+ ResolutionWorldBuilderBase(this._elementEnvironment, this._commonElements, |
+ this._nativeBasicData, this.selectorConstraintsStrategy) { |
_allFunctions = new FunctionSetBuilder(); |
} |
- Iterable<ClassElement> get processedClasses => _processedClasses.keys |
+ Iterable<ClassEntity> get processedClasses => _processedClasses.keys |
.where((cls) => _processedClasses[cls].isInstantiated); |
- CommonElements get commonElements => _resolution.commonElements; |
- |
ClosedWorld get closedWorldForTesting { |
if (!_closed) { |
throw new SpannableAssertionFailure( |
@@ -381,9 +379,9 @@ class ElementResolutionWorldBuilder implements ResolutionEnqueuerWorldBuilder { |
/// constructor that has been called directly and not only through a |
/// super-call. |
// TODO(johnniwinther): Improve semantic precision. |
- Iterable<ClassElement> get directlyInstantiatedClasses { |
- Set<ClassElement> classes = new Set<ClassElement>(); |
- getInstantiationMap().forEach((ClassElement cls, InstantiationInfo info) { |
+ Iterable<ClassEntity> get directlyInstantiatedClasses { |
+ Set<ClassEntity> classes = new Set<ClassEntity>(); |
+ getInstantiationMap().forEach((ClassEntity cls, InstantiationInfo info) { |
if (info.hasInstantiation) { |
classes.add(cls); |
} |
@@ -397,7 +395,7 @@ class ElementResolutionWorldBuilder implements ResolutionEnqueuerWorldBuilder { |
/// See [directlyInstantiatedClasses]. |
// TODO(johnniwinther): Improve semantic precision. |
Iterable<InterfaceType> get instantiatedTypes { |
- Set<ResolutionInterfaceType> types = new Set<ResolutionInterfaceType>(); |
+ Set<InterfaceType> types = new Set<InterfaceType>(); |
getInstantiationMap().forEach((_, InstantiationInfo info) { |
if (info.instantiationMap != null) { |
for (Set<Instance> instances in info.instantiationMap.values) { |
@@ -410,18 +408,14 @@ class ElementResolutionWorldBuilder implements ResolutionEnqueuerWorldBuilder { |
return types; |
} |
- /// Returns `true` if [cls] is considered to be implemented by an |
- /// instantiated class, either directly, through subclasses or through |
- /// subtypes. The latter case only contains spurious information from |
- /// instantiations through factory constructors and mixins. |
- // TODO(johnniwinther): Improve semantic precision. |
- bool isImplemented(ClassElement cls) { |
- return _implementedClasses.contains(cls.declaration); |
+ bool isImplemented(ClassEntity cls) { |
+ return _implementedClasses.contains(cls); |
} |
- void registerClosurizedMember(MemberElement element) { |
+ void registerClosurizedMember(FunctionEntity element) { |
closurizedMembers.add(element); |
- if (element.type.containsTypeVariables) { |
+ FunctionType type = _elementEnvironment.getFunctionType(element); |
+ if (type.containsTypeVariables) { |
closurizedMembersWithFreeTypeVariables.add(element); |
} |
} |
@@ -433,16 +427,15 @@ class ElementResolutionWorldBuilder implements ResolutionEnqueuerWorldBuilder { |
// subclass and through subtype instantiated types/classes. |
// TODO(johnniwinther): Support unknown type arguments for generic types. |
void registerTypeInstantiation( |
- ResolutionInterfaceType type, ClassUsedCallback classUsed, |
- {ConstructorElement constructor, |
+ InterfaceType type, ClassUsedCallback classUsed, |
+ {ConstructorEntity constructor, |
bool byMirrors: false, |
bool isRedirection: false}) { |
- ClassElement cls = type.element; |
- cls.ensureResolved(_resolution); |
+ ClassEntity cls = type.element; |
InstantiationInfo info = |
_instantiationInfo.putIfAbsent(cls, () => new InstantiationInfo()); |
Instantiation kind = Instantiation.UNINSTANTIATED; |
- bool isNative = _backend.nativeBasicData.isNativeClass(cls); |
+ bool isNative = _nativeBasicData.isNativeClass(cls); |
if (!cls.isAbstract || |
// We can't use the closed-world assumption with native abstract |
// classes; a native abstract class may have non-abstract subclasses |
@@ -467,7 +460,7 @@ class ElementResolutionWorldBuilder implements ResolutionEnqueuerWorldBuilder { |
// instead. |
if (_implementedClasses.add(cls)) { |
classUsed(cls, _getClassUsage(cls).implement()); |
- cls.allSupertypes.forEach((ResolutionInterfaceType supertype) { |
+ _elementEnvironment.forEachSupertype(cls, (InterfaceType supertype) { |
if (_implementedClasses.add(supertype.element)) { |
classUsed( |
supertype.element, _getClassUsage(supertype.element).implement()); |
@@ -477,12 +470,12 @@ class ElementResolutionWorldBuilder implements ResolutionEnqueuerWorldBuilder { |
} |
@override |
- void forEachInstantiatedClass(f(ClassElement cls, InstantiationInfo info)) { |
+ void forEachInstantiatedClass(f(ClassEntity cls, InstantiationInfo info)) { |
getInstantiationMap().forEach(f); |
} |
bool _hasMatchingSelector( |
- Map<Selector, SelectorConstraints> selectors, Element member) { |
+ Map<Selector, SelectorConstraints> selectors, MemberEntity member) { |
if (selectors == null) return false; |
for (Selector selector in selectors.keys) { |
if (selector.appliesUnnamed(member)) { |
@@ -496,59 +489,20 @@ class ElementResolutionWorldBuilder implements ResolutionEnqueuerWorldBuilder { |
} |
/// Returns the instantiation map used for computing the closed world. |
- /// |
- /// If [useInstantiationMap] is `true`, redirections are removed and |
- /// redirecting factories are converted to their effective target and type. |
- Map<ClassElement, InstantiationInfo> getInstantiationMap() { |
- if (!useInstantiationMap) return _instantiationInfo; |
- |
- Map<ClassElement, InstantiationInfo> instantiationMap = |
- <ClassElement, InstantiationInfo>{}; |
- |
- InstantiationInfo infoFor(ClassElement cls) { |
- return instantiationMap.putIfAbsent(cls, () => new InstantiationInfo()); |
- } |
- |
- _instantiationInfo.forEach((cls, info) { |
- if (info.instantiationMap != null) { |
- info.instantiationMap |
- .forEach((ConstructorElement constructor, Set<Instance> set) { |
- for (Instance instance in set) { |
- if (instance.isRedirection) { |
- continue; |
- } |
- if (constructor == null || !constructor.isRedirectingFactory) { |
- infoFor(cls) |
- .addInstantiation(constructor, instance.type, instance.kind); |
- } else { |
- ConstructorElement target = constructor.effectiveTarget; |
- ResolutionInterfaceType targetType = |
- constructor.computeEffectiveTargetType(instance.type); |
- Instantiation kind = Instantiation.DIRECTLY_INSTANTIATED; |
- if (target.enclosingClass.isAbstract) { |
- // If target is a factory constructor on an abstract class. |
- kind = Instantiation.UNINSTANTIATED; |
- } |
- infoFor(targetType.element) |
- .addInstantiation(target, targetType, kind); |
- } |
- } |
- }); |
- } |
- }); |
- return instantiationMap; |
+ Map<ClassEntity, InstantiationInfo> getInstantiationMap() { |
+ return _instantiationInfo; |
} |
- bool _hasInvocation(Element member) { |
+ bool _hasInvocation(MemberEntity member) { |
return _hasMatchingSelector(_invokedNames[member.name], member); |
} |
- bool _hasInvokedGetter(Element member) { |
+ bool _hasInvokedGetter(MemberEntity member) { |
return _hasMatchingSelector(_invokedGetters[member.name], member) || |
member.isFunction && methodsNeedingSuperGetter.contains(member); |
} |
- bool hasInvokedSetter(Element member) { |
+ bool hasInvokedSetter(MemberEntity member) { |
return _hasMatchingSelector(_invokedSetters[member.name], member); |
} |
@@ -602,13 +556,7 @@ class ElementResolutionWorldBuilder implements ResolutionEnqueuerWorldBuilder { |
return constraints.addReceiverConstraint(mask); |
} |
- void registerIsCheck(ResolutionDartType type) { |
- type.computeUnaliased(_resolution); |
- type = type.unaliased; |
- // Even in checked mode, type annotations for return type and argument |
- // types do not imply type checks, so there should never be a check |
- // against the type variable of a typedef. |
- assert(!type.isTypeVariable || !type.element.enclosingElement.isTypedef); |
+ void registerIsCheck(DartType type) { |
isChecks.add(type); |
} |
@@ -617,9 +565,7 @@ class ElementResolutionWorldBuilder implements ResolutionEnqueuerWorldBuilder { |
} |
void registerStaticUse(StaticUse staticUse, MemberUsedCallback memberUsed) { |
- Element element = staticUse.element; |
- assert(invariant(element, element.isDeclaration, |
- message: "Element ${element} is not the declaration.")); |
+ MemberEntity element = staticUse.element; |
_StaticMemberUsage usage = _staticMemberUsage.putIfAbsent(element, () { |
if ((element.isStatic || element.isTopLevel) && element.isFunction) { |
return new _StaticFunctionUsage(element); |
@@ -629,8 +575,8 @@ class ElementResolutionWorldBuilder implements ResolutionEnqueuerWorldBuilder { |
}); |
EnumSet<MemberUse> useSet = new EnumSet<MemberUse>(); |
- if (Elements.isStaticOrTopLevel(element) && element.isField) { |
- allReferencedStaticFields.add(element); |
+ if ((element.isStatic || element.isTopLevel) && element.isField) { |
+ allReferencedStaticFields.add(staticUse.element); |
} |
// TODO(johnniwinther): Avoid this. Currently [FIELD_GET] and |
// [FIELD_SET] contains [BoxFieldElement]s which we cannot enqueue. |
@@ -640,21 +586,17 @@ class ElementResolutionWorldBuilder implements ResolutionEnqueuerWorldBuilder { |
case StaticUseKind.FIELD_GET: |
break; |
case StaticUseKind.FIELD_SET: |
- fieldSetters.add(element); |
+ fieldSetters.add(staticUse.element); |
break; |
case StaticUseKind.CLOSURE: |
- LocalFunctionElement localFunction = staticUse.element; |
- if (localFunction.type.containsTypeVariables) { |
- localFunctionsWithFreeTypeVariables.add(localFunction); |
- } |
- localFunctions.add(element); |
- break; |
+ throw new UnimplementedError( |
+ "registerStaticUse not implemented for StaticUseKind.CLOSURE."); |
case StaticUseKind.SUPER_TEAR_OFF: |
useSet.addAll(usage.tearOff()); |
- methodsNeedingSuperGetter.add(element); |
+ methodsNeedingSuperGetter.add(staticUse.element); |
break; |
case StaticUseKind.SUPER_FIELD_SET: |
- fieldSetters.add(element); |
+ fieldSetters.add(staticUse.element); |
useSet.addAll(usage.normalUse()); |
break; |
case StaticUseKind.STATIC_TEAR_OFF: |
@@ -680,23 +622,24 @@ class ElementResolutionWorldBuilder implements ResolutionEnqueuerWorldBuilder { |
} |
} |
+ /// Called to create a [_ClassUsage] for [cls]. |
+ /// |
+ /// Subclasses override this to ensure needed invariants on [cls]. |
+ _ClassUsage _createClassUsage(ClassEntity cls) => new _ClassUsage(cls); |
+ |
/// Return the canonical [_ClassUsage] for [cls]. |
- _ClassUsage _getClassUsage(ClassElement cls) { |
+ _ClassUsage _getClassUsage(ClassEntity cls) { |
return _processedClasses.putIfAbsent(cls, () { |
- cls.ensureResolved(_resolution); |
- _ClassUsage usage = new _ClassUsage(cls); |
- _resolution.ensureClassMembers(cls); |
- return usage; |
+ return _createClassUsage(cls); |
}); |
} |
/// Register [cls] and all its superclasses as instantiated. |
- void _processInstantiatedClass( |
- ClassElement cls, ClassUsedCallback classUsed) { |
+ void _processInstantiatedClass(ClassEntity cls, ClassUsedCallback classUsed) { |
// Registers [superclass] as instantiated. Returns `true` if it wasn't |
// already instantiated and we therefore have to process its superclass as |
// well. |
- bool processClass(ClassElement superclass) { |
+ bool processClass(ClassEntity superclass) { |
_ClassUsage usage = _getClassUsage(superclass); |
if (!usage.isInstantiated) { |
classUsed(usage.cls, usage.instantiate()); |
@@ -706,14 +649,15 @@ class ElementResolutionWorldBuilder implements ResolutionEnqueuerWorldBuilder { |
} |
while (cls != null && processClass(cls)) { |
- cls = cls.superclass; |
+ cls = _elementEnvironment.getSuperClass(cls); |
} |
} |
/// Computes usage for all members declared by [cls]. Calls [membersUsed] with |
/// the usage changes for each member. |
- void processClassMembers(ClassElement cls, MemberUsedCallback memberUsed) { |
- cls.implementation.forEachMember((ClassElement cls, MemberElement member) { |
+ void processClassMembers(ClassEntity cls, MemberUsedCallback memberUsed) { |
+ _elementEnvironment.forEachClassMember(cls, |
+ (ClassEntity cls, MemberEntity member) { |
_processInstantiatedClassMember(cls, member, memberUsed); |
}); |
} |
@@ -737,11 +681,9 @@ class ElementResolutionWorldBuilder implements ResolutionEnqueuerWorldBuilder { |
} |
void _processInstantiatedClassMember( |
- ClassElement cls, MemberElement member, MemberUsedCallback memberUsed) { |
- assert(invariant(member, member.isDeclaration)); |
+ ClassEntity cls, MemberEntity member, MemberUsedCallback memberUsed) { |
if (!member.isInstanceMember) return; |
String memberName = member.name; |
- member.computeType(_resolution); |
// The obvious thing to test here would be "member.isNative", |
// however, that only works after metadata has been parsed/analyzed, |
// and that may not have happened yet. |
@@ -750,7 +692,7 @@ class ElementResolutionWorldBuilder implements ResolutionEnqueuerWorldBuilder { |
// Note: this assumes that there are no non-native fields on native |
// classes, which may not be the case when a native class is subclassed. |
_instanceMemberUsage.putIfAbsent(member, () { |
- bool isNative = _backend.nativeBasicData.isNativeClass(cls); |
+ bool isNative = _nativeBasicData.isNativeClass(cls); |
_MemberUsage usage = new _MemberUsage(member, isNative: isNative); |
EnumSet<MemberUse> useSet = new EnumSet<MemberUse>(); |
useSet.addAll(usage.appliedUse); |
@@ -759,7 +701,7 @@ class ElementResolutionWorldBuilder implements ResolutionEnqueuerWorldBuilder { |
} |
if (member.isFunction && |
member.name == Identifiers.call && |
- !cls.typeVariables.isEmpty) { |
+ _elementEnvironment.getThisType(cls).typeArguments.isNotEmpty) { |
closurizedMembersWithFreeTypeVariables.add(member); |
} |
@@ -794,159 +736,23 @@ class ElementResolutionWorldBuilder implements ResolutionEnqueuerWorldBuilder { |
} |
/// Returns an iterable over all mixin applications that mixin [cls]. |
- Iterable<MixinApplicationElement> allMixinUsesOf(ClassElement cls) { |
- Iterable<MixinApplicationElement> uses = _mixinUses[cls]; |
- return uses != null ? uses : const <MixinApplicationElement>[]; |
- } |
- |
- /// Called to add [cls] to the set of known classes. |
- /// |
- /// This ensures that class hierarchy queries can be performed on [cls] and |
- /// classes that extend or implement it. |
- void registerClass(ClassElement cls) => _registerClass(cls); |
- |
- void _registerClass(ClassElement cls, {bool isDirectlyInstantiated: false}) { |
- _ensureClassSet(cls); |
- if (isDirectlyInstantiated) { |
- _updateClassHierarchyNodeForClass(cls, directlyInstantiated: true); |
- } |
+ Iterable<ClassEntity> allMixinUsesOf(ClassEntity cls) { |
+ Iterable<ClassEntity> uses = _mixinUses[cls]; |
+ return uses != null ? uses : const <ClassEntity>[]; |
} |
void registerTypedef(TypedefElement typdef) { |
_allTypedefs.add(typdef); |
} |
- ClassHierarchyNode _ensureClassHierarchyNode(ClassElement cls) { |
- cls = cls.declaration; |
- return _classHierarchyNodes.putIfAbsent(cls, () { |
- ClassHierarchyNode parentNode; |
- if (cls.superclass != null) { |
- parentNode = _ensureClassHierarchyNode(cls.superclass); |
- } |
- return new ClassHierarchyNode(parentNode, cls); |
- }); |
- } |
- |
- ClassSet _ensureClassSet(ClassElement cls) { |
- cls = cls.declaration; |
- return _classSets.putIfAbsent(cls, () { |
- ClassHierarchyNode node = _ensureClassHierarchyNode(cls); |
- ClassSet classSet = new ClassSet(node); |
- |
- for (ResolutionInterfaceType type in cls.allSupertypes) { |
- // TODO(johnniwinther): Optimization: Avoid adding [cls] to |
- // superclasses. |
- ClassSet subtypeSet = _ensureClassSet(type.element); |
- subtypeSet.addSubtype(node); |
- } |
- if (cls.isMixinApplication) { |
- // TODO(johnniwinther): Store this in the [ClassSet]. |
- MixinApplicationElement mixinApplication = cls; |
- if (mixinApplication.mixin != null) { |
- // If [mixinApplication] is malformed [mixin] is `null`. |
- registerMixinUse(mixinApplication, mixinApplication.mixin); |
- } |
- } |
- |
- return classSet; |
- }); |
- } |
- |
- void _updateSuperClassHierarchyNodeForClass(ClassHierarchyNode node) { |
- // Ensure that classes implicitly implementing `Function` are in its |
- // subtype set. |
- ClassElement cls = node.cls; |
- if (cls != commonElements.functionClass && |
- cls.implementsFunction(commonElements)) { |
- ClassSet subtypeSet = _ensureClassSet(commonElements.functionClass); |
- subtypeSet.addSubtype(node); |
- } |
- if (!node.isInstantiated && node.parentNode != null) { |
- _updateSuperClassHierarchyNodeForClass(node.parentNode); |
- } |
- } |
- |
- void _updateClassHierarchyNodeForClass(ClassElement cls, |
- {bool directlyInstantiated: false, bool abstractlyInstantiated: false}) { |
- ClassHierarchyNode node = _ensureClassHierarchyNode(cls); |
- _updateSuperClassHierarchyNodeForClass(node); |
- if (directlyInstantiated) { |
- node.isDirectlyInstantiated = true; |
- } |
- if (abstractlyInstantiated) { |
- node.isAbstractlyInstantiated = true; |
- } |
- } |
- |
- ClosedWorld closeWorld(DiagnosticReporter reporter) { |
- Map<ClassElement, Set<ClassElement>> typesImplementedBySubclasses = |
- new Map<ClassElement, Set<ClassElement>>(); |
- |
- /// Updates the `isDirectlyInstantiated` and `isIndirectlyInstantiated` |
- /// properties of the [ClassHierarchyNode] for [cls]. |
- |
- void addSubtypes(ClassElement cls, InstantiationInfo info) { |
- if (!info.hasInstantiation) { |
- return; |
- } |
- assert(cls.isDeclaration); |
- if (!cls.isResolved) { |
- reporter.internalError(cls, 'Class "${cls.name}" is not resolved.'); |
- } |
- |
- _updateClassHierarchyNodeForClass(cls, |
- directlyInstantiated: info.isDirectlyInstantiated, |
- abstractlyInstantiated: info.isAbstractlyInstantiated); |
- |
- // Walk through the superclasses, and record the types |
- // implemented by that type on the superclasses. |
- ClassElement superclass = cls.superclass; |
- while (superclass != null) { |
- Set<Element> typesImplementedBySubclassesOfCls = |
- typesImplementedBySubclasses.putIfAbsent( |
- superclass, () => new Set<ClassElement>()); |
- for (ResolutionDartType current in cls.allSupertypes) { |
- typesImplementedBySubclassesOfCls.add(current.element); |
- } |
- superclass = superclass.superclass; |
- } |
- } |
- |
- // Use the [:seenClasses:] set to include non-instantiated |
- // classes: if the superclass of these classes require RTI, then |
- // they also need RTI, so that a constructor passes the type |
- // variables to the super constructor. |
- forEachInstantiatedClass(addSubtypes); |
- |
- _closed = true; |
- return _closedWorldCache = new ClosedWorldImpl( |
- backend: _backend, |
- commonElements: commonElements, |
- resolutionWorldBuilder: this, |
- functionSetBuilder: _allFunctions, |
- allTypedefs: _allTypedefs, |
- mixinUses: _mixinUses, |
- typesImplementedBySubclasses: typesImplementedBySubclasses, |
- classHierarchyNodes: _classHierarchyNodes, |
- classSets: _classSets); |
- } |
- |
- void registerMixinUse( |
- MixinApplicationElement mixinApplication, ClassElement mixin) { |
+ void registerMixinUse(ClassEntity mixinApplication, ClassEntity mixin) { |
// TODO(johnniwinther): Add map restricted to live classes. |
// We don't support patch classes as mixin. |
- assert(mixin.isDeclaration); |
- Set<MixinApplicationElement> users = |
- _mixinUses.putIfAbsent(mixin, () => new Set<MixinApplicationElement>()); |
+ Set<ClassEntity> users = |
+ _mixinUses.putIfAbsent(mixin, () => new Set<ClassEntity>()); |
users.add(mixinApplication); |
} |
- void registerUsedElement(MemberElement element) { |
- if (element.isInstanceMember && !element.isAbstract) { |
- _allFunctions.add(element); |
- } |
- } |
- |
ClosedWorld get closedWorldCache { |
assert(isClosed); |
return _closedWorldCache; |