Chromium Code Reviews| Index: pkg/compiler/lib/src/world.dart |
| diff --git a/pkg/compiler/lib/src/world.dart b/pkg/compiler/lib/src/world.dart |
| index 76b2bc3e44d52e20b88a68ea27fcddf0b039895c..3fe2657eec9cfa636414cc2450d547ceab92c3c3 100644 |
| --- a/pkg/compiler/lib/src/world.dart |
| +++ b/pkg/compiler/lib/src/world.dart |
| @@ -5,7 +5,7 @@ |
| library dart2js.world; |
| import 'cache_strategy.dart'; |
| -import 'closure.dart' show SynthesizedCallMethodElementX; |
| +import 'closure.dart' show ClosureClassElement, SynthesizedCallMethodElementX; |
| import 'common/backend_api.dart' show BackendClasses; |
| import 'common.dart'; |
| import 'constants/constant_system.dart'; |
| @@ -23,7 +23,7 @@ import 'js_backend/backend.dart' show JavaScriptBackend; |
| import 'ordered_typeset.dart'; |
| import 'types/masks.dart' show CommonMasks, FlatTypeMask, TypeMask; |
| import 'universe/class_set.dart'; |
| -import 'universe/function_set.dart' show FunctionSet; |
| +import 'universe/function_set.dart' show FunctionSet, FunctionSetBuilder; |
| import 'universe/selector.dart' show Selector; |
| import 'universe/side_effects.dart' show SideEffects; |
| import 'universe/world_builder.dart' |
| @@ -350,13 +350,283 @@ abstract class OpenWorld implements World { |
| Iterable<MixinApplicationElement> allMixinUsesOf(ClassElement cls); |
| } |
| -class WorldImpl implements ClosedWorld, ClosedWorldRefiner, OpenWorld { |
| +class WorldImpl implements OpenWorld { |
| bool _closed = false; |
| + ClosedWorld _closedWorldCache; |
| - TypeMask getCachedMask(ClassElement base, int flags, TypeMask createMask()) { |
| - Map<ClassElement, TypeMask> cachedMasks = |
| - _canonicalizedTypeMasks[flags] ??= <ClassElement, TypeMask>{}; |
| - return cachedMasks.putIfAbsent(base, createMask); |
| + final JavaScriptBackend _backend; |
| + FunctionSetBuilder _allFunctions; |
| + |
| + final Set<TypedefElement> _allTypedefs = new Set<TypedefElement>(); |
| + |
| + final Map<ClassElement, Set<MixinApplicationElement>> _mixinUses = |
| + new Map<ClassElement, Set<MixinApplicationElement>>(); |
| + |
| + // 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<ClassElement, Map<ClassElement, bool>> _subtypeCoveredByCache = |
| + <ClassElement, Map<ClassElement, bool>>{}; |
| + |
| + final Set<Element> alreadyPopulated; |
| + |
| + final CommonElements commonElements; |
| + |
| + final CoreTypes coreTypes; |
| + |
| + final CacheStrategy cacheStrategy; |
| + |
| + final ResolutionWorldBuilder resolverWorld; |
| + |
| + bool get isClosed => _closed; |
| + |
| + WorldImpl(this.resolverWorld, this._backend, this.commonElements, |
| + this.coreTypes, CacheStrategy cacheStrategy) |
| + : this.cacheStrategy = cacheStrategy, |
| + alreadyPopulated = cacheStrategy.newSet() { |
| + _allFunctions = new FunctionSetBuilder(); |
| + } |
| + |
| + /// 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); |
| + } |
| + } |
| + |
| + 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 (InterfaceType 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; |
| + } |
| + if (cacheStrategy.hasIncrementalSupport && !alreadyPopulated.add(cls)) { |
| + return; |
| + } |
| + assert(cls.isDeclaration); |
| + if (!cls.isResolved) { |
| + reporter.internalError(cls, 'Class "${cls.name}" is not resolved.'); |
|
Siggi Cherem (dart-lang)
2016/12/20 15:36:36
related to the discussion in the other CL - this w
Johnni Winther
2016/12/21 08:41:25
Yes. Will do later.
|
| + } |
| + |
| + _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 (DartType 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. |
| + resolverWorld.forEachInstantiatedClass(addSubtypes); |
| + |
| + _closed = true; |
| + return _closedWorldCache = new ClosedWorldImpl( |
| + backend: _backend, |
| + commonElements: commonElements, |
| + coreTypes: coreTypes, |
| + resolverWorld: resolverWorld, |
| + functionSetBuilder: _allFunctions, |
| + allTypedefs: _allTypedefs, |
| + mixinUses: _mixinUses, |
| + typesImplementedBySubclasses: typesImplementedBySubclasses, |
| + classHierarchyNodes: _classHierarchyNodes, |
| + classSets: _classSets); |
| + } |
| + |
| + void registerMixinUse( |
| + MixinApplicationElement mixinApplication, ClassElement 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>()); |
| + users.add(mixinApplication); |
| + } |
| + |
| + void registerUsedElement(Element element) { |
| + if (element.isInstanceMember && !element.isAbstract) { |
| + _allFunctions.add(element); |
| + } |
| + } |
| + |
| + ClosedWorld get closedWorldCache { |
| + assert(isClosed); |
| + return _closedWorldCache; |
| + } |
| +} |
| + |
| +/// Enum values defining subset of classes included in queries. |
| +enum ClassQuery { |
| + /// Only the class itself is included. |
| + EXACT, |
| + |
| + /// The class and all subclasses (transitively) are included. |
| + SUBCLASS, |
| + |
| + /// The class and all classes that implement or subclass it (transitively) |
| + /// are included. |
| + SUBTYPE, |
| +} |
| + |
| +class ClosedWorldImpl implements ClosedWorld, ClosedWorldRefiner { |
| + final JavaScriptBackend _backend; |
| + BackendClasses get backendClasses => _backend.backendClasses; |
| + FunctionSet _allFunctions; |
| + |
| + final Iterable<TypedefElement> _allTypedefs; |
| + |
| + final Map<ClassElement, Set<MixinApplicationElement>> _mixinUses; |
| + Map<ClassElement, List<MixinApplicationElement>> _liveMixinUses; |
| + |
| + final Map<ClassElement, Set<ClassElement>> _typesImplementedBySubclasses; |
| + |
| + // We keep track of subtype and subclass relationships in four |
| + // distinct sets to make class hierarchy analysis faster. |
| + final Map<ClassElement, ClassHierarchyNode> _classHierarchyNodes; |
| + final Map<ClassElement, ClassSet> _classSets; |
| + |
| + final Map<ClassElement, Map<ClassElement, bool>> _subtypeCoveredByCache = |
| + <ClassElement, Map<ClassElement, bool>>{}; |
| + |
| + final Set<Element> functionsCalledInLoop = new Set<Element>(); |
| + final Map<Element, SideEffects> sideEffects = new Map<Element, SideEffects>(); |
| + |
| + final Set<Element> sideEffectsFreeElements = new Set<Element>(); |
| + |
| + final Set<Element> elementsThatCannotThrow = new Set<Element>(); |
| + |
| + final Set<Element> functionsThatMightBePassedToApply = |
| + new Set<FunctionElement>(); |
| + |
| + CommonMasks _commonMasks; |
| + |
| + final CommonElements commonElements; |
| + |
| + final CoreTypes coreTypes; |
| + |
| + final ResolutionWorldBuilder _resolverWorld; |
| + |
| + bool get isClosed => true; |
| + |
| + ClosedWorldImpl( |
| + {JavaScriptBackend backend, |
| + this.commonElements, |
| + this.coreTypes, |
| + ResolutionWorldBuilder resolverWorld, |
| + FunctionSetBuilder functionSetBuilder, |
| + Iterable<TypedefElement> allTypedefs, |
| + Map<ClassElement, Set<MixinApplicationElement>> mixinUses, |
| + Map<ClassElement, Set<ClassElement>> typesImplementedBySubclasses, |
| + Map<ClassElement, ClassHierarchyNode> classHierarchyNodes, |
| + Map<ClassElement, ClassSet> classSets}) |
| + : this._backend = backend, |
| + this._resolverWorld = resolverWorld, |
| + this._allTypedefs = allTypedefs, |
| + this._mixinUses = mixinUses, |
| + this._typesImplementedBySubclasses = typesImplementedBySubclasses, |
| + this._classHierarchyNodes = classHierarchyNodes, |
| + this._classSets = classSets { |
| + _commonMasks = new CommonMasks(this); |
| + _allFunctions = functionSetBuilder.close(this); |
| } |
| /// Cache of [FlatTypeMask]s grouped by the 8 possible values of the |
| @@ -364,6 +634,23 @@ class WorldImpl implements ClosedWorld, ClosedWorldRefiner, OpenWorld { |
| final List<Map<ClassElement, TypeMask>> _canonicalizedTypeMasks = |
| new List<Map<ClassElement, TypeMask>>.filled(8, null); |
| + FunctionSet get allFunctions => _allFunctions; |
| + |
| + CommonMasks get commonMasks { |
| + assert(isClosed); |
| + return _commonMasks; |
| + } |
| + |
| + CoreClasses get coreClasses => commonElements; |
| + |
| + ConstantSystem get constantSystem => _backend.constantSystem; |
| + |
| + TypeMask getCachedMask(ClassElement base, int flags, TypeMask createMask()) { |
| + Map<ClassElement, TypeMask> cachedMasks = |
| + _canonicalizedTypeMasks[flags] ??= <ClassElement, TypeMask>{}; |
| + return cachedMasks.putIfAbsent(base, createMask); |
| + } |
| + |
| bool checkInvariants(ClassElement cls, {bool mustBeInstantiated: true}) { |
| return invariant(cls, cls.isDeclaration, |
| message: '$cls must be the declaration.') && |
| @@ -447,7 +734,7 @@ class WorldImpl implements ClosedWorld, ClosedWorldRefiner, OpenWorld { |
| /// Returns `true` if [cls] is implemented by an instantiated class. |
| bool isImplemented(ClassElement cls) { |
| assert(isClosed); |
| - return resolverWorld.isImplemented(cls); |
| + return _resolverWorld.isImplemented(cls); |
| } |
| /// Returns an iterable over the directly instantiated classes that extend |
| @@ -668,12 +955,6 @@ class WorldImpl implements ClosedWorld, ClosedWorldRefiner, OpenWorld { |
| return commonSupertypes; |
| } |
| - /// 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>[]; |
| - } |
| - |
| /// Returns an iterable over the live mixin applications that mixin [cls]. |
| Iterable<MixinApplicationElement> mixinUsesOf(ClassElement cls) { |
| assert(isClosed); |
| @@ -758,7 +1039,9 @@ class WorldImpl implements ClosedWorld, ClosedWorldRefiner, OpenWorld { |
| bool hasAnySubclassThatImplements( |
| ClassElement superclass, ClassElement type) { |
| assert(isClosed); |
| - Set<ClassElement> subclasses = typesImplementedBySubclassesOf(superclass); |
| + |
| + Set<ClassElement> subclasses = |
| + _typesImplementedBySubclasses[superclass.declaration]; |
| if (subclasses == null) return false; |
| return subclasses.contains(type); |
| } |
| @@ -846,96 +1129,6 @@ class WorldImpl implements ClosedWorld, ClosedWorldRefiner, OpenWorld { |
| } |
| } |
| - final JavaScriptBackend _backend; |
| - BackendClasses get backendClasses => _backend.backendClasses; |
| - FunctionSet _allFunctions; |
| - final Set<Element> functionsCalledInLoop = new Set<Element>(); |
| - final Map<Element, SideEffects> sideEffects = new Map<Element, SideEffects>(); |
| - |
| - final Set<TypedefElement> _allTypedefs = new Set<TypedefElement>(); |
| - |
| - final Map<ClassElement, Set<MixinApplicationElement>> _mixinUses = |
| - new Map<ClassElement, Set<MixinApplicationElement>>(); |
| - Map<ClassElement, List<MixinApplicationElement>> _liveMixinUses; |
| - |
| - final Map<ClassElement, Set<ClassElement>> _typesImplementedBySubclasses = |
| - new Map<ClassElement, Set<ClassElement>>(); |
| - |
| - // 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<ClassElement, Map<ClassElement, bool>> _subtypeCoveredByCache = |
| - <ClassElement, Map<ClassElement, bool>>{}; |
| - |
| - final Set<Element> sideEffectsFreeElements = new Set<Element>(); |
| - |
| - final Set<Element> elementsThatCannotThrow = new Set<Element>(); |
| - |
| - final Set<Element> functionsThatMightBePassedToApply = |
| - new Set<FunctionElement>(); |
| - |
| - final Set<Element> alreadyPopulated; |
| - |
| - CommonMasks _commonMasks; |
| - |
| - final CommonElements commonElements; |
| - |
| - final CoreTypes coreTypes; |
| - |
| - final CacheStrategy cacheStrategy; |
| - |
| - final ResolutionWorldBuilder resolverWorld; |
| - |
| - bool get isClosed => _closed; |
| - |
| - Set<ClassElement> typesImplementedBySubclassesOf(ClassElement cls) { |
| - return _typesImplementedBySubclasses[cls.declaration]; |
| - } |
| - |
| - WorldImpl(this.resolverWorld, this._backend, this.commonElements, |
| - this.coreTypes, CacheStrategy cacheStrategy) |
| - : this.cacheStrategy = cacheStrategy, |
| - alreadyPopulated = cacheStrategy.newSet() { |
| - _allFunctions = new FunctionSet(this); |
| - } |
| - |
| - FunctionSet get allFunctions => _allFunctions; |
| - |
| - CommonMasks get commonMasks { |
| - assert(isClosed); |
| - return _commonMasks; |
| - } |
| - |
| - CoreClasses get coreClasses => commonElements; |
| - |
| - ConstantSystem get constantSystem => _backend.constantSystem; |
| - |
| - /// 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 registerClosureClass(ClassElement cls) { |
| - _registerClass(cls, isDirectlyInstantiated: true); |
| - } |
| - |
| - void _registerClass(ClassElement cls, {bool isDirectlyInstantiated: false}) { |
| - _ensureClassSet(cls); |
| - if (isDirectlyInstantiated) { |
| - _updateClassHierarchyNodeForClass(cls, directlyInstantiated: true); |
| - } |
| - } |
| - |
| - void registerTypedef(TypedefElement typdef) { |
| - _allTypedefs.add(typdef); |
| - } |
| - |
| - Iterable<TypedefElement> get allTypedefs => _allTypedefs; |
| - |
| /// Returns [ClassHierarchyNode] for [cls] used to model the class hierarchies |
| /// of known classes. |
| /// |
| @@ -945,17 +1138,6 @@ class WorldImpl implements ClosedWorld, ClosedWorldRefiner, OpenWorld { |
| return _classHierarchyNodes[cls.declaration]; |
| } |
| - 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); |
| - }); |
| - } |
| - |
| /// Returns [ClassSet] for [cls] used to model the extends and implements |
| /// relations of known classes. |
| /// |
| @@ -965,38 +1147,26 @@ class WorldImpl implements ClosedWorld, ClosedWorldRefiner, OpenWorld { |
| return _classSets[cls.declaration]; |
| } |
| - ClassSet _ensureClassSet(ClassElement cls) { |
| - cls = cls.declaration; |
| - return _classSets.putIfAbsent(cls, () { |
| - ClassHierarchyNode node = _ensureClassHierarchyNode(cls); |
| - ClassSet classSet = new ClassSet(node); |
| - |
| - for (InterfaceType 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 registerClosureClass(ClosureClassElement cls) { |
| + ClassHierarchyNode parentNode = getClassHierarchyNode(cls.superclass); |
| + ClassHierarchyNode node = |
| + _classHierarchyNodes[cls] = new ClassHierarchyNode(parentNode, cls); |
| + for (InterfaceType type in cls.allSupertypes) { |
| + ClassSet subtypeSet = getClassSet(type.element); |
| + subtypeSet.addSubtype(node); |
| + } |
| + _classSets[cls] = new ClassSet(node); |
| + _updateSuperClassHierarchyNodeForClass(node); |
| + node.isDirectlyInstantiated = true; |
| } |
| void _updateSuperClassHierarchyNodeForClass(ClassHierarchyNode node) { |
| // Ensure that classes implicitly implementing `Function` are in its |
| // subtype set. |
| ClassElement cls = node.cls; |
| - if (cls != coreClasses.functionClass && |
| - cls.implementsFunction(coreClasses)) { |
| - ClassSet subtypeSet = _ensureClassSet(coreClasses.functionClass); |
| + if (cls != commonElements.functionClass && |
| + cls.implementsFunction(commonElements)) { |
| + ClassSet subtypeSet = getClassSet(commonElements.functionClass); |
| subtypeSet.addSubtype(node); |
| } |
| if (!node.isInstantiated && node.parentNode != null) { |
| @@ -1004,62 +1174,7 @@ class WorldImpl implements ClosedWorld, ClosedWorldRefiner, OpenWorld { |
| } |
| } |
| - 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) { |
| - /// Updates the `isDirectlyInstantiated` and `isIndirectlyInstantiated` |
| - /// properties of the [ClassHierarchyNode] for [cls]. |
| - |
| - void addSubtypes(ClassElement cls, InstantiationInfo info) { |
| - if (!info.hasInstantiation) { |
| - return; |
| - } |
| - if (cacheStrategy.hasIncrementalSupport && !alreadyPopulated.add(cls)) { |
| - 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 (DartType 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. |
| - resolverWorld.forEachInstantiatedClass(addSubtypes); |
| - |
| - _closed = true; |
| - _commonMasks = new CommonMasks(this); |
| - return this; |
| - } |
| + Iterable<TypedefElement> get allTypedefs => _allTypedefs; |
| @override |
| String dump([ClassElement cls]) { |
| @@ -1074,26 +1189,10 @@ class WorldImpl implements ClosedWorld, ClosedWorldRefiner, OpenWorld { |
| return sb.toString(); |
| } |
| - void registerMixinUse( |
| - MixinApplicationElement mixinApplication, ClassElement 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>()); |
| - users.add(mixinApplication); |
| - } |
| - |
| bool hasAnyUserDefinedGetter(Selector selector, TypeMask mask) { |
| return allFunctions.filter(selector, mask).any((each) => each.isGetter); |
| } |
| - void registerUsedElement(Element element) { |
| - if (element.isInstanceMember && !element.isAbstract) { |
| - allFunctions.add(element); |
| - } |
| - } |
| - |
| FieldElement locateSingleField(Selector selector, TypeMask mask) { |
| Element result = locateSingleElement(selector, mask); |
| return (result != null && result.isField) ? result : null; |
| @@ -1137,8 +1236,8 @@ class WorldImpl implements ClosedWorld, ClosedWorldRefiner, OpenWorld { |
| return true; |
| } |
| if (element.isInstanceMember) { |
| - return !resolverWorld.hasInvokedSetter(element) && |
| - !resolverWorld.fieldSetters.contains(element); |
| + return !_resolverWorld.hasInvokedSetter(element) && |
| + !_resolverWorld.fieldSetters.contains(element); |
| } |
| return false; |
| } |
| @@ -1226,16 +1325,3 @@ class WorldImpl implements ClosedWorld, ClosedWorldRefiner, OpenWorld { |
| return getMightBePassedToApply(element); |
| } |
| } |
| - |
| -/// Enum values defining subset of classes included in queries. |
| -enum ClassQuery { |
| - /// Only the class itself is included. |
| - EXACT, |
| - |
| - /// The class and all subclasses (transitively) are included. |
| - SUBCLASS, |
| - |
| - /// The class and all classes that implement or subclass it (transitively) |
| - /// are included. |
| - SUBTYPE, |
| -} |