Chromium Code Reviews| 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 637fd168f1c891cd59fa934c21897837dd8384d3..8c3ce5e56bff06b3b502e7b0fba8f7febf3d0c87 100644 |
| --- a/pkg/compiler/lib/src/universe/class_set.dart |
| +++ b/pkg/compiler/lib/src/universe/class_set.dart |
| @@ -6,6 +6,7 @@ library dart2js.world.class_set; |
| import 'dart:collection' show IterableBase; |
| +import '../common.dart'; |
| import '../elements/elements.dart' show ClassElement; |
| import '../util/enumset.dart' show EnumSet; |
| import '../util/util.dart' show Link; |
| @@ -15,6 +16,7 @@ enum Instantiation { |
| UNINSTANTIATED, |
| DIRECTLY_INSTANTIATED, |
| INDIRECTLY_INSTANTIATED, |
| + ABSTRACTLY_INSTANTIATED, |
| } |
| /// Node for [cls] in a tree forming the subclass relation of [ClassElement]s. |
| @@ -49,16 +51,18 @@ class ClassHierarchyNode { |
| static final EnumSet<Instantiation> INSTANTIATED = |
| new EnumSet<Instantiation>.fromValues(const <Instantiation>[ |
| Instantiation.DIRECTLY_INSTANTIATED, |
| - Instantiation.INDIRECTLY_INSTANTIATED |
| + Instantiation.INDIRECTLY_INSTANTIATED, |
| + Instantiation.ABSTRACTLY_INSTANTIATED, |
| ], fixed: true); |
| - /// Enum set for selecting directly instantiated classes in |
| + /// Enum set for selecting directly and abstractly instantiated classes in |
| /// [ClassHierarchyNode.subclassesByMask], |
| /// [ClassHierarchyNode.subclassesByMask] and [ClassSet.subtypesByMask]. |
| - static final EnumSet<Instantiation> DIRECTLY_INSTANTIATED = |
| - new EnumSet<Instantiation>.fromValues( |
| - const <Instantiation>[Instantiation.DIRECTLY_INSTANTIATED], |
| - fixed: true); |
| + static final EnumSet<Instantiation> ROOT_INSTANTIATED = |
| + new EnumSet<Instantiation>.fromValues(const <Instantiation>[ |
| + Instantiation.DIRECTLY_INSTANTIATED, |
| + Instantiation.ABSTRACTLY_INSTANTIATED |
| + ], fixed: true); |
| /// Enum set for selecting all classes in |
| /// [ClassHierarchyNode.subclassesByMask], |
| @@ -72,7 +76,8 @@ class ClassHierarchyNode { |
| static EnumSet<Instantiation> createMask( |
| {bool includeDirectlyInstantiated: true, |
| bool includeIndirectlyInstantiated: true, |
| - bool includeUninstantiated: true}) { |
| + bool includeUninstantiated: true, |
| + bool includeAbstractlyInstantiated: true}) { |
| EnumSet<Instantiation> mask = new EnumSet<Instantiation>(); |
| if (includeDirectlyInstantiated) { |
| mask.add(Instantiation.DIRECTLY_INSTANTIATED); |
| @@ -83,6 +88,9 @@ class ClassHierarchyNode { |
| if (includeUninstantiated) { |
| mask.add(Instantiation.UNINSTANTIATED); |
| } |
| + if (includeAbstractlyInstantiated) { |
| + mask.add(Instantiation.ABSTRACTLY_INSTANTIATED); |
| + } |
| return mask; |
| } |
| @@ -106,23 +114,47 @@ class ClassHierarchyNode { |
| void set isDirectlyInstantiated(bool value) { |
| if (value != isDirectlyInstantiated) { |
| - ClassHierarchyNode parent = parentNode; |
| - if (value) { |
| - _mask.remove(Instantiation.UNINSTANTIATED); |
| - _mask.add(Instantiation.DIRECTLY_INSTANTIATED); |
| - while (parent != null) { |
| - parent._updateInstantiatedSubclassCount(1); |
| - parent = parent.parentNode; |
| - } |
| - } else { |
| - _mask.remove(Instantiation.DIRECTLY_INSTANTIATED); |
| - if (_mask.isEmpty) { |
| - _mask.add(Instantiation.UNINSTANTIATED); |
| - } |
| - while (parent != null) { |
| - parent._updateInstantiatedSubclassCount(-1); |
| - parent = parent.parentNode; |
| - } |
| + _updateParentInstantiatedSubclassCount( |
| + Instantiation.DIRECTLY_INSTANTIATED, |
| + add: value); |
| + } |
| + } |
| + |
| + /// `true` if [cls] has been abstractly instantiated. |
|
Siggi Cherem (dart-lang)
2016/10/27 13:22:07
it would be good to add here the definition of "ab
Johnni Winther
2016/11/01 11:26:34
Done.
|
| + /// |
|
Siggi Cherem (dart-lang)
2016/10/27 13:22:07
nit: delete line
Johnni Winther
2016/11/01 11:26:35
Done.
|
| + bool get isAbstractlyInstantiated => |
| + _mask.contains(Instantiation.ABSTRACTLY_INSTANTIATED); |
| + |
| + void set isAbstractlyInstantiated(bool value) { |
| + if (value != isAbstractlyInstantiated) { |
| + _updateParentInstantiatedSubclassCount( |
| + Instantiation.ABSTRACTLY_INSTANTIATED, |
| + add: value); |
| + } |
| + } |
| + |
| + /// `true` if [cls] is either directly or abstactly instantiated. |
| + bool get isRootInstantiated => |
|
Siggi Cherem (dart-lang)
2016/10/27 13:22:07
I'm trying to think of other names for this - root
Johnni Winther
2016/11/01 11:26:35
isExplicitlyInstantiated it is!
|
| + isDirectlyInstantiated || isAbstractlyInstantiated; |
| + |
| + void _updateParentInstantiatedSubclassCount(Instantiation instantiation, |
| + {bool add}) { |
| + ClassHierarchyNode parent = parentNode; |
| + if (add) { |
| + _mask.remove(Instantiation.UNINSTANTIATED); |
| + _mask.add(instantiation); |
| + while (parent != null) { |
| + parent._updateInstantiatedSubclassCount(1); |
| + parent = parent.parentNode; |
| + } |
| + } else { |
| + _mask.remove(instantiation); |
| + if (_mask.isEmpty) { |
| + _mask.add(Instantiation.UNINSTANTIATED); |
| + } |
| + while (parent != null) { |
| + parent._updateInstantiatedSubclassCount(-1); |
| + parent = parent.parentNode; |
| } |
| } |
| } |
| @@ -188,8 +220,8 @@ class ClassHierarchyNode { |
| return false; |
| } |
| - /// `true` if [cls] has been directly or indirectly instantiated. |
| - bool get isInstantiated => isDirectlyInstantiated || isIndirectlyInstantiated; |
| + /// `true` if [cls] has been directly, indirectly, or abstractly instantiated. |
| + bool get isInstantiated => isRootInstantiated || isIndirectlyInstantiated; |
| /// Returns an [Iterable] of the subclasses of [cls] possibly including [cls]. |
| /// |
| @@ -270,9 +302,12 @@ class ClassHierarchyNode { |
| } |
| ClassElement _computeLeastUpperInstantiatedSubclass() { |
| - if (isDirectlyInstantiated) { |
| + if (isRootInstantiated) { |
| return cls; |
| } |
| + if (!isInstantiated) { |
| + return null; |
| + } |
| ClassHierarchyNode subclass; |
| for (Link<ClassHierarchyNode> link = _directSubclasses; |
| !link.isEmpty; |
| @@ -311,6 +346,9 @@ class ClassHierarchyNode { |
| if (isIndirectlyInstantiated) { |
| sb.write(' indirectly'); |
| } |
| + if (isAbstractlyInstantiated) { |
| + sb.write(' abstractly'); |
| + } |
| sb.write(' ['); |
| if (_directSubclasses.isEmpty) { |
| sb.write(']'); |
| @@ -439,7 +477,8 @@ class ClassSet { |
| int count = node.instantiatedSubclassCount; |
| if (_subtypes != null) { |
| for (ClassHierarchyNode subtypeNode in _subtypes) { |
| - if (subtypeNode.isDirectlyInstantiated) { |
| + if (subtypeNode.isDirectlyInstantiated || |
|
Siggi Cherem (dart-lang)
2016/10/27 13:22:07
can we use isRootInstantiated here too?
Johnni Winther
2016/11/01 11:26:35
Done.
|
| + subtypeNode.isAbstractlyInstantiated) { |
| count++; |
| } |
| count += subtypeNode.instantiatedSubclassCount; |
| @@ -647,7 +686,7 @@ class ClassSet { |
| } |
| ClassElement _computeLeastUpperInstantiatedSubtype() { |
| - if (node.isDirectlyInstantiated) { |
| + if (node.isRootInstantiated) { |
| return cls; |
| } |
| if (_subtypes == null) { |