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

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

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