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

Side by Side Diff: pkg/kernel/lib/class_hierarchy.dart

Issue 2904203002: Extract ClassHierarchyImpl implementation from ClassHierarchy. (Closed)
Patch Set: Rename ClassHierarchyImpl to ClosedWorldClassHierarchy. Created 3 years, 6 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 unified diff | Download patch
« no previous file with comments | « no previous file | pkg/kernel/lib/transformations/treeshaker.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 library kernel.class_hierarchy; 4 library kernel.class_hierarchy;
5 5
6 import 'ast.dart'; 6 import 'ast.dart';
7 import 'dart:math'; 7 import 'dart:math';
8 import 'dart:typed_data'; 8 import 'dart:typed_data';
9 import 'src/heap.dart'; 9 import 'src/heap.dart';
10 import 'type_algebra.dart'; 10 import 'type_algebra.dart';
11 11
12 /// Data structure for answering various subclassing queries. 12 /// Interface for answering various subclassing queries.
13 class ClassHierarchy { 13 /// TODO(scheglov) Several methods are not used, or used only in tests.
14 /// Check if these methods are not useful and should be removed .
15 abstract class ClassHierarchy {
16 factory ClassHierarchy(Program program) =>
17 new ClosedWorldClassHierarchy(program);
18
19 /// All classes in the program.
20 ///
21 /// The iterable is ordered so that classes occur after their super classes.
22 Iterable<Class> get classes;
23
24 Class get rootClass;
25
26 /// Returns the index of [class_] in the [classes] list.
27 int getClassIndex(Class class_);
28
29 /// True if the program contains another class that is a subtype of given one.
30 bool hasProperSubtypes(Class class_);
31
32 /// Returns the number of steps in the longest inheritance path from [class_]
33 /// to [rootClass].
34 int getClassDepth(Class class_);
35
36 /// Returns a list of classes appropriate for use in calculating a least upper
37 /// bound.
38 ///
39 /// The returned list is a list of all classes that [class_] is a subtype of
40 /// (including itself), sorted first by depth (deepest first) and then by
41 /// class index.
42 List<Class> getRankedSuperclasses(Class class_);
43
44 /// Returns the least upper bound of two interface types, as defined by Dart
45 /// 1.0.
46 ///
47 /// Given two interfaces I and J, let S_I be the set of superinterfaces of I,
48 /// let S_J be the set of superinterfaces of J, and let
49 /// S = (I union S_I) intersect (J union S_J). Furthermore, we define
50 /// S_n = {T | T in S and depth(T) = n} for any finite n where depth(T) is
51 /// the number of steps in the longest inheritance path from T to Object. Let
52 /// q be the largest number such that S_q has cardinality one. The least
53 /// upper bound of I and J is the sole element of S_q.
54 ///
55 /// This is called the "classic" least upper bound to distinguish it from the
56 /// strong mode least upper bound, which has special behaviors in the case
57 /// where one type is a subtype of the other, or where both types are based on
58 /// the same class.
59 InterfaceType getClassicLeastUpperBound(
60 InterfaceType type1, InterfaceType type2);
61
62 /// Returns the instantiation of [superclass] that is implemented by [class_],
63 /// or `null` if [class_] does not implement [superclass] at all.
64 Supertype getClassAsInstanceOf(Class class_, Class superclass);
65
66 /// Returns the instantiation of [superclass] that is implemented by [type],
67 /// or `null` if [type] does not implement [superclass] at all.
68 InterfaceType getTypeAsInstanceOf(InterfaceType type, Class superclass);
69
70 /// Returns the instance member that would respond to a dynamic dispatch of
71 /// [name] to an instance of [class_], or `null` if no such member exists.
72 ///
73 /// If [setter] is `false`, the name is dispatched as a getter or call,
74 /// and will return a field, getter, method, or operator (or null).
75 ///
76 /// If [setter] is `true`, the name is dispatched as a setter, roughly
77 /// corresponding to `name=` in the Dart specification, but note that the
78 /// returned member will not have a name ending with `=`. In this case,
79 /// a non-final field or setter (or null) will be returned.
80 ///
81 /// If the class is abstract, abstract members are ignored and the dispatch
82 /// is resolved if the class was not abstract.
83 Member getDispatchTarget(Class class_, Name name, {bool setter: false});
84
85 /// Returns the possibly abstract interface member of [class_] with the given
86 /// [name].
87 ///
88 /// If [setter] is `false`, only fields, methods, and getters with that name
89 /// will be found. If [setter] is `true`, only non-final fields and setters
90 /// will be found.
91 ///
92 /// If multiple members with that name are inherited and not overridden, the
93 /// member from the first declared supertype is returned.
94 Member getInterfaceMember(Class class_, Name name, {bool setter: false});
95
96 /// Invokes [callback] for every member declared in or inherited by [class_]
97 /// that overrides or implements a member in a supertype of [class_]
98 /// (or in rare cases, overrides a member declared in [class_]).
99 ///
100 /// We use the term "inheritable" for members that are candidates for
101 /// inheritance but may have been overridden. The "declared" members of a
102 /// mixin application are those declared in the mixed-in type. The callback is
103 /// invoked in the following cases:
104 ///
105 /// 1. A member declared in the class overrides a member inheritable through
106 /// one of the supertypes of the class.
107 ///
108 /// 2. A non-abstract member is inherited from a superclass, and in the
109 /// context of this class, it overrides an abstract member inheritable through
110 /// one of its superinterfaces.
111 ///
112 /// 3. A non-abstract member is inherited from a superclass, and it overrides
113 /// an abstract member declared in this class.
114 ///
115 /// This method will not report that a member overrides itself. A given pair
116 /// may be reported multiple times when there are multiple inheritance paths
117 /// to the overridden member.
118 ///
119 /// It is possible for two methods to override one another in both directions.
120 ///
121 /// Getters and setters are overridden separately. The [isSetter] callback
122 /// parameter determines which type of access is being overridden.
123 void forEachOverridePair(Class class_,
124 callback(Member declaredMember, Member interfaceMember, bool isSetter));
125 }
126
127 /// Implementation of [ClassHierarchy] for closed world.
128 class ClosedWorldClassHierarchy implements ClassHierarchy {
14 /// All classes in the program. 129 /// All classes in the program.
15 /// 130 ///
16 /// The list is ordered so that classes occur after their super classes. 131 /// The list is ordered so that classes occur after their super classes.
17 final List<Class> classes; 132 final List<Class> classes;
18 133
19 final Map<Class, _ClassInfo> _infoFor = <Class, _ClassInfo>{}; 134 final Map<Class, _ClassInfo> _infoFor = <Class, _ClassInfo>{};
20 135
21 ClassHierarchy(Program program) 136 ClosedWorldClassHierarchy(Program program)
22 : this._internal(program, _countClasses(program)); 137 : this._internal(program, _countClasses(program));
23 138
24 Class get rootClass => classes[0]; 139 Class get rootClass => classes[0];
25 140
26 /// Returns the index of [class_] in the [classes] list. 141 @override
27 int getClassIndex(Class class_) => _infoFor[class_].topologicalIndex; 142 int getClassIndex(Class class_) => _infoFor[class_].topologicalIndex;
28 143
29 /// True if [subclass] inherits from [superclass] though zero or more 144 /// True if [subclass] inherits from [superclass] though zero or more
30 /// `extends` relationships. 145 /// `extends` relationships.
31 bool isSubclassOf(Class subclass, Class superclass) { 146 bool isSubclassOf(Class subclass, Class superclass) {
32 if (identical(subclass, superclass)) return true; 147 if (identical(subclass, superclass)) return true;
33 return _infoFor[subclass].isSubclassOf(_infoFor[superclass]); 148 return _infoFor[subclass].isSubclassOf(_infoFor[superclass]);
34 } 149 }
35 150
36 /// True if [submixture] inherits from [superclass] though zero or more 151 /// True if [submixture] inherits from [superclass] though zero or more
(...skipping 19 matching lines...) Expand all
56 /// mixin application (i.e. [Class.mixedInType]). 171 /// mixin application (i.e. [Class.mixedInType]).
57 bool isUsedAsMixin(Class class_) { 172 bool isUsedAsMixin(Class class_) {
58 return _infoFor[class_].directMixers.isNotEmpty; 173 return _infoFor[class_].directMixers.isNotEmpty;
59 } 174 }
60 175
61 /// True if the given class is used in an `implements` clause. 176 /// True if the given class is used in an `implements` clause.
62 bool isUsedAsSuperInterface(Class class_) { 177 bool isUsedAsSuperInterface(Class class_) {
63 return _infoFor[class_].directImplementers.isNotEmpty; 178 return _infoFor[class_].directImplementers.isNotEmpty;
64 } 179 }
65 180
66 /// Returns the number of steps in the longest inheritance path from [class_] 181 @override
67 /// to [rootClass].
68 int getClassDepth(Class class_) => _infoFor[class_].depth; 182 int getClassDepth(Class class_) => _infoFor[class_].depth;
69 183
70 /// Returns a list of classes appropriate for use in calculating a least upper 184 @override
71 /// bound.
72 ///
73 /// The returned list is a list of all classes that [class_] is a subtype of
74 /// (including itself), sorted first by depth (deepest first) and then by
75 /// class index.
76 List<Class> getRankedSuperclasses(Class class_) { 185 List<Class> getRankedSuperclasses(Class class_) {
77 return _getRankedSuperclassInfos(_infoFor[class_]) 186 return _getRankedSuperclassInfos(_infoFor[class_])
78 .map((info) => info.classNode) 187 .map((info) => info.classNode)
79 .toList(); 188 .toList();
80 } 189 }
81 190
82 List<_ClassInfo> _getRankedSuperclassInfos(_ClassInfo info) { 191 List<_ClassInfo> _getRankedSuperclassInfos(_ClassInfo info) {
83 if (info.leastUpperBoundInfos != null) return info.leastUpperBoundInfos; 192 if (info.leastUpperBoundInfos != null) return info.leastUpperBoundInfos;
84 var heap = new _LubHeap()..add(info); 193 var heap = new _LubHeap()..add(info);
85 var chain = <_ClassInfo>[]; 194 var chain = <_ClassInfo>[];
86 info.leastUpperBoundInfos = chain; 195 info.leastUpperBoundInfos = chain;
87 _ClassInfo lastInfo = null; 196 _ClassInfo lastInfo = null;
88 while (heap.isNotEmpty) { 197 while (heap.isNotEmpty) {
89 var nextInfo = heap.remove(); 198 var nextInfo = heap.remove();
90 if (identical(nextInfo, lastInfo)) continue; 199 if (identical(nextInfo, lastInfo)) continue;
91 chain.add(nextInfo); 200 chain.add(nextInfo);
92 lastInfo = nextInfo; 201 lastInfo = nextInfo;
93 var classNode = nextInfo.classNode; 202 var classNode = nextInfo.classNode;
94 void addToHeap(Supertype supertype) { 203 void addToHeap(Supertype supertype) {
95 heap.add(_infoFor[supertype.classNode]); 204 heap.add(_infoFor[supertype.classNode]);
96 } 205 }
97 206
98 if (classNode.supertype != null) addToHeap(classNode.supertype); 207 if (classNode.supertype != null) addToHeap(classNode.supertype);
99 if (classNode.mixedInType != null) addToHeap(classNode.mixedInType); 208 if (classNode.mixedInType != null) addToHeap(classNode.mixedInType);
100 classNode.implementedTypes.forEach(addToHeap); 209 classNode.implementedTypes.forEach(addToHeap);
101 } 210 }
102 return chain; 211 return chain;
103 } 212 }
104 213
105 /// Returns the least upper bound of two interface types, as defined by Dart 214 @override
106 /// 1.0.
107 ///
108 /// Given two interfaces I and J, let S_I be the set of superinterfaces of I,
109 /// let S_J be the set of superinterfaces of J, and let
110 /// S = (I union S_I) intersect (J union S_J). Furthermore, we define
111 /// S_n = {T | T in S and depth(T) = n} for any finite n where depth(T) is
112 /// the number of steps in the longest inheritance path from T to Object. Let
113 /// q be the largest number such that S_q has cardinality one. The least
114 /// upper bound of I and J is the sole element of S_q.
115 ///
116 /// This is called the "classic" least upper bound to distinguish it from the
117 /// strong mode least upper bound, which has special behaviors in the case
118 /// where one type is a subtype of the other, or where both types are based on
119 /// the same class.
120 InterfaceType getClassicLeastUpperBound( 215 InterfaceType getClassicLeastUpperBound(
121 InterfaceType type1, InterfaceType type2) { 216 InterfaceType type1, InterfaceType type2) {
122 // The algorithm is: first we compute a list of superclasses for both types, 217 // The algorithm is: first we compute a list of superclasses for both types,
123 // ordered from greatest to least depth, and ordered by topological sort 218 // ordered from greatest to least depth, and ordered by topological sort
124 // index within each depth. Due to the sort order, we can find the 219 // index within each depth. Due to the sort order, we can find the
125 // intersection of these lists by a simple walk. 220 // intersection of these lists by a simple walk.
126 // 221 //
127 // Then, for each class in the intersection, determine the exact type that 222 // Then, for each class in the intersection, determine the exact type that
128 // is implemented by type1 and type2. If the types match, that type is a 223 // is implemented by type1 and type2. If the types match, that type is a
129 // candidate (it's a member of S_n). As soon as we find a candidate which 224 // candidate (it's a member of S_n). As soon as we find a candidate which
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
205 : Substitution.fromInterfaceType(type2).substituteType( 300 : Substitution.fromInterfaceType(type2).substituteType(
206 info2.genericSuperTypes[next.classNode].asInterfaceType); 301 info2.genericSuperTypes[next.classNode].asInterfaceType);
207 if (superType1 == superType2) { 302 if (superType1 == superType2) {
208 candidate = superType1; 303 candidate = superType1;
209 ++numCandidatesAtThisDepth; 304 ++numCandidatesAtThisDepth;
210 } 305 }
211 } 306 }
212 } 307 }
213 } 308 }
214 309
215 /// Returns the instantiation of [superclass] that is implemented by [class_], 310 @override
216 /// or `null` if [class_] does not implement [superclass] at all.
217 Supertype getClassAsInstanceOf(Class class_, Class superclass) { 311 Supertype getClassAsInstanceOf(Class class_, Class superclass) {
218 if (identical(class_, superclass)) return class_.asThisSupertype; 312 if (identical(class_, superclass)) return class_.asThisSupertype;
219 _ClassInfo info = _infoFor[class_]; 313 _ClassInfo info = _infoFor[class_];
220 _ClassInfo superInfo = _infoFor[superclass]; 314 _ClassInfo superInfo = _infoFor[superclass];
221 if (!info.isSubtypeOf(superInfo)) return null; 315 if (!info.isSubtypeOf(superInfo)) return null;
222 if (superclass.typeParameters.isEmpty) return superclass.asRawSupertype; 316 if (superclass.typeParameters.isEmpty) return superclass.asRawSupertype;
223 return info.genericSuperTypes[superclass]; 317 return info.genericSuperTypes[superclass];
224 } 318 }
225 319
226 /// Returns the instantiation of [superclass] that is implemented by [type], 320 @override
227 /// or `null` if [type] does not implement [superclass] at all.
228 InterfaceType getTypeAsInstanceOf(InterfaceType type, Class superclass) { 321 InterfaceType getTypeAsInstanceOf(InterfaceType type, Class superclass) {
229 Supertype castedType = getClassAsInstanceOf(type.classNode, superclass); 322 Supertype castedType = getClassAsInstanceOf(type.classNode, superclass);
230 if (castedType == null) return null; 323 if (castedType == null) return null;
231 return Substitution 324 return Substitution
232 .fromInterfaceType(type) 325 .fromInterfaceType(type)
233 .substituteType(castedType.asInterfaceType); 326 .substituteType(castedType.asInterfaceType);
234 } 327 }
235 328
236 /// Returns the instance member that would respond to a dynamic dispatch of 329 @override
237 /// [name] to an instance of [class_], or `null` if no such member exists.
238 ///
239 /// If [setter] is `false`, the name is dispatched as a getter or call,
240 /// and will return a field, getter, method, or operator (or null).
241 ///
242 /// If [setter] is `true`, the name is dispatched as a setter, roughly
243 /// corresponding to `name=` in the Dart specification, but note that the
244 /// returned member will not have a name ending with `=`. In this case,
245 /// a non-final field or setter (or null) will be returned.
246 ///
247 /// If the class is abstract, abstract members are ignored and the dispatch
248 /// is resolved if the class was not abstract.
249 Member getDispatchTarget(Class class_, Name name, {bool setter: false}) { 330 Member getDispatchTarget(Class class_, Name name, {bool setter: false}) {
250 _ClassInfo info = _infoFor[class_]; 331 _ClassInfo info = _infoFor[class_];
251 List<Member> list = 332 List<Member> list =
252 setter ? info.implementedSetters : info.implementedGettersAndCalls; 333 setter ? info.implementedSetters : info.implementedGettersAndCalls;
253 return _findMemberByName(list, name); 334 return _findMemberByName(list, name);
254 } 335 }
255 336
256 /// Returns the list of potential targets of dynamic dispatch to an instance 337 /// Returns the list of potential targets of dynamic dispatch to an instance
257 /// of [class_]. 338 /// of [class_].
258 /// 339 ///
259 /// If [setters] is `false`, only potential targets of a getter or call 340 /// If [setters] is `false`, only potential targets of a getter or call
260 /// dispatch are returned. If [setters] is `true`, only potential targets 341 /// dispatch are returned. If [setters] is `true`, only potential targets
261 /// of a setter dispatch are returned. 342 /// of a setter dispatch are returned.
262 /// 343 ///
263 /// See [getDispatchTarget] for more details. 344 /// See [getDispatchTarget] for more details.
264 /// 345 ///
265 /// The returned list should not be modified. 346 /// The returned list should not be modified.
266 List<Member> getDispatchTargets(Class class_, {bool setters: false}) { 347 List<Member> getDispatchTargets(Class class_, {bool setters: false}) {
267 _ClassInfo info = _infoFor[class_]; 348 _ClassInfo info = _infoFor[class_];
268 return setters ? info.implementedSetters : info.implementedGettersAndCalls; 349 return setters ? info.implementedSetters : info.implementedGettersAndCalls;
269 } 350 }
270 351
271 /// Returns the possibly abstract interface member of [class_] with the given 352 @override
272 /// [name].
273 ///
274 /// If [setters] is `false`, only fields, methods, and getters with that name
275 /// will be found. If [setters] is `true`, only non-final fields and setters
276 /// will be found.
277 ///
278 /// If multiple members with that name are inherited and not overidden, the
279 /// member from the first declared supertype is returned.
280 Member getInterfaceMember(Class class_, Name name, {bool setter: false}) { 353 Member getInterfaceMember(Class class_, Name name, {bool setter: false}) {
281 List<Member> list = getInterfaceMembers(class_, setters: setter); 354 List<Member> list = getInterfaceMembers(class_, setters: setter);
282 return _findMemberByName(list, name); 355 return _findMemberByName(list, name);
283 } 356 }
284 357
285 /// Returns the list of members denoting the interface for [class_], which 358 /// Returns the list of members denoting the interface for [class_], which
286 /// may include abstract members. 359 /// may include abstract members.
287 /// 360 ///
288 /// The list may contain multiple members with a given name. This happens 361 /// The list may contain multiple members with a given name. This happens
289 /// when members are inherited through different supertypes and not overridden 362 /// when members are inherited through different supertypes and not overridden
290 /// in the class. 363 /// in the class.
291 /// 364 ///
292 /// Also see [getInterfaceMember]. 365 /// Also see [getInterfaceMember].
293 List<Member> getInterfaceMembers(Class class_, {bool setters: false}) { 366 List<Member> getInterfaceMembers(Class class_, {bool setters: false}) {
294 return _buildInterfaceMembers(class_, _infoFor[class_], setters: setters); 367 return _buildInterfaceMembers(class_, _infoFor[class_], setters: setters);
295 } 368 }
296 369
297 /// Invokes [callback] for every member declared in or inherited by [class_] 370 @override
298 /// that overrides or implements a member in a supertype of [class_]
299 /// (or in rare cases, overrides a member declared in [class_]).
300 ///
301 /// We use the term "inheritable" for members that are candidates for
302 /// inheritance but may have been overridden. The "declared" members of a
303 /// mixin application are those declared in the mixed-in type. The callback is
304 /// invoked in the following cases:
305 ///
306 /// 1. A member declared in the class overrides a member inheritable through
307 /// one of the supertypes of the class.
308 ///
309 /// 2. A non-abstract member is inherited from a superclass, and in the
310 /// context of this class, it overrides an abstract member inheritable through
311 /// one of its superinterfaces.
312 ///
313 /// 3. A non-abstract member is inherited from a superclass, and it overrides
314 /// an abstract member declared in this class.
315 ///
316 /// This method will not report that a member overrides itself. A given pair
317 /// may be reported multiple times when there are multiple inheritance paths
318 /// to the overridden member.
319 ///
320 /// It is possible for two methods to override one another in both directions.
321 ///
322 /// Getters and setters are overridden separately. The [isSetter] callback
323 /// parameter determines which type of access is being overridden.
324 void forEachOverridePair(Class class_, 371 void forEachOverridePair(Class class_,
325 callback(Member declaredMember, Member interfaceMember, bool isSetter)) { 372 callback(Member declaredMember, Member interfaceMember, bool isSetter)) {
326 _ClassInfo info = _infoFor[class_]; 373 _ClassInfo info = _infoFor[class_];
327 for (var supertype in class_.supers) { 374 for (var supertype in class_.supers) {
328 var superclass = supertype.classNode; 375 var superclass = supertype.classNode;
329 var superGetters = getInterfaceMembers(superclass); 376 var superGetters = getInterfaceMembers(superclass);
330 var superSetters = getInterfaceMembers(superclass, setters: true); 377 var superSetters = getInterfaceMembers(superclass, setters: true);
331 _reportOverrides(info.implementedGettersAndCalls, superGetters, callback); 378 _reportOverrides(info.implementedGettersAndCalls, superGetters, callback);
332 _reportOverrides(info.declaredGettersAndCalls, superGetters, callback, 379 _reportOverrides(info.declaredGettersAndCalls, superGetters, callback,
333 onlyAbstract: true); 380 onlyAbstract: true);
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
375 if (!identical(declared, inherited)) { 422 if (!identical(declared, inherited)) {
376 callback(declared, inherited, isSetter); 423 callback(declared, inherited, isSetter);
377 } 424 }
378 // A given declared member may override multiple interface members, 425 // A given declared member may override multiple interface members,
379 // so only move past the interface member. 426 // so only move past the interface member.
380 ++j; 427 ++j;
381 } 428 }
382 } 429 }
383 } 430 }
384 431
385 /// True if the program contains another class that is a subtype of given one. 432 @override
386 bool hasProperSubtypes(Class class_) { 433 bool hasProperSubtypes(Class class_) {
387 // If there are no subtypes then the subtype set contains the class itself. 434 // If there are no subtypes then the subtype set contains the class itself.
388 return !getSubtypesOf(class_).isSingleton; 435 return !getSubtypesOf(class_).isSingleton;
389 } 436 }
390 437
391 /// Returns the subtypes of [class_] as an interval list. 438 /// Returns the subtypes of [class_] as an interval list.
392 ClassSet getSubtypesOf(Class class_) { 439 ClassSet getSubtypesOf(Class class_) {
393 return new ClassSet(this, _infoFor[class_].subtypeIntervalList); 440 return new ClassSet(this, _infoFor[class_].subtypeIntervalList);
394 } 441 }
395 442
396 /// Returns the subclasses of [class_] as an interval list. 443 /// Returns the subclasses of [class_] as an interval list.
397 ClassSet getSubclassesOf(Class class_) { 444 ClassSet getSubclassesOf(Class class_) {
398 return new ClassSet(this, _infoFor[class_].subclassIntervalList); 445 return new ClassSet(this, _infoFor[class_].subclassIntervalList);
399 } 446 }
400 447
401 ClassHierarchy._internal(Program program, int numberOfClasses) 448 ClosedWorldClassHierarchy._internal(Program program, int numberOfClasses)
402 : classes = new List<Class>(numberOfClasses) { 449 : classes = new List<Class>(numberOfClasses) {
403 // Build the class ordering based on a topological sort. 450 // Build the class ordering based on a topological sort.
404 for (var library in program.libraries) { 451 for (var library in program.libraries) {
405 for (var classNode in library.classes) { 452 for (var classNode in library.classes) {
406 _topologicalSortVisit(classNode); 453 _topologicalSortVisit(classNode);
407 } 454 }
408 } 455 }
409 456
410 // Build index of direct children. Do this after the topological sort so 457 // Build index of direct children. Do this after the topological sort so
411 // that super types always occur before subtypes. 458 // that super types always occur before subtypes.
(...skipping 615 matching lines...) Expand 10 before | Expand all | Expand 10 after
1027 List<Member> implementedSetters; 1074 List<Member> implementedSetters;
1028 1075
1029 List<Member> interfaceGettersAndCalls; 1076 List<Member> interfaceGettersAndCalls;
1030 List<Member> interfaceSetters; 1077 List<Member> interfaceSetters;
1031 1078
1032 _ClassInfo(this.classNode); 1079 _ClassInfo(this.classNode);
1033 } 1080 }
1034 1081
1035 /// An immutable set of classes, internally represented as an interval list. 1082 /// An immutable set of classes, internally represented as an interval list.
1036 class ClassSet { 1083 class ClassSet {
1037 final ClassHierarchy _hierarchy; 1084 final ClosedWorldClassHierarchy _hierarchy;
1038 final Uint32List _intervalList; 1085 final Uint32List _intervalList;
1039 1086
1040 ClassSet(this._hierarchy, this._intervalList); 1087 ClassSet(this._hierarchy, this._intervalList);
1041 1088
1042 bool get isEmpty => _intervalList.isEmpty; 1089 bool get isEmpty => _intervalList.isEmpty;
1043 1090
1044 bool get isSingleton { 1091 bool get isSingleton {
1045 var list = _intervalList; 1092 var list = _intervalList;
1046 return list.length == 2 && list[0] + 1 == list[1]; 1093 return list.length == 2 && list[0] + 1 == list[1];
1047 } 1094 }
(...skipping 21 matching lines...) Expand all
1069 class _LubHeap extends Heap<_ClassInfo> { 1116 class _LubHeap extends Heap<_ClassInfo> {
1070 @override 1117 @override
1071 bool sortsBefore(_ClassInfo a, _ClassInfo b) => sortsBeforeStatic(a, b); 1118 bool sortsBefore(_ClassInfo a, _ClassInfo b) => sortsBeforeStatic(a, b);
1072 1119
1073 static bool sortsBeforeStatic(_ClassInfo a, _ClassInfo b) { 1120 static bool sortsBeforeStatic(_ClassInfo a, _ClassInfo b) {
1074 if (a.depth > b.depth) return true; 1121 if (a.depth > b.depth) return true;
1075 if (a.depth < b.depth) return false; 1122 if (a.depth < b.depth) return false;
1076 return a.topologicalIndex < b.topologicalIndex; 1123 return a.topologicalIndex < b.topologicalIndex;
1077 } 1124 }
1078 } 1125 }
OLDNEW
« 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