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

Unified Diff: pkg/kernel/lib/class_hierarchy.dart

Issue 2904203002: Extract ClassHierarchyImpl implementation from ClassHierarchy. (Closed)
Patch Set: Created 3 years, 7 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
« no previous file with comments | « no previous file | pkg/kernel/lib/transformations/treeshaker.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: pkg/kernel/lib/class_hierarchy.dart
diff --git a/pkg/kernel/lib/class_hierarchy.dart b/pkg/kernel/lib/class_hierarchy.dart
index 8388fc481b22878102bd863a59b9f44cb2e31fbc..30ef005694024942a319482db5183e786fdd6e04 100644
--- a/pkg/kernel/lib/class_hierarchy.dart
+++ b/pkg/kernel/lib/class_hierarchy.dart
@@ -9,8 +9,122 @@ import 'dart:typed_data';
import 'src/heap.dart';
import 'type_algebra.dart';
+/// Interface for answering various subclassing queries.
+/// TODO(scheglov) Several methods are not used, or used only in tests.
+/// Check if these methods are not useful and should be removed .
+abstract class ClassHierarchy {
+ factory ClassHierarchy(Program program) => new ClassHierarchyImpl(program);
+
+ /// All classes in the program.
+ ///
+ /// The iterable is ordered so that classes occur after their super classes.
+ Iterable<Class> get classes;
+
+ Class get rootClass;
+
+ /// Returns the index of [class_] in the [classes] list.
+ int getClassIndex(Class class_);
+
+ /// True if the program contains another class that is a subtype of given one.
+ bool hasProperSubtypes(Class class_);
+
+ /// Returns the number of steps in the longest inheritance path from [class_]
+ /// to [rootClass].
+ int getClassDepth(Class class_);
+
+ /// Returns a list of classes appropriate for use in calculating a least upper
+ /// bound.
+ ///
+ /// The returned list is a list of all classes that [class_] is a subtype of
+ /// (including itself), sorted first by depth (deepest first) and then by
+ /// class index.
+ List<Class> getRankedSuperclasses(Class class_);
+
+ /// Returns the least upper bound of two interface types, as defined by Dart
+ /// 1.0.
+ ///
+ /// Given two interfaces I and J, let S_I be the set of superinterfaces of I,
+ /// let S_J be the set of superinterfaces of J, and let
+ /// S = (I union S_I) intersect (J union S_J). Furthermore, we define
+ /// S_n = {T | T in S and depth(T) = n} for any finite n where depth(T) is
+ /// the number of steps in the longest inheritance path from T to Object. Let
+ /// q be the largest number such that S_q has cardinality one. The least
+ /// upper bound of I and J is the sole element of S_q.
+ ///
+ /// This is called the "classic" least upper bound to distinguish it from the
+ /// strong mode least upper bound, which has special behaviors in the case
+ /// where one type is a subtype of the other, or where both types are based on
+ /// the same class.
+ InterfaceType getClassicLeastUpperBound(
+ InterfaceType type1, InterfaceType type2);
+
+ /// Returns the instantiation of [superclass] that is implemented by [class_],
+ /// or `null` if [class_] does not implement [superclass] at all.
+ Supertype getClassAsInstanceOf(Class class_, Class superclass);
+
+ /// Returns the instantiation of [superclass] that is implemented by [type],
+ /// or `null` if [type] does not implement [superclass] at all.
+ InterfaceType getTypeAsInstanceOf(InterfaceType type, Class superclass);
+
+ /// Returns the instance member that would respond to a dynamic dispatch of
+ /// [name] to an instance of [class_], or `null` if no such member exists.
+ ///
+ /// If [setter] is `false`, the name is dispatched as a getter or call,
+ /// and will return a field, getter, method, or operator (or null).
+ ///
+ /// If [setter] is `true`, the name is dispatched as a setter, roughly
+ /// corresponding to `name=` in the Dart specification, but note that the
+ /// returned member will not have a name ending with `=`. In this case,
+ /// a non-final field or setter (or null) will be returned.
+ ///
+ /// If the class is abstract, abstract members are ignored and the dispatch
+ /// is resolved if the class was not abstract.
+ Member getDispatchTarget(Class class_, Name name, {bool setter: false});
+
+ /// Returns the possibly abstract interface member of [class_] with the given
+ /// [name].
+ ///
+ /// If [setter] is `false`, only fields, methods, and getters with that name
+ /// will be found. If [setter] is `true`, only non-final fields and setters
+ /// will be found.
+ ///
+ /// If multiple members with that name are inherited and not overridden, the
+ /// member from the first declared supertype is returned.
+ Member getInterfaceMember(Class class_, Name name, {bool setter: false});
+
+ /// Invokes [callback] for every member declared in or inherited by [class_]
+ /// that overrides or implements a member in a supertype of [class_]
+ /// (or in rare cases, overrides a member declared in [class_]).
+ ///
+ /// We use the term "inheritable" for members that are candidates for
+ /// inheritance but may have been overridden. The "declared" members of a
+ /// mixin application are those declared in the mixed-in type. The callback is
+ /// invoked in the following cases:
+ ///
+ /// 1. A member declared in the class overrides a member inheritable through
+ /// one of the supertypes of the class.
+ ///
+ /// 2. A non-abstract member is inherited from a superclass, and in the
+ /// context of this class, it overrides an abstract member inheritable through
+ /// one of its superinterfaces.
+ ///
+ /// 3. A non-abstract member is inherited from a superclass, and it overrides
+ /// an abstract member declared in this class.
+ ///
+ /// This method will not report that a member overrides itself. A given pair
+ /// may be reported multiple times when there are multiple inheritance paths
+ /// to the overridden member.
+ ///
+ /// It is possible for two methods to override one another in both directions.
+ ///
+ /// Getters and setters are overridden separately. The [isSetter] callback
+ /// parameter determines which type of access is being overridden.
+ void forEachOverridePair(Class class_,
+ callback(Member declaredMember, Member interfaceMember, bool isSetter));
+}
+
/// Data structure for answering various subclassing queries.
-class ClassHierarchy {
+class ClassHierarchyImpl implements ClassHierarchy {
ahe 2017/05/29 13:56:18 I suggest that this class is renamed to, for examp
scheglov 2017/05/30 01:18:18 Good idea. Done.
/// All classes in the program.
///
/// The list is ordered so that classes occur after their super classes.
@@ -18,12 +132,12 @@ class ClassHierarchy {
final Map<Class, _ClassInfo> _infoFor = <Class, _ClassInfo>{};
- ClassHierarchy(Program program)
+ ClassHierarchyImpl(Program program)
: this._internal(program, _countClasses(program));
Class get rootClass => classes[0];
- /// Returns the index of [class_] in the [classes] list.
+ @override
int getClassIndex(Class class_) => _infoFor[class_].topologicalIndex;
/// True if [subclass] inherits from [superclass] though zero or more
@@ -63,16 +177,10 @@ class ClassHierarchy {
return _infoFor[class_].directImplementers.isNotEmpty;
}
- /// Returns the number of steps in the longest inheritance path from [class_]
- /// to [rootClass].
+ @override
int getClassDepth(Class class_) => _infoFor[class_].depth;
- /// Returns a list of classes appropriate for use in calculating a least upper
- /// bound.
- ///
- /// The returned list is a list of all classes that [class_] is a subtype of
- /// (including itself), sorted first by depth (deepest first) and then by
- /// class index.
+ @override
List<Class> getRankedSuperclasses(Class class_) {
return _getRankedSuperclassInfos(_infoFor[class_])
.map((info) => info.classNode)
@@ -102,21 +210,7 @@ class ClassHierarchy {
return chain;
}
- /// Returns the least upper bound of two interface types, as defined by Dart
- /// 1.0.
- ///
- /// Given two interfaces I and J, let S_I be the set of superinterfaces of I,
- /// let S_J be the set of superinterfaces of J, and let
- /// S = (I union S_I) intersect (J union S_J). Furthermore, we define
- /// S_n = {T | T in S and depth(T) = n} for any finite n where depth(T) is
- /// the number of steps in the longest inheritance path from T to Object. Let
- /// q be the largest number such that S_q has cardinality one. The least
- /// upper bound of I and J is the sole element of S_q.
- ///
- /// This is called the "classic" least upper bound to distinguish it from the
- /// strong mode least upper bound, which has special behaviors in the case
- /// where one type is a subtype of the other, or where both types are based on
- /// the same class.
+ @override
InterfaceType getClassicLeastUpperBound(
InterfaceType type1, InterfaceType type2) {
// The algorithm is: first we compute a list of superclasses for both types,
@@ -212,8 +306,7 @@ class ClassHierarchy {
}
}
- /// Returns the instantiation of [superclass] that is implemented by [class_],
- /// or `null` if [class_] does not implement [superclass] at all.
+ @override
Supertype getClassAsInstanceOf(Class class_, Class superclass) {
if (identical(class_, superclass)) return class_.asThisSupertype;
_ClassInfo info = _infoFor[class_];
@@ -223,8 +316,7 @@ class ClassHierarchy {
return info.genericSuperTypes[superclass];
}
- /// Returns the instantiation of [superclass] that is implemented by [type],
- /// or `null` if [type] does not implement [superclass] at all.
+ @override
InterfaceType getTypeAsInstanceOf(InterfaceType type, Class superclass) {
Supertype castedType = getClassAsInstanceOf(type.classNode, superclass);
if (castedType == null) return null;
@@ -233,19 +325,7 @@ class ClassHierarchy {
.substituteType(castedType.asInterfaceType);
}
- /// Returns the instance member that would respond to a dynamic dispatch of
- /// [name] to an instance of [class_], or `null` if no such member exists.
- ///
- /// If [setter] is `false`, the name is dispatched as a getter or call,
- /// and will return a field, getter, method, or operator (or null).
- ///
- /// If [setter] is `true`, the name is dispatched as a setter, roughly
- /// corresponding to `name=` in the Dart specification, but note that the
- /// returned member will not have a name ending with `=`. In this case,
- /// a non-final field or setter (or null) will be returned.
- ///
- /// If the class is abstract, abstract members are ignored and the dispatch
- /// is resolved if the class was not abstract.
+ @override
Member getDispatchTarget(Class class_, Name name, {bool setter: false}) {
_ClassInfo info = _infoFor[class_];
List<Member> list =
@@ -268,15 +348,7 @@ class ClassHierarchy {
return setters ? info.implementedSetters : info.implementedGettersAndCalls;
}
- /// Returns the possibly abstract interface member of [class_] with the given
- /// [name].
- ///
- /// If [setters] is `false`, only fields, methods, and getters with that name
- /// will be found. If [setters] is `true`, only non-final fields and setters
- /// will be found.
- ///
- /// If multiple members with that name are inherited and not overidden, the
- /// member from the first declared supertype is returned.
+ @override
Member getInterfaceMember(Class class_, Name name, {bool setter: false}) {
List<Member> list = getInterfaceMembers(class_, setters: setter);
return _findMemberByName(list, name);
@@ -294,33 +366,7 @@ class ClassHierarchy {
return _buildInterfaceMembers(class_, _infoFor[class_], setters: setters);
}
- /// Invokes [callback] for every member declared in or inherited by [class_]
- /// that overrides or implements a member in a supertype of [class_]
- /// (or in rare cases, overrides a member declared in [class_]).
- ///
- /// We use the term "inheritable" for members that are candidates for
- /// inheritance but may have been overridden. The "declared" members of a
- /// mixin application are those declared in the mixed-in type. The callback is
- /// invoked in the following cases:
- ///
- /// 1. A member declared in the class overrides a member inheritable through
- /// one of the supertypes of the class.
- ///
- /// 2. A non-abstract member is inherited from a superclass, and in the
- /// context of this class, it overrides an abstract member inheritable through
- /// one of its superinterfaces.
- ///
- /// 3. A non-abstract member is inherited from a superclass, and it overrides
- /// an abstract member declared in this class.
- ///
- /// This method will not report that a member overrides itself. A given pair
- /// may be reported multiple times when there are multiple inheritance paths
- /// to the overridden member.
- ///
- /// It is possible for two methods to override one another in both directions.
- ///
- /// Getters and setters are overridden separately. The [isSetter] callback
- /// parameter determines which type of access is being overridden.
+ @override
void forEachOverridePair(Class class_,
callback(Member declaredMember, Member interfaceMember, bool isSetter)) {
_ClassInfo info = _infoFor[class_];
@@ -382,7 +428,7 @@ class ClassHierarchy {
}
}
- /// True if the program contains another class that is a subtype of given one.
+ @override
bool hasProperSubtypes(Class class_) {
// If there are no subtypes then the subtype set contains the class itself.
return !getSubtypesOf(class_).isSingleton;
@@ -398,7 +444,7 @@ class ClassHierarchy {
return new ClassSet(this, _infoFor[class_].subclassIntervalList);
}
- ClassHierarchy._internal(Program program, int numberOfClasses)
+ ClassHierarchyImpl._internal(Program program, int numberOfClasses)
: classes = new List<Class>(numberOfClasses) {
// Build the class ordering based on a topological sort.
for (var library in program.libraries) {
@@ -1034,7 +1080,7 @@ class _ClassInfo {
/// An immutable set of classes, internally represented as an interval list.
class ClassSet {
- final ClassHierarchy _hierarchy;
+ final ClassHierarchyImpl _hierarchy;
final Uint32List _intervalList;
ClassSet(this._hierarchy, this._intervalList);
« no previous file with comments | « no previous file | pkg/kernel/lib/transformations/treeshaker.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698