Index: pkg/compiler/lib/src/universe/class_set.dart |
diff --git a/pkg/compiler/lib/src/universe/class_set.dart b/pkg/compiler/lib/src/universe/class_set.dart |
index 3790a03d097c89faf080a82f901e0d006da94eb8..bf2f31c674f94d79b16865e31f2e44e639b26cdd 100644 |
--- a/pkg/compiler/lib/src/universe/class_set.dart |
+++ b/pkg/compiler/lib/src/universe/class_set.dart |
@@ -221,10 +221,10 @@ class ClassHierarchyNode { |
EnumSet<Instantiation> mask, |
{bool strict: false}) { |
- ForEach wrapper(ClassElement cls) { |
- return predicate(cls) ? ForEach.STOP : ForEach.CONTINUE; |
+ IterationStep wrapper(ClassElement cls) { |
+ return predicate(cls) ? IterationStep.STOP : IterationStep.CONTINUE; |
} |
- return forEachSubclass(wrapper, mask, strict: strict) == ForEach.STOP; |
+ return forEachSubclass(wrapper, mask, strict: strict) == IterationStep.STOP; |
} |
/// Applies [f] to each subclass of [cls] matching the criteria specified by |
@@ -241,31 +241,31 @@ class ClassHierarchyNode { |
/// continues. The return value of the function is either [ForEach.STOP], if |
/// visitation was stopped, or [ForEach.CONTINUE] if visitation continued to |
/// the end. |
- ForEach forEachSubclass( |
+ IterationStep forEachSubclass( |
ForEachFunction f, |
EnumSet<Instantiation> mask, |
{bool strict: false}) { |
- ForEach forEach; |
+ IterationStep nextStep; |
if (!strict && mask.intersects(_mask)) { |
- forEach = f(cls); |
+ nextStep = f(cls); |
} |
// Interpret `forEach == null` as `forEach == ForEach.CONTINUE`. |
- forEach ??= ForEach.CONTINUE; |
+ nextStep ??= IterationStep.CONTINUE; |
- if (forEach == ForEach.CONTINUE) { |
+ if (nextStep == IterationStep.CONTINUE) { |
if (mask.contains(Instantiation.UNINSTANTIATED) || isInstantiated) { |
for (ClassHierarchyNode subclass in _directSubclasses) { |
- ForEach subForEach = subclass.forEachSubclass(f, mask); |
- if (subForEach == ForEach.STOP) { |
+ IterationStep subForEach = subclass.forEachSubclass(f, mask); |
+ if (subForEach == IterationStep.STOP) { |
return subForEach; |
} |
} |
} |
} |
- if (forEach == ForEach.STOP) { |
- return forEach; |
+ if (nextStep == IterationStep.STOP) { |
+ return nextStep; |
} |
- return ForEach.CONTINUE; |
+ return IterationStep.CONTINUE; |
} |
/// Returns the most specific subclass of [cls] (including [cls]) that is |
@@ -425,7 +425,23 @@ class ClassSet { |
final ClassHierarchyNode node; |
ClassElement _leastUpperInstantiatedSubtype; |
- List<ClassHierarchyNode> _directSubtypes; |
+ /// A list of the class hierarchy nodes for the subtypes that declare a |
+ /// subtype relationship to [cls] either directly or indirectly. |
+ /// |
+ /// For instance |
+ /// |
+ /// class A {} |
+ /// class B extends A {} |
+ /// class C implements B {} |
+ /// class D implements A {} |
+ /// class E extends D {} |
+ /// |
+ /// The class hierarchy nodes for classes `C` and `D` are in [_subtypes]. `C` |
+ /// because it implements `A` through `B` and `D` because it implements `A` |
+ /// directly. `E` also implements `A` through its extension of `D` and it is |
+ /// therefore included through the class hierarchy node for `D`. |
+ /// |
+ List<ClassHierarchyNode> _subtypes; |
ClassSet(this.node); |
@@ -434,8 +450,8 @@ class ClassSet { |
/// Returns the number of directly instantiated subtypes of [cls]. |
int get instantiatedSubtypeCount { |
int count = node.instantiatedSubclassCount; |
- if (_directSubtypes != null) { |
- for (ClassHierarchyNode subtypeNode in _directSubtypes) { |
+ if (_subtypes != null) { |
+ for (ClassHierarchyNode subtypeNode in _subtypes) { |
if (subtypeNode.isDirectlyInstantiated) { |
count++; |
} |
@@ -448,8 +464,8 @@ class ClassSet { |
/// Returns `true` if all instantiated subtypes of [cls] are subclasses of |
/// [cls]. |
bool get hasOnlyInstantiatedSubclasses { |
- if (_directSubtypes != null) { |
- for (ClassHierarchyNode subtypeNode in _directSubtypes) { |
+ if (_subtypes != null) { |
+ for (ClassHierarchyNode subtypeNode in _subtypes) { |
if (subtypeNode.isInstantiated) { |
return false; |
} |
@@ -495,7 +511,7 @@ class ClassSet { |
Iterable<ClassElement> subtypesByMask( |
EnumSet<Instantiation> mask, |
{bool strict: false}) { |
- if (_directSubtypes == null) { |
+ if (_subtypes == null) { |
return node.subclassesByMask( |
mask, |
strict: strict); |
@@ -534,7 +550,7 @@ class ClassSet { |
/// continues. The return value of the function is either [ForEach.STOP], if |
/// visitation was stopped, or [ForEach.CONTINUE] if visitation continued to |
/// the end. |
- ForEach forEachSubclass( |
+ IterationStep forEachSubclass( |
ForEachFunction f, |
EnumSet<Instantiation> mask, |
{bool strict: false}) { |
@@ -553,10 +569,10 @@ class ClassSet { |
EnumSet<Instantiation> mask, |
{bool strict: false}) { |
- ForEach wrapper(ClassElement cls) { |
- return predicate(cls) ? ForEach.STOP : ForEach.CONTINUE; |
+ IterationStep wrapper(ClassElement cls) { |
+ return predicate(cls) ? IterationStep.STOP : IterationStep.CONTINUE; |
} |
- return forEachSubtype(wrapper, mask, strict: strict) == ForEach.STOP; |
+ return forEachSubtype(wrapper, mask, strict: strict) == IterationStep.STOP; |
} |
/// Applies [f] to each subtype of [cls] matching the criteria specified by |
@@ -573,22 +589,22 @@ class ClassSet { |
/// continues. The return value of the function is either [ForEach.STOP], if |
/// visitation was stopped, or [ForEach.CONTINUE] if visitation continued to |
/// the end. |
- ForEach forEachSubtype( |
+ IterationStep forEachSubtype( |
ForEachFunction f, |
EnumSet<Instantiation> mask, |
{bool strict: false}) { |
- ForEach forEach = node.forEachSubclass(f, mask, strict: strict); |
- forEach ??= ForEach.CONTINUE; |
- if (forEach == ForEach.CONTINUE && _directSubtypes != null) { |
- for (ClassHierarchyNode subclass in _directSubtypes) { |
- ForEach subForEach = subclass.forEachSubclass(f, mask); |
- if (subForEach == ForEach.STOP) { |
+ IterationStep nextStep = |
+ node.forEachSubclass(f, mask, strict: strict) ?? IterationStep.CONTINUE; |
+ if (nextStep == IterationStep.CONTINUE && _subtypes != null) { |
+ for (ClassHierarchyNode subclass in _subtypes) { |
+ IterationStep subForEach = subclass.forEachSubclass(f, mask); |
+ if (subForEach == IterationStep.STOP) { |
return subForEach; |
} |
} |
} |
- assert(forEach != ForEach.SKIP_SUBCLASSES); |
- return forEach; |
+ assert(nextStep != IterationStep.SKIP_SUBCLASSES); |
+ return nextStep; |
} |
/// Adds [subtype] as a subtype of [cls]. |
@@ -596,13 +612,13 @@ class ClassSet { |
if (node.contains(subtype.cls)) { |
return; |
} |
- if (_directSubtypes == null) { |
- _directSubtypes = <ClassHierarchyNode>[subtype]; |
+ if (_subtypes == null) { |
+ _subtypes = <ClassHierarchyNode>[subtype]; |
} else { |
int hierarchyDepth = subtype.cls.hierarchyDepth; |
List<ClassHierarchyNode> newSubtypes = <ClassHierarchyNode>[]; |
bool added = false; |
- for (ClassHierarchyNode otherSubtype in _directSubtypes) { |
+ for (ClassHierarchyNode otherSubtype in _subtypes) { |
int otherHierarchyDepth = otherSubtype.cls.hierarchyDepth; |
if (hierarchyDepth == otherHierarchyDepth) { |
if (subtype == otherSubtype) { |
@@ -637,7 +653,7 @@ class ClassSet { |
if (!added) { |
newSubtypes.add(subtype); |
} |
- _directSubtypes = newSubtypes; |
+ _subtypes = newSubtypes; |
} |
} |
@@ -655,14 +671,14 @@ class ClassSet { |
if (node.isDirectlyInstantiated) { |
return cls; |
} |
- if (_directSubtypes == null) { |
+ if (_subtypes == null) { |
return node.getLubOfInstantiatedSubclasses(); |
} |
ClassHierarchyNode subtype; |
if (node.isInstantiated) { |
subtype = node; |
} |
- for (ClassHierarchyNode subnode in _directSubtypes) { |
+ for (ClassHierarchyNode subnode in _subtypes) { |
if (subnode.isInstantiated) { |
if (subtype == null) { |
subtype = subnode; |
@@ -682,8 +698,8 @@ class ClassSet { |
sb.write('[\n'); |
node.printOn(sb, ' '); |
sb.write('\n'); |
- if (_directSubtypes != null) { |
- for (ClassHierarchyNode node in _directSubtypes) { |
+ if (_subtypes != null) { |
+ for (ClassHierarchyNode node in _subtypes) { |
node.printOn(sb, ' '); |
sb.write('\n'); |
} |
@@ -841,7 +857,7 @@ class SubtypesIterator extends Iterator<ClassElement> { |
} |
if (hierarchyNodes == null) { |
// Start iterating through subtypes. |
- hierarchyNodes = iterable.subtypeSet._directSubtypes.iterator; |
+ hierarchyNodes = iterable.subtypeSet._subtypes.iterator; |
} |
while (hierarchyNodes.moveNext()) { |
elements = hierarchyNodes.current.subclassesByMask(mask).iterator; |
@@ -856,7 +872,7 @@ class SubtypesIterator extends Iterator<ClassElement> { |
/// Enum values returned from the [ForEachFunction] provided to the `forEachX` |
/// functions of [ClassHierarchyNode] and [ClassSet]. The value is used to |
/// control the continued iteration. |
-enum ForEach { |
+enum IterationStep { |
/// Iteration continues. |
CONTINUE, |
/// Iteration stops immediately. |
@@ -868,4 +884,4 @@ enum ForEach { |
/// Visiting function used for the `forEachX` functions of [ClassHierarchyNode] |
/// and [ClassSet]. The return value controls the continued iteration. If `null` |
/// is returned, iteration continues to the end. |
-typedef ForEach ForEachFunction(ClassElement cls); |
+typedef IterationStep ForEachFunction(ClassElement cls); |