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

Unified Diff: pkg/compiler/lib/src/world.dart

Issue 2826673002: Remove JavaScriptBackend from ClosedWorldBase (Closed)
Patch Set: 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/world.dart
diff --git a/pkg/compiler/lib/src/world.dart b/pkg/compiler/lib/src/world.dart
index 7e3770dd28faa0a10a2c6215dac9022d5f97a99d..a65b083e96d2866ab39c7c48195e328355882641 100644
--- a/pkg/compiler/lib/src/world.dart
+++ b/pkg/compiler/lib/src/world.dart
@@ -18,7 +18,7 @@ import 'elements/elements.dart'
TypedefElement;
import 'elements/resolution_types.dart';
import 'elements/types.dart';
-import 'js_backend/backend.dart' show JavaScriptBackend;
+import 'js_backend/backend_usage.dart' show BackendUsage;
import 'js_backend/interceptor_data.dart' show InterceptorData;
import 'js_backend/native_data.dart' show NativeData;
import 'ordered_typeset.dart';
@@ -364,7 +364,7 @@ abstract class OpenWorld implements World {
void registerUsedElement(MemberEntity element);
void registerTypedef(TypedefElement typedef);
- ClosedWorld closeWorld(DiagnosticReporter reporter);
+ ClosedWorld closeWorld();
/// Returns an iterable over all mixin applications that mixin [cls].
Iterable<ClassEntity> allMixinUsesOf(ClassEntity cls);
@@ -384,8 +384,11 @@ enum ClassQuery {
}
abstract class ClosedWorldBase implements ClosedWorld, ClosedWorldRefiner {
- final JavaScriptBackend _backend;
- InterceptorData get interceptorData => _backend.interceptorData;
+ final ConstantSystem constantSystem;
+ final NativeData nativeData;
+ final InterceptorData interceptorData;
+ final BackendUsage _backendUsage;
+
FunctionSet _allFunctions;
final Iterable<TypedefElement> _allTypedefs;
@@ -419,8 +422,11 @@ abstract class ClosedWorldBase implements ClosedWorld, ClosedWorldRefiner {
final ResolutionWorldBuilder _resolverWorld;
ClosedWorldBase(
- {JavaScriptBackend backend,
- this.commonElements,
+ {this.commonElements,
+ this.constantSystem,
+ this.nativeData,
+ this.interceptorData,
+ BackendUsage backendUsage,
ResolutionWorldBuilder resolutionWorldBuilder,
FunctionSetBuilder functionSetBuilder,
Iterable<TypedefElement> allTypedefs,
@@ -428,7 +434,7 @@ abstract class ClosedWorldBase implements ClosedWorld, ClosedWorldRefiner {
Map<ClassEntity, Set<ClassEntity>> typesImplementedBySubclasses,
Map<ClassEntity, ClassHierarchyNode> classHierarchyNodes,
Map<ClassEntity, ClassSet> classSets})
- : this._backend = backend,
+ : this._backendUsage = backendUsage,
this._resolverWorld = resolutionWorldBuilder,
this._allTypedefs = allTypedefs,
this._mixinUses = mixinUses,
@@ -439,8 +445,6 @@ abstract class ClosedWorldBase implements ClosedWorld, ClosedWorldRefiner {
_allFunctions = functionSetBuilder.close(this);
}
- NativeData get nativeData => _backend.nativeData;
-
@override
ClosedWorld get closedWorld => this;
@@ -455,8 +459,6 @@ abstract class ClosedWorldBase implements ClosedWorld, ClosedWorldRefiner {
return _commonMasks;
}
- ConstantSystem get constantSystem => _backend.constantSystem;
-
TypeMask getCachedMask(ClassEntity base, int flags, TypeMask createMask()) {
Map<ClassEntity, TypeMask> cachedMasks =
_canonicalizedTypeMasks[flags] ??= <ClassEntity, TypeMask>{};
@@ -469,6 +471,18 @@ abstract class ClosedWorldBase implements ClosedWorld, ClosedWorldRefiner {
bool _checkInvariants(ClassEntity cls, {bool mustBeInstantiated: true});
+ OrderedTypeSet _getOrderedTypeSet(ClassEntity cls);
+
+ int _getHierarchyDepth(ClassEntity cls);
+
+ ClassEntity _getSuperClass(ClassEntity cls);
+
+ Iterable<ClassEntity> _getInterfaces(ClassEntity cls);
+
+ ClassEntity _getAppliedMixin(ClassEntity cls);
+
+ bool _isNamedMixinApplication(ClassEntity cls);
+
@override
bool isInstantiated(ClassEntity cls) {
assert(_checkClass(cls));
@@ -809,6 +823,130 @@ abstract class ClosedWorldBase implements ClosedWorld, ClosedWorldRefiner {
}
}
+ /// Returns an iterable over the common supertypes of the [classes].
+ Iterable<ClassEntity> commonSupertypesOf(Iterable<ClassEntity> classes) {
+ Iterator<ClassEntity> iterator = classes.iterator;
+ if (!iterator.moveNext()) return const <ClassEntity>[];
+
+ ClassEntity cls = iterator.current;
+ assert(_checkInvariants(cls));
+ OrderedTypeSet typeSet = _getOrderedTypeSet(cls);
+ if (!iterator.moveNext()) return typeSet.types.map((type) => type.element);
+
+ int depth = typeSet.maxDepth;
+ Link<OrderedTypeSet> otherTypeSets = const Link<OrderedTypeSet>();
+ do {
+ ClassEntity otherClass = iterator.current;
+ assert(_checkInvariants(otherClass));
+ OrderedTypeSet otherTypeSet = _getOrderedTypeSet(otherClass);
+ otherTypeSets = otherTypeSets.prepend(otherTypeSet);
+ if (otherTypeSet.maxDepth < depth) {
+ depth = otherTypeSet.maxDepth;
+ }
+ } while (iterator.moveNext());
+
+ List<ClassEntity> commonSupertypes = <ClassEntity>[];
+ OUTER:
+ for (Link<InterfaceType> link = typeSet[depth];
+ link.head.element != commonElements.objectClass;
+ link = link.tail) {
+ ClassEntity cls = link.head.element;
+ for (Link<OrderedTypeSet> link = otherTypeSets;
+ !link.isEmpty;
+ link = link.tail) {
+ if (link.head.asInstanceOf(cls, _getHierarchyDepth(cls)) == null) {
+ continue OUTER;
+ }
+ }
+ commonSupertypes.add(cls);
+ }
+ commonSupertypes.add(commonElements.objectClass);
+ return commonSupertypes;
+ }
+
+ Iterable<ClassEntity> commonSubclasses(ClassEntity cls1, ClassQuery query1,
+ ClassEntity cls2, ClassQuery query2) {
+ // TODO(johnniwinther): Use [ClassSet] to compute this.
+ // Compute the set of classes that are contained in both class subsets.
+ Set<ClassEntity> common =
+ _commonContainedClasses(cls1, query1, cls2, query2);
+ if (common == null || common.isEmpty) return const <ClassEntity>[];
+ // Narrow down the candidates by only looking at common classes
+ // that do not have a superclass or supertype that will be a
+ // better candidate.
+ return common.where((ClassEntity each) {
+ bool containsSuperclass = common.contains(_getSuperClass(each));
+ // If the superclass is also a candidate, then we don't want to
+ // deal with this class. If we're only looking for a subclass we
+ // know we don't have to look at the list of interfaces because
+ // they can never be in the common set.
+ if (containsSuperclass ||
+ query1 == ClassQuery.SUBCLASS ||
+ query2 == ClassQuery.SUBCLASS) {
+ return !containsSuperclass;
+ }
+ // Run through the direct supertypes of the class. If the common
+ // set contains the direct supertype of the class, we ignore the
+ // the class because the supertype is a better candidate.
+
+ for (ClassEntity interface in _getInterfaces(each)) {
+ if (common.contains(interface)) return false;
+ }
+ return true;
+ });
+ }
+
+ /// Returns an iterable over the live mixin applications that mixin [cls].
+ Iterable<ClassEntity> mixinUsesOf(ClassEntity cls) {
+ if (_liveMixinUses == null) {
+ _liveMixinUses = new Map<ClassEntity, List<ClassEntity>>();
+ for (ClassEntity mixin in _mixinUses.keys) {
+ List<ClassEntity> uses = <ClassEntity>[];
+
+ void addLiveUse(ClassEntity mixinApplication) {
+ if (isInstantiated(mixinApplication)) {
+ uses.add(mixinApplication);
+ } else if (_isNamedMixinApplication(mixinApplication)) {
+ Set<ClassEntity> next = _mixinUses[mixinApplication];
+ if (next != null) {
+ next.forEach(addLiveUse);
+ }
+ }
+ }
+
+ _mixinUses[mixin].forEach(addLiveUse);
+ if (uses.isNotEmpty) {
+ _liveMixinUses[mixin] = uses;
+ }
+ }
+ }
+ Iterable<ClassEntity> uses = _liveMixinUses[cls];
+ return uses != null ? uses : const <ClassEntity>[];
+ }
+
+ /// Returns `true` if any live class that mixes in [mixin] is also a subclass
+ /// of [superclass].
+ bool hasAnySubclassThatMixes(ClassEntity superclass, ClassEntity mixin) {
+ return mixinUsesOf(mixin).any((ClassEntity each) {
+ return isSubclassOf(each, superclass);
+ });
+ }
+
+ /// Returns `true` if [cls] or any superclass mixes in [mixin].
+ bool isSubclassOfMixinUseOf(ClassEntity cls, ClassEntity mixin) {
+ assert(_checkClass(cls));
+ assert(_checkClass(mixin));
+ if (isUsedAsMixin(mixin)) {
+ ClassEntity current = cls;
+ while (current != null) {
+ ClassEntity currentMixin = _getAppliedMixin(cls);
+ if (currentMixin == mixin) return true;
+ current = _getSuperClass(current);
+ }
+ }
+ return false;
+ }
+
/// Returns [ClassHierarchyNode] for [cls] used to model the class hierarchies
/// of known classes.
///
@@ -848,7 +986,7 @@ abstract class ClosedWorldBase implements ClosedWorld, ClosedWorldRefiner {
TypeMask extendMaskIfReachesAll(Selector selector, TypeMask mask) {
bool canReachAll = true;
if (mask != null) {
- canReachAll = _backend.backendUsage.isInvokeOnUsed &&
+ canReachAll = _backendUsage.isInvokeOnUsed &&
mask.needsNoSuchMethodHandling(selector, this);
}
return canReachAll ? commonMasks.dynamicType : mask;
@@ -966,8 +1104,11 @@ abstract class ClosedWorldBase implements ClosedWorld, ClosedWorldRefiner {
class ClosedWorldImpl extends ClosedWorldBase {
ClosedWorldImpl(
- {JavaScriptBackend backend,
- CommonElements commonElements,
+ {CommonElements commonElements,
+ ConstantSystem constantSystem,
+ NativeData nativeData,
+ InterceptorData interceptorData,
+ BackendUsage backendUsage,
ResolutionWorldBuilder resolutionWorldBuilder,
FunctionSetBuilder functionSetBuilder,
Iterable<TypedefElement> allTypedefs,
@@ -976,8 +1117,11 @@ class ClosedWorldImpl extends ClosedWorldBase {
Map<ClassEntity, ClassHierarchyNode> classHierarchyNodes,
Map<ClassEntity, ClassSet> classSets})
: super(
- backend: backend,
commonElements: commonElements,
+ constantSystem: constantSystem,
+ nativeData: nativeData,
+ interceptorData: interceptorData,
+ backendUsage: backendUsage,
resolutionWorldBuilder: resolutionWorldBuilder,
functionSetBuilder: functionSetBuilder,
allTypedefs: allTypedefs,
@@ -987,6 +1131,7 @@ class ClosedWorldImpl extends ClosedWorldBase {
classSets: classSets);
bool _checkClass(ClassElement cls) => cls.isDeclaration;
+
bool _checkEntity(Element element) => element.isDeclaration;
bool _checkInvariants(ClassElement cls, {bool mustBeInstantiated: true}) {
@@ -1005,129 +1150,28 @@ class ClosedWorldImpl extends ClosedWorldBase {
;
}
- /// Returns an iterable over the common supertypes of the [classes].
- Iterable<ClassElement> commonSupertypesOf(Iterable<ClassElement> classes) {
- Iterator<ClassElement> iterator = classes.iterator;
- if (!iterator.moveNext()) return const <ClassElement>[];
+ OrderedTypeSet _getOrderedTypeSet(ClassElement cls) =>
+ cls.allSupertypesAndSelf;
- ClassElement cls = iterator.current;
- assert(_checkInvariants(cls));
- OrderedTypeSet typeSet = cls.allSupertypesAndSelf;
- if (!iterator.moveNext()) return typeSet.types.map((type) => type.element);
+ int _getHierarchyDepth(ClassElement cls) => cls.hierarchyDepth;
- int depth = typeSet.maxDepth;
- Link<OrderedTypeSet> otherTypeSets = const Link<OrderedTypeSet>();
- do {
- ClassElement otherClass = iterator.current;
- assert(_checkInvariants(otherClass));
- OrderedTypeSet otherTypeSet = otherClass.allSupertypesAndSelf;
- otherTypeSets = otherTypeSets.prepend(otherTypeSet);
- if (otherTypeSet.maxDepth < depth) {
- depth = otherTypeSet.maxDepth;
- }
- } while (iterator.moveNext());
+ ClassEntity _getSuperClass(ClassElement cls) => cls.superclass;
- List<ClassElement> commonSupertypes = <ClassElement>[];
- OUTER:
- for (Link<InterfaceType> link = typeSet[depth];
- link.head.element != commonElements.objectClass;
- link = link.tail) {
- ClassElement cls = link.head.element;
- for (Link<OrderedTypeSet> link = otherTypeSets;
- !link.isEmpty;
- link = link.tail) {
- if (link.head.asInstanceOf(cls, cls.hierarchyDepth) == null) {
- continue OUTER;
- }
- }
- commonSupertypes.add(cls);
- }
- commonSupertypes.add(commonElements.objectClass);
- return commonSupertypes;
- }
-
- Iterable<ClassEntity> commonSubclasses(ClassEntity cls1, ClassQuery query1,
- ClassEntity cls2, ClassQuery query2) {
- // TODO(johnniwinther): Use [ClassSet] to compute this.
- // Compute the set of classes that are contained in both class subsets.
- Set<ClassEntity> common =
- _commonContainedClasses(cls1, query1, cls2, query2);
- if (common == null || common.isEmpty) return const <ClassEntity>[];
- // Narrow down the candidates by only looking at common classes
- // that do not have a superclass or supertype that will be a
- // better candidate.
- return common.where((ClassElement each) {
- bool containsSuperclass = common.contains(each.supertype.element);
- // If the superclass is also a candidate, then we don't want to
- // deal with this class. If we're only looking for a subclass we
- // know we don't have to look at the list of interfaces because
- // they can never be in the common set.
- if (containsSuperclass ||
- query1 == ClassQuery.SUBCLASS ||
- query2 == ClassQuery.SUBCLASS) {
- return !containsSuperclass;
- }
- // Run through the direct supertypes of the class. If the common
- // set contains the direct supertype of the class, we ignore the
- // the class because the supertype is a better candidate.
- for (Link link = each.interfaces; !link.isEmpty; link = link.tail) {
- if (common.contains(link.head.element)) return false;
- }
- return true;
- });
- }
-
- /// Returns an iterable over the live mixin applications that mixin [cls].
- Iterable<ClassEntity> mixinUsesOf(ClassEntity cls) {
- if (_liveMixinUses == null) {
- _liveMixinUses = new Map<ClassEntity, List<ClassEntity>>();
- for (ClassElement mixin in _mixinUses.keys) {
- List<ClassEntity> uses = <ClassEntity>[];
-
- void addLiveUse(MixinApplicationElement mixinApplication) {
- if (isInstantiated(mixinApplication)) {
- uses.add(mixinApplication);
- } else if (mixinApplication.isNamedMixinApplication) {
- Set<ClassEntity> next = _mixinUses[mixinApplication];
- if (next != null) {
- next.forEach(addLiveUse);
- }
- }
- }
-
- _mixinUses[mixin].forEach(addLiveUse);
- if (uses.isNotEmpty) {
- _liveMixinUses[mixin] = uses;
- }
- }
+ Iterable<ClassEntity> _getInterfaces(ClassElement cls) sync* {
+ for (Link link = cls.interfaces; !link.isEmpty; link = link.tail) {
+ yield link.head.element;
}
- Iterable<ClassEntity> uses = _liveMixinUses[cls];
- return uses != null ? uses : const <ClassEntity>[];
}
- /// Returns `true` if any live class that mixes in [mixin] is also a subclass
- /// of [superclass].
- bool hasAnySubclassThatMixes(ClassEntity superclass, ClassEntity mixin) {
- return mixinUsesOf(mixin).any((ClassElement each) {
- return each.isSubclassOf(superclass);
- });
- }
+ bool _isNamedMixinApplication(ClassElement cls) =>
+ cls.isNamedMixinApplication;
- /// Returns `true` if [cls] or any superclass mixes in [mixin].
- bool isSubclassOfMixinUseOf(ClassEntity cls, ClassEntity mixin) {
- assert(_checkClass(cls));
- assert(_checkClass(mixin));
- if (isUsedAsMixin(mixin)) {
- ClassElement current = cls;
- while (current != null) {
- if (current.isMixinApplication) {
- MixinApplicationElement application = current;
- if (application.mixin == mixin) return true;
- }
- current = current.superclass;
- }
+ ClassEntity _getAppliedMixin(ClassElement cls) {
+ if (cls.isMixinApplication) {
+ MixinApplicationElement application = cls;
+ return application.mixin;
}
- return false;
+ return null;
}
@override
@@ -1216,3 +1260,93 @@ class ClosedWorldImpl extends ClosedWorldBase {
return super.getSideEffectsOfElement(element);
}
}
+
+class KernelClosedWorld extends ClosedWorldBase {
+ KernelClosedWorld(
+ {CommonElements commonElements,
+ ConstantSystem constantSystem,
+ NativeData nativeData,
+ InterceptorData interceptorData,
+ BackendUsage backendUsage,
+ ResolutionWorldBuilder resolutionWorldBuilder,
+ FunctionSetBuilder functionSetBuilder,
+ Iterable<TypedefElement> allTypedefs,
+ Map<ClassEntity, Set<ClassEntity>> mixinUses,
+ Map<ClassEntity, Set<ClassEntity>> typesImplementedBySubclasses,
+ Map<ClassEntity, ClassHierarchyNode> classHierarchyNodes,
+ Map<ClassEntity, ClassSet> classSets})
+ : super(
+ commonElements: commonElements,
+ constantSystem: constantSystem,
+ nativeData: nativeData,
+ interceptorData: interceptorData,
+ backendUsage: backendUsage,
+ resolutionWorldBuilder: resolutionWorldBuilder,
+ functionSetBuilder: functionSetBuilder,
+ allTypedefs: allTypedefs,
+ mixinUses: mixinUses,
+ typesImplementedBySubclasses: typesImplementedBySubclasses,
+ classHierarchyNodes: classHierarchyNodes,
+ classSets: classSets);
+
+ @override
+ bool hasConcreteMatch(ClassEntity cls, Selector selector,
+ {ClassEntity stopAtSuperclass}) {
+ throw new UnimplementedError('KernelClosedWorld.hasConcreteMatch');
+ }
+
+ @override
+ bool _isNamedMixinApplication(ClassEntity cls) {
+ throw new UnimplementedError('KernelClosedWorld._isNamedMixinApplication');
+ }
+
+ @override
+ ClassEntity _getAppliedMixin(ClassEntity cls) {
+ throw new UnimplementedError('KernelClosedWorld._getAppliedMixin');
+ }
+
+ @override
+ Iterable<ClassEntity> _getInterfaces(ClassEntity cls) {
+ throw new UnimplementedError('KernelClosedWorld._getInterfaces');
+ }
+
+ @override
+ ClassEntity _getSuperClass(ClassEntity cls) {
+ throw new UnimplementedError('KernelClosedWorld._getSuperClass');
+ }
+
+ @override
+ int _getHierarchyDepth(ClassEntity cls) {
+ throw new UnimplementedError('KernelClosedWorld._getHierarchyDepth');
+ }
+
+ @override
+ OrderedTypeSet _getOrderedTypeSet(ClassEntity cls) {
+ throw new UnimplementedError('KernelClosedWorld._getOrderedTypeSet');
+ }
+
+ @override
+ bool _checkInvariants(ClassEntity cls, {bool mustBeInstantiated: true}) =>
+ true;
+
+ @override
+ bool _checkClass(ClassEntity cls) => true;
+
+ @override
+ bool _checkEntity(Entity element) => true;
+
+ @override
+ void registerClosureClass(ClassElement cls) {
+ throw new UnimplementedError('KernelClosedWorld.registerClosureClass');
+ }
+
+ @override
+ String dump([ClassEntity cls]) {
+ throw new UnimplementedError('KernelClosedWorld.dump');
+ }
+
+ @override
+ bool hasElementIn(ClassEntity cls, Selector selector, Entity element) {
+ throw new UnimplementedError('KernelClosedWorld.hasElementIn');
+ }
+}

Powered by Google App Engine
This is Rietveld 408576698