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

Unified Diff: pkg/compiler/lib/src/universe/resolution_world_builder.dart

Issue 2804993002: Extract ResolutionWorldBuilderBase from ElementResolutionWorldBuilder (Closed)
Patch Set: Fix. Created 3 years, 8 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
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;
« no previous file with comments | « pkg/compiler/lib/src/universe/element_world_builder.dart ('k') | pkg/compiler/lib/src/universe/world_builder.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698