mirror of
https://github.com/dart-lang/sdk
synced 2024-09-16 00:39:49 +00:00
Updates from comments.
BUG= R=sigmund@google.com Review URL: https://codereview.chromium.org/1683063002 .
This commit is contained in:
parent
583fd470d8
commit
7cbfcd69ca
|
@ -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);
|
||||
|
|
|
@ -99,7 +99,8 @@ abstract class ClassWorld {
|
|||
|
||||
/// Applies [f] to each live class that extend [cls] _not_ including [cls]
|
||||
/// itself.
|
||||
void forEachStrictSubclassOf(ClassElement cls, ForEach f(ClassElement cls));
|
||||
void forEachStrictSubclassOf(ClassElement cls,
|
||||
IterationStep f(ClassElement cls));
|
||||
|
||||
/// Returns `true` if [predicate] applies to any live class that extend [cls]
|
||||
/// _not_ including [cls] itself.
|
||||
|
@ -119,7 +120,8 @@ abstract class ClassWorld {
|
|||
|
||||
/// Applies [f] to each live class that implements [cls] _not_ including [cls]
|
||||
/// itself.
|
||||
void forEachStrictSubtypeOf(ClassElement cls, ForEach f(ClassElement cls));
|
||||
void forEachStrictSubtypeOf(ClassElement cls,
|
||||
IterationStep f(ClassElement cls));
|
||||
|
||||
/// Returns `true` if [predicate] applies to any live class that implements
|
||||
/// [cls] _not_ including [cls] itself.
|
||||
|
@ -282,7 +284,8 @@ class World implements ClassWorld {
|
|||
|
||||
/// Applies [f] to each live class that extend [cls] _not_ including [cls]
|
||||
/// itself.
|
||||
void forEachStrictSubclassOf(ClassElement cls, ForEach f(ClassElement cls)) {
|
||||
void forEachStrictSubclassOf(ClassElement cls,
|
||||
IterationStep f(ClassElement cls)) {
|
||||
ClassHierarchyNode subclasses = _classHierarchyNodes[cls.declaration];
|
||||
if (subclasses == null) return;
|
||||
subclasses.forEachSubclass(
|
||||
|
@ -336,7 +339,8 @@ class World implements ClassWorld {
|
|||
|
||||
/// Applies [f] to each live class that implements [cls] _not_ including [cls]
|
||||
/// itself.
|
||||
void forEachStrictSubtypeOf(ClassElement cls, ForEach f(ClassElement cls)) {
|
||||
void forEachStrictSubtypeOf(ClassElement cls,
|
||||
IterationStep f(ClassElement cls)) {
|
||||
ClassSet classSet = _classSets[cls.declaration];
|
||||
if (classSet == null) return;
|
||||
classSet.forEachSubtype(
|
||||
|
|
|
@ -411,7 +411,7 @@ testForEach() async {
|
|||
visited = <ClassElement>[];
|
||||
classSet.forEachSubclass((ClassElement cls) {
|
||||
visited.add(cls);
|
||||
return ForEach.CONTINUE;
|
||||
return IterationStep.CONTINUE;
|
||||
}, ClassHierarchyNode.ALL);
|
||||
|
||||
Expect.listEquals(expected, visited,
|
||||
|
@ -444,7 +444,7 @@ testForEach() async {
|
|||
visited = <ClassElement>[];
|
||||
classSet.forEachSubtype((ClassElement cls) {
|
||||
visited.add(cls);
|
||||
return ForEach.CONTINUE;
|
||||
return IterationStep.CONTINUE;
|
||||
}, ClassHierarchyNode.ALL);
|
||||
|
||||
Expect.listEquals(expected, visited,
|
||||
|
@ -478,14 +478,14 @@ testForEach() async {
|
|||
ClassSet classSet = world.getClassSet(cls);
|
||||
List<ClassElement> visited = <ClassElement>[];
|
||||
|
||||
ForEach visit(ClassElement cls) {
|
||||
IterationStep visit(ClassElement cls) {
|
||||
visited.add(cls);
|
||||
if (cls == stop) {
|
||||
return ForEach.STOP;
|
||||
return IterationStep.STOP;
|
||||
} else if (skipSubclasses.contains(cls)) {
|
||||
return ForEach.SKIP_SUBCLASSES;
|
||||
return IterationStep.SKIP_SUBCLASSES;
|
||||
}
|
||||
return ForEach.CONTINUE;
|
||||
return IterationStep.CONTINUE;
|
||||
}
|
||||
|
||||
if (forEachSubtype) {
|
||||
|
|
Loading…
Reference in a new issue