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

Side by Side Diff: pkg/compiler/lib/src/universe/class_set.dart

Issue 1859343004: dartfmt pkg/compiler (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 4 years, 8 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
OLDNEW
1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2015, 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 4
5 library dart2js.world.class_set; 5 library dart2js.world.class_set;
6 6
7 import 'dart:collection' show 7 import 'dart:collection' show IterableBase;
8 IterableBase; 8 import '../elements/elements.dart' show ClassElement;
9 import '../elements/elements.dart' show 9 import '../util/enumset.dart' show EnumSet;
10 ClassElement; 10 import '../util/util.dart' show Link;
11 import '../util/enumset.dart' show
12 EnumSet;
13 import '../util/util.dart' show
14 Link;
15 11
16 /// Enum for the different kinds of instantiation of a class. 12 /// Enum for the different kinds of instantiation of a class.
17 enum Instantiation { 13 enum Instantiation {
18 UNINSTANTIATED, 14 UNINSTANTIATED,
19 DIRECTLY_INSTANTIATED, 15 DIRECTLY_INSTANTIATED,
20 INDIRECTLY_INSTANTIATED, 16 INDIRECTLY_INSTANTIATED,
21 } 17 }
22 18
23 /// Node for [cls] in a tree forming the subclass relation of [ClassElement]s. 19 /// Node for [cls] in a tree forming the subclass relation of [ClassElement]s.
24 /// 20 ///
(...skipping 18 matching lines...) Expand all
43 /// | 39 /// |
44 /// D 40 /// D
45 /// | 41 /// |
46 /// E 42 /// E
47 /// 43 ///
48 class ClassHierarchyNode { 44 class ClassHierarchyNode {
49 /// Enum set for selecting instantiated classes in 45 /// Enum set for selecting instantiated classes in
50 /// [ClassHierarchyNode.subclassesByMask], 46 /// [ClassHierarchyNode.subclassesByMask],
51 /// [ClassHierarchyNode.subclassesByMask] and [ClassSet.subtypesByMask]. 47 /// [ClassHierarchyNode.subclassesByMask] and [ClassSet.subtypesByMask].
52 static final EnumSet<Instantiation> INSTANTIATED = 48 static final EnumSet<Instantiation> INSTANTIATED =
53 new EnumSet<Instantiation>.fromValues( 49 new EnumSet<Instantiation>.fromValues(const <Instantiation>[
54 const <Instantiation>[ 50 Instantiation.DIRECTLY_INSTANTIATED,
55 Instantiation.DIRECTLY_INSTANTIATED, 51 Instantiation.INDIRECTLY_INSTANTIATED
56 Instantiation.INDIRECTLY_INSTANTIATED], 52 ], fixed: true);
57 fixed: true);
58 53
59 /// Enum set for selecting directly instantiated classes in 54 /// Enum set for selecting directly instantiated classes in
60 /// [ClassHierarchyNode.subclassesByMask], 55 /// [ClassHierarchyNode.subclassesByMask],
61 /// [ClassHierarchyNode.subclassesByMask] and [ClassSet.subtypesByMask]. 56 /// [ClassHierarchyNode.subclassesByMask] and [ClassSet.subtypesByMask].
62 static final EnumSet<Instantiation> DIRECTLY_INSTANTIATED = 57 static final EnumSet<Instantiation> DIRECTLY_INSTANTIATED =
63 new EnumSet<Instantiation>.fromValues( 58 new EnumSet<Instantiation>.fromValues(
64 const <Instantiation>[Instantiation.DIRECTLY_INSTANTIATED], 59 const <Instantiation>[Instantiation.DIRECTLY_INSTANTIATED],
65 fixed: true); 60 fixed: true);
66 61
67 /// Enum set for selecting all classes in 62 /// Enum set for selecting all classes in
68 /// [ClassHierarchyNode.subclassesByMask], 63 /// [ClassHierarchyNode.subclassesByMask],
69 /// [ClassHierarchyNode.subclassesByMask] and [ClassSet.subtypesByMask]. 64 /// [ClassHierarchyNode.subclassesByMask] and [ClassSet.subtypesByMask].
70 static final EnumSet<Instantiation> ALL = 65 static final EnumSet<Instantiation> ALL =
71 new EnumSet<Instantiation>.fromValues( 66 new EnumSet<Instantiation>.fromValues(Instantiation.values, fixed: true);
72 Instantiation.values,
73 fixed: true);
74 67
75 /// Creates an enum set for selecting the returned classes in 68 /// Creates an enum set for selecting the returned classes in
76 /// [ClassHierarchyNode.subclassesByMask], 69 /// [ClassHierarchyNode.subclassesByMask],
77 /// [ClassHierarchyNode.subclassesByMask] and [ClassSet.subtypesByMask]. 70 /// [ClassHierarchyNode.subclassesByMask] and [ClassSet.subtypesByMask].
78 static EnumSet<Instantiation> createMask( 71 static EnumSet<Instantiation> createMask(
79 {bool includeDirectlyInstantiated: true, 72 {bool includeDirectlyInstantiated: true,
80 bool includeIndirectlyInstantiated: true, 73 bool includeIndirectlyInstantiated: true,
81 bool includeUninstantiated: true}) { 74 bool includeUninstantiated: true}) {
82 EnumSet<Instantiation> mask = new EnumSet<Instantiation>(); 75 EnumSet<Instantiation> mask = new EnumSet<Instantiation>();
83 if (includeDirectlyInstantiated) { 76 if (includeDirectlyInstantiated) {
84 mask.add(Instantiation.DIRECTLY_INSTANTIATED); 77 mask.add(Instantiation.DIRECTLY_INSTANTIATED);
85 } 78 }
86 if (includeIndirectlyInstantiated) { 79 if (includeIndirectlyInstantiated) {
87 mask.add(Instantiation.INDIRECTLY_INSTANTIATED); 80 mask.add(Instantiation.INDIRECTLY_INSTANTIATED);
88 } 81 }
89 if (includeUninstantiated) { 82 if (includeUninstantiated) {
90 mask.add(Instantiation.UNINSTANTIATED); 83 mask.add(Instantiation.UNINSTANTIATED);
91 } 84 }
92 return mask; 85 return mask;
93 } 86 }
94 87
95 final ClassHierarchyNode parentNode; 88 final ClassHierarchyNode parentNode;
96 final ClassElement cls; 89 final ClassElement cls;
97 final EnumSet<Instantiation> _mask = 90 final EnumSet<Instantiation> _mask = new EnumSet<Instantiation>.fromValues(
98 new EnumSet<Instantiation>.fromValues( 91 const <Instantiation>[Instantiation.UNINSTANTIATED]);
99 const <Instantiation>[Instantiation.UNINSTANTIATED]);
100 92
101 ClassElement _leastUpperInstantiatedSubclass; 93 ClassElement _leastUpperInstantiatedSubclass;
102 int _instantiatedSubclassCount = 0; 94 int _instantiatedSubclassCount = 0;
103 95
104 /// `true` if [cls] has been directly instantiated. 96 /// `true` if [cls] has been directly instantiated.
105 /// 97 ///
106 /// For instance `C` but _not_ `B` in: 98 /// For instance `C` but _not_ `B` in:
107 /// class B {} 99 /// class B {}
108 /// class C extends B {} 100 /// class C extends B {}
109 /// main() => new C(); 101 /// main() => new C();
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
196 } 188 }
197 189
198 /// `true` if [cls] has been directly or indirectly instantiated. 190 /// `true` if [cls] has been directly or indirectly instantiated.
199 bool get isInstantiated => isDirectlyInstantiated || isIndirectlyInstantiated; 191 bool get isInstantiated => isDirectlyInstantiated || isIndirectlyInstantiated;
200 192
201 /// Returns an [Iterable] of the subclasses of [cls] possibly including [cls]. 193 /// Returns an [Iterable] of the subclasses of [cls] possibly including [cls].
202 /// 194 ///
203 /// Subclasses are included if their instantiation properties intersect with 195 /// Subclasses are included if their instantiation properties intersect with
204 /// their corresponding [Instantiation] values in [mask]. If [strict] is 196 /// their corresponding [Instantiation] values in [mask]. If [strict] is
205 /// `true`, [cls] itself is _not_ returned. 197 /// `true`, [cls] itself is _not_ returned.
206 Iterable<ClassElement> subclassesByMask( 198 Iterable<ClassElement> subclassesByMask(EnumSet<Instantiation> mask,
207 EnumSet<Instantiation> mask,
208 {bool strict: false}) { 199 {bool strict: false}) {
209 return new ClassHierarchyNodeIterable( 200 return new ClassHierarchyNodeIterable(this, mask, includeRoot: !strict);
210 this, mask, includeRoot: !strict);
211 } 201 }
212 202
213 /// Applies [predicate] to each subclass of [cls] matching the criteria 203 /// Applies [predicate] to each subclass of [cls] matching the criteria
214 /// specified by [mask] and [strict]. If [predicate] returns `true` on a 204 /// specified by [mask] and [strict]. If [predicate] returns `true` on a
215 /// class, visitation is stopped immediately and the function returns `true`. 205 /// class, visitation is stopped immediately and the function returns `true`.
216 /// 206 ///
217 /// [predicate] is applied to subclasses if their instantiation properties 207 /// [predicate] is applied to subclasses if their instantiation properties
218 /// intersect with their corresponding [Instantiation] values in [mask]. If 208 /// intersect with their corresponding [Instantiation] values in [mask]. If
219 /// [strict] is `true`, [predicate] is _not_ called on [cls] itself. 209 /// [strict] is `true`, [predicate] is _not_ called on [cls] itself.
220 bool anySubclass( 210 bool anySubclass(
221 bool predicate(ClassElement cls), 211 bool predicate(ClassElement cls), EnumSet<Instantiation> mask,
222 EnumSet<Instantiation> mask,
223 {bool strict: false}) { 212 {bool strict: false}) {
224
225 IterationStep wrapper(ClassElement cls) { 213 IterationStep wrapper(ClassElement cls) {
226 return predicate(cls) ? IterationStep.STOP : IterationStep.CONTINUE; 214 return predicate(cls) ? IterationStep.STOP : IterationStep.CONTINUE;
227 } 215 }
228 return forEachSubclass(wrapper, mask, strict: strict) == IterationStep.STOP; 216 return forEachSubclass(wrapper, mask, strict: strict) == IterationStep.STOP;
229 } 217 }
230 218
231 /// Applies [f] to each subclass of [cls] matching the criteria specified by 219 /// Applies [f] to each subclass of [cls] matching the criteria specified by
232 /// [mask] and [strict]. 220 /// [mask] and [strict].
233 /// 221 ///
234 /// [f] is a applied to subclasses if their instantiation properties intersect 222 /// [f] is a applied to subclasses if their instantiation properties intersect
235 /// with their corresponding [Instantiation] values in [mask]. If [strict] is 223 /// with their corresponding [Instantiation] values in [mask]. If [strict] is
236 /// `true`, [f] is _not_ called on [cls] itself. 224 /// `true`, [f] is _not_ called on [cls] itself.
237 /// 225 ///
238 /// The visitation of subclasses can be cut short by the return value of [f]. 226 /// The visitation of subclasses can be cut short by the return value of [f].
239 /// If [ForEach.STOP] is returned, no further classes are visited and the 227 /// If [ForEach.STOP] is returned, no further classes are visited and the
240 /// function stops immediately. If [ForEach.SKIP_SUBCLASSES] is returned, the 228 /// function stops immediately. If [ForEach.SKIP_SUBCLASSES] is returned, the
241 /// subclasses of the last visited class are skipped, but visitation 229 /// subclasses of the last visited class are skipped, but visitation
242 /// continues. The return value of the function is either [ForEach.STOP], if 230 /// continues. The return value of the function is either [ForEach.STOP], if
243 /// visitation was stopped, or [ForEach.CONTINUE] if visitation continued to 231 /// visitation was stopped, or [ForEach.CONTINUE] if visitation continued to
244 /// the end. 232 /// the end.
245 IterationStep forEachSubclass( 233 IterationStep forEachSubclass(ForEachFunction f, EnumSet<Instantiation> mask,
246 ForEachFunction f,
247 EnumSet<Instantiation> mask,
248 {bool strict: false}) { 234 {bool strict: false}) {
249 IterationStep nextStep; 235 IterationStep nextStep;
250 if (!strict && mask.intersects(_mask)) { 236 if (!strict && mask.intersects(_mask)) {
251 nextStep = f(cls); 237 nextStep = f(cls);
252 } 238 }
253 // Interpret `forEach == null` as `forEach == ForEach.CONTINUE`. 239 // Interpret `forEach == null` as `forEach == ForEach.CONTINUE`.
254 nextStep ??= IterationStep.CONTINUE; 240 nextStep ??= IterationStep.CONTINUE;
255 241
256 if (nextStep == IterationStep.CONTINUE) { 242 if (nextStep == IterationStep.CONTINUE) {
257 if (mask.contains(Instantiation.UNINSTANTIATED) || isInstantiated) { 243 if (mask.contains(Instantiation.UNINSTANTIATED) || isInstantiated) {
(...skipping 22 matching lines...) Expand all
280 } 266 }
281 return _leastUpperInstantiatedSubclass; 267 return _leastUpperInstantiatedSubclass;
282 } 268 }
283 269
284 ClassElement _computeLeastUpperInstantiatedSubclass() { 270 ClassElement _computeLeastUpperInstantiatedSubclass() {
285 if (isDirectlyInstantiated) { 271 if (isDirectlyInstantiated) {
286 return cls; 272 return cls;
287 } 273 }
288 ClassHierarchyNode subclass; 274 ClassHierarchyNode subclass;
289 for (Link<ClassHierarchyNode> link = _directSubclasses; 275 for (Link<ClassHierarchyNode> link = _directSubclasses;
290 !link.isEmpty; 276 !link.isEmpty;
291 link = link.tail) { 277 link = link.tail) {
292 if (link.head.isInstantiated) { 278 if (link.head.isInstantiated) {
293 if (subclass == null) { 279 if (subclass == null) {
294 subclass = link.head; 280 subclass = link.head;
295 } else { 281 } else {
296 return cls; 282 return cls;
297 } 283 }
298 } 284 }
299 } 285 }
300 if (subclass != null) { 286 if (subclass != null) {
301 return subclass.getLubOfInstantiatedSubclasses(); 287 return subclass.getLubOfInstantiatedSubclasses();
302 } 288 }
303 return cls; 289 return cls;
304 } 290 }
305 291
306 void printOn(StringBuffer sb, String indentation, 292 void printOn(StringBuffer sb, String indentation,
307 {bool instantiatedOnly: false, 293 {bool instantiatedOnly: false,
308 bool sorted: true, 294 bool sorted: true,
309 ClassElement withRespectTo}) { 295 ClassElement withRespectTo}) {
310
311 bool isRelatedTo(ClassElement subclass) { 296 bool isRelatedTo(ClassElement subclass) {
312 return subclass == withRespectTo || 297 return subclass == withRespectTo ||
313 subclass.implementsInterface(withRespectTo); 298 subclass.implementsInterface(withRespectTo);
314 } 299 }
315 300
316 sb.write(indentation); 301 sb.write(indentation);
317 if (cls.isAbstract) { 302 if (cls.isAbstract) {
318 sb.write('abstract '); 303 sb.write('abstract ');
319 } 304 }
320 sb.write('class ${cls.name}:'); 305 sb.write('class ${cls.name}:');
321 if (isDirectlyInstantiated) { 306 if (isDirectlyInstantiated) {
322 sb.write(' directly'); 307 sb.write(' directly');
323 } 308 }
324 if (isIndirectlyInstantiated) { 309 if (isIndirectlyInstantiated) {
325 sb.write(' indirectly'); 310 sb.write(' indirectly');
326 } 311 }
327 sb.write(' ['); 312 sb.write(' [');
328 if (_directSubclasses.isEmpty) { 313 if (_directSubclasses.isEmpty) {
329 sb.write(']'); 314 sb.write(']');
330 } else { 315 } else {
331 var subclasses = _directSubclasses; 316 var subclasses = _directSubclasses;
332 if (sorted) { 317 if (sorted) {
333 subclasses = _directSubclasses.toList()..sort((a, b) { 318 subclasses = _directSubclasses.toList()
334 return a.cls.name.compareTo(b.cls.name); 319 ..sort((a, b) {
335 }); 320 return a.cls.name.compareTo(b.cls.name);
321 });
336 } 322 }
337 bool needsComma = false; 323 bool needsComma = false;
338 for (ClassHierarchyNode child in subclasses) { 324 for (ClassHierarchyNode child in subclasses) {
339 if (instantiatedOnly && !child.isInstantiated) { 325 if (instantiatedOnly && !child.isInstantiated) {
340 continue; 326 continue;
341 } 327 }
342 if (withRespectTo != null && 328 if (withRespectTo != null &&
343 !child.anySubclass(isRelatedTo, ClassHierarchyNode.ALL)) { 329 !child.anySubclass(isRelatedTo, ClassHierarchyNode.ALL)) {
344 continue; 330 continue;
345 } 331 }
346 if (needsComma) { 332 if (needsComma) {
347 sb.write(',\n'); 333 sb.write(',\n');
348 } else { 334 } else {
349 sb.write('\n'); 335 sb.write('\n');
350 } 336 }
351 child.printOn( 337 child.printOn(sb, '$indentation ',
352 sb,
353 '$indentation ',
354 instantiatedOnly: instantiatedOnly, 338 instantiatedOnly: instantiatedOnly,
355 sorted: sorted, 339 sorted: sorted,
356 withRespectTo: withRespectTo); 340 withRespectTo: withRespectTo);
357 needsComma = true; 341 needsComma = true;
358 } 342 }
359 if (needsComma) { 343 if (needsComma) {
360 sb.write('\n'); 344 sb.write('\n');
361 sb.write('$indentation]'); 345 sb.write('$indentation]');
362 } else { 346 } else {
363 sb.write(']'); 347 sb.write(']');
364 } 348 }
365 } 349 }
366 } 350 }
367 351
368 String dump({String indentation: '', 352 String dump(
369 bool instantiatedOnly: false, 353 {String indentation: '',
370 ClassElement withRespectTo}) { 354 bool instantiatedOnly: false,
355 ClassElement withRespectTo}) {
371 StringBuffer sb = new StringBuffer(); 356 StringBuffer sb = new StringBuffer();
372 printOn(sb, indentation, 357 printOn(sb, indentation,
373 instantiatedOnly: instantiatedOnly, 358 instantiatedOnly: instantiatedOnly, withRespectTo: withRespectTo);
374 withRespectTo: withRespectTo);
375 return sb.toString(); 359 return sb.toString();
376 } 360 }
377 361
378 String toString() => cls.toString(); 362 String toString() => cls.toString();
379 } 363 }
380 364
381 /// Object holding the subclass and subtype relation for a single 365 /// Object holding the subclass and subtype relation for a single
382 /// [ClassElement]. 366 /// [ClassElement].
383 /// 367 ///
384 /// The subclass relation for a class `C` is modelled through a reference to 368 /// The subclass relation for a class `C` is modelled through a reference to
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
473 } 457 }
474 } 458 }
475 return true; 459 return true;
476 } 460 }
477 461
478 /// Returns an [Iterable] of the subclasses of [cls] possibly including [cls]. 462 /// Returns an [Iterable] of the subclasses of [cls] possibly including [cls].
479 /// 463 ///
480 /// Subclasses are included if their instantiation properties intersect with 464 /// Subclasses are included if their instantiation properties intersect with
481 /// their corresponding [Instantiation] values in [mask]. If [strict] is 465 /// their corresponding [Instantiation] values in [mask]. If [strict] is
482 /// `true`, [cls] itself is _not_ returned. 466 /// `true`, [cls] itself is _not_ returned.
483 Iterable<ClassElement> subclassesByMask( 467 Iterable<ClassElement> subclassesByMask(EnumSet<Instantiation> mask,
484 EnumSet<Instantiation> mask,
485 {bool strict: false}) { 468 {bool strict: false}) {
486 return node.subclassesByMask(mask, strict: strict); 469 return node.subclassesByMask(mask, strict: strict);
487 } 470 }
488 471
489 /// Returns an [Iterable] of the subtypes of [cls] possibly including [cls]. 472 /// Returns an [Iterable] of the subtypes of [cls] possibly including [cls].
490 /// 473 ///
491 /// The directly instantiated, indirectly instantiated and uninstantiated 474 /// The directly instantiated, indirectly instantiated and uninstantiated
492 /// subtypes of [cls] are returned if [includeDirectlyInstantiated], 475 /// subtypes of [cls] are returned if [includeDirectlyInstantiated],
493 /// [includeIndirectlyInstantiated], and [includeUninstantiated] are `true`, 476 /// [includeIndirectlyInstantiated], and [includeUninstantiated] are `true`,
494 /// respectively. If [strict] is `true`, [cls] itself is _not_ returned. 477 /// respectively. If [strict] is `true`, [cls] itself is _not_ returned.
495 Iterable<ClassElement> subtypes( 478 Iterable<ClassElement> subtypes(
496 {bool includeDirectlyInstantiated: true, 479 {bool includeDirectlyInstantiated: true,
497 bool includeIndirectlyInstantiated: true, 480 bool includeIndirectlyInstantiated: true,
498 bool includeUninstantiated: true, 481 bool includeUninstantiated: true,
499 bool strict: false}) { 482 bool strict: false}) {
500 EnumSet<Instantiation> mask = ClassHierarchyNode.createMask( 483 EnumSet<Instantiation> mask = ClassHierarchyNode.createMask(
501 includeDirectlyInstantiated: includeDirectlyInstantiated, 484 includeDirectlyInstantiated: includeDirectlyInstantiated,
502 includeIndirectlyInstantiated:includeIndirectlyInstantiated, 485 includeIndirectlyInstantiated: includeIndirectlyInstantiated,
503 includeUninstantiated: includeUninstantiated); 486 includeUninstantiated: includeUninstantiated);
504 return subtypesByMask(mask, strict: strict); 487 return subtypesByMask(mask, strict: strict);
505 } 488 }
506 489
507 /// Returns an [Iterable] of the subtypes of [cls] possibly including [cls]. 490 /// Returns an [Iterable] of the subtypes of [cls] possibly including [cls].
508 /// 491 ///
509 /// Subtypes are included if their instantiation properties intersect with 492 /// Subtypes are included if their instantiation properties intersect with
510 /// their corresponding [Instantiation] values in [mask]. If [strict] is 493 /// their corresponding [Instantiation] values in [mask]. If [strict] is
511 /// `true`, [cls] itself is _not_ returned. 494 /// `true`, [cls] itself is _not_ returned.
512 Iterable<ClassElement> subtypesByMask( 495 Iterable<ClassElement> subtypesByMask(EnumSet<Instantiation> mask,
513 EnumSet<Instantiation> mask,
514 {bool strict: false}) { 496 {bool strict: false}) {
515 if (_subtypes == null) { 497 if (_subtypes == null) {
516 return node.subclassesByMask( 498 return node.subclassesByMask(mask, strict: strict);
517 mask,
518 strict: strict);
519 } 499 }
520 500
521 return new SubtypesIterable.SubtypesIterator(this, 501 return new SubtypesIterable.SubtypesIterator(this, mask,
522 mask,
523 includeRoot: !strict); 502 includeRoot: !strict);
524 } 503 }
525 504
526 /// Applies [predicate] to each subclass of [cls] matching the criteria 505 /// Applies [predicate] to each subclass of [cls] matching the criteria
527 /// specified by [mask] and [strict]. If [predicate] returns `true` on a 506 /// specified by [mask] and [strict]. If [predicate] returns `true` on a
528 /// class, visitation is stopped immediately and the function returns `true`. 507 /// class, visitation is stopped immediately and the function returns `true`.
529 /// 508 ///
530 /// [predicate] is applied to subclasses if their instantiation properties 509 /// [predicate] is applied to subclasses if their instantiation properties
531 /// intersect with their corresponding [Instantiation] values in [mask]. If 510 /// intersect with their corresponding [Instantiation] values in [mask]. If
532 /// [strict] is `true`, [predicate] is _not_ called on [cls] itself. 511 /// [strict] is `true`, [predicate] is _not_ called on [cls] itself.
533 bool anySubclass( 512 bool anySubclass(
534 bool predicate(ClassElement cls), 513 bool predicate(ClassElement cls), EnumSet<Instantiation> mask,
535 EnumSet<Instantiation> mask,
536 {bool strict: false}) { 514 {bool strict: false}) {
537 return node.anySubclass(predicate, mask, strict: strict); 515 return node.anySubclass(predicate, mask, strict: strict);
538 } 516 }
539 517
540 /// Applies [f] to each subclass of [cls] matching the criteria specified by 518 /// Applies [f] to each subclass of [cls] matching the criteria specified by
541 /// [mask] and [strict]. 519 /// [mask] and [strict].
542 /// 520 ///
543 /// [f] is a applied to subclasses if their instantiation properties intersect 521 /// [f] is a applied to subclasses if their instantiation properties intersect
544 /// with their corresponding [Instantiation] values in [mask]. If [strict] is 522 /// with their corresponding [Instantiation] values in [mask]. If [strict] is
545 /// `true`, [f] is _not_ called on [cls] itself. 523 /// `true`, [f] is _not_ called on [cls] itself.
546 /// 524 ///
547 /// The visitation of subclasses can be cut short by the return value of [f]. 525 /// The visitation of subclasses can be cut short by the return value of [f].
548 /// If [ForEach.STOP] is returned, no further classes are visited and the 526 /// If [ForEach.STOP] is returned, no further classes are visited and the
549 /// function stops immediately. If [ForEach.SKIP_SUBCLASSES] is returned, the 527 /// function stops immediately. If [ForEach.SKIP_SUBCLASSES] is returned, the
550 /// subclasses of the last visited class are skipped, but visitation 528 /// subclasses of the last visited class are skipped, but visitation
551 /// continues. The return value of the function is either [ForEach.STOP], if 529 /// continues. The return value of the function is either [ForEach.STOP], if
552 /// visitation was stopped, or [ForEach.CONTINUE] if visitation continued to 530 /// visitation was stopped, or [ForEach.CONTINUE] if visitation continued to
553 /// the end. 531 /// the end.
554 IterationStep forEachSubclass( 532 IterationStep forEachSubclass(ForEachFunction f, EnumSet<Instantiation> mask,
555 ForEachFunction f,
556 EnumSet<Instantiation> mask,
557 {bool strict: false}) { 533 {bool strict: false}) {
558 return node.forEachSubclass(f, mask, strict: strict); 534 return node.forEachSubclass(f, mask, strict: strict);
559 } 535 }
560 536
561 /// Applies [predicate] to each subtype of [cls] matching the criteria 537 /// Applies [predicate] to each subtype of [cls] matching the criteria
562 /// specified by [mask] and [strict]. If [predicate] returns `true` on a 538 /// specified by [mask] and [strict]. If [predicate] returns `true` on a
563 /// class, visitation is stopped immediately and the function returns `true`. 539 /// class, visitation is stopped immediately and the function returns `true`.
564 /// 540 ///
565 /// [predicate] is applied to subtypes if their instantiation properties 541 /// [predicate] is applied to subtypes if their instantiation properties
566 /// intersect with their corresponding [Instantiation] values in [mask]. If 542 /// intersect with their corresponding [Instantiation] values in [mask]. If
567 /// [strict] is `true`, [predicate] is _not_ called on [cls] itself. 543 /// [strict] is `true`, [predicate] is _not_ called on [cls] itself.
568 bool anySubtype( 544 bool anySubtype(bool predicate(ClassElement cls), EnumSet<Instantiation> mask,
569 bool predicate(ClassElement cls),
570 EnumSet<Instantiation> mask,
571 {bool strict: false}) { 545 {bool strict: false}) {
572
573 IterationStep wrapper(ClassElement cls) { 546 IterationStep wrapper(ClassElement cls) {
574 return predicate(cls) ? IterationStep.STOP : IterationStep.CONTINUE; 547 return predicate(cls) ? IterationStep.STOP : IterationStep.CONTINUE;
575 } 548 }
576 return forEachSubtype(wrapper, mask, strict: strict) == IterationStep.STOP; 549 return forEachSubtype(wrapper, mask, strict: strict) == IterationStep.STOP;
577 } 550 }
578 551
579 /// Applies [f] to each subtype of [cls] matching the criteria specified by 552 /// Applies [f] to each subtype of [cls] matching the criteria specified by
580 /// [mask] and [strict]. 553 /// [mask] and [strict].
581 /// 554 ///
582 /// [f] is a applied to subtypes if their instantiation properties intersect 555 /// [f] is a applied to subtypes if their instantiation properties intersect
583 /// with their corresponding [Instantiation] values in [mask]. If [strict] is 556 /// with their corresponding [Instantiation] values in [mask]. If [strict] is
584 /// `true`, [f] is _not_ called on [cls] itself. 557 /// `true`, [f] is _not_ called on [cls] itself.
585 /// 558 ///
586 /// The visitation of subtypes can be cut short by the return value of [f]. 559 /// The visitation of subtypes can be cut short by the return value of [f].
587 /// If [ForEach.STOP] is returned, no further classes are visited and the 560 /// If [ForEach.STOP] is returned, no further classes are visited and the
588 /// function stops immediately. If [ForEach.SKIP_SUBCLASSES] is returned, the 561 /// function stops immediately. If [ForEach.SKIP_SUBCLASSES] is returned, the
589 /// subclasses of the last visited class are skipped, but visitation 562 /// subclasses of the last visited class are skipped, but visitation
590 /// continues. The return value of the function is either [ForEach.STOP], if 563 /// continues. The return value of the function is either [ForEach.STOP], if
591 /// visitation was stopped, or [ForEach.CONTINUE] if visitation continued to 564 /// visitation was stopped, or [ForEach.CONTINUE] if visitation continued to
592 /// the end. 565 /// the end.
593 IterationStep forEachSubtype( 566 IterationStep forEachSubtype(ForEachFunction f, EnumSet<Instantiation> mask,
594 ForEachFunction f,
595 EnumSet<Instantiation> mask,
596 {bool strict: false}) { 567 {bool strict: false}) {
597 IterationStep nextStep = 568 IterationStep nextStep =
598 node.forEachSubclass(f, mask, strict: strict) ?? IterationStep.CONTINUE; 569 node.forEachSubclass(f, mask, strict: strict) ?? IterationStep.CONTINUE;
599 if (nextStep == IterationStep.CONTINUE && _subtypes != null) { 570 if (nextStep == IterationStep.CONTINUE && _subtypes != null) {
600 for (ClassHierarchyNode subclass in _subtypes) { 571 for (ClassHierarchyNode subclass in _subtypes) {
601 IterationStep subForEach = subclass.forEachSubclass(f, mask); 572 IterationStep subForEach = subclass.forEachSubclass(f, mask);
602 if (subForEach == IterationStep.STOP) { 573 if (subForEach == IterationStep.STOP) {
603 return subForEach; 574 return subForEach;
604 } 575 }
605 } 576 }
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
709 return sb.toString(); 680 return sb.toString();
710 } 681 }
711 } 682 }
712 683
713 /// Iterable for subclasses of a [ClassHierarchyNode]. 684 /// Iterable for subclasses of a [ClassHierarchyNode].
714 class ClassHierarchyNodeIterable extends IterableBase<ClassElement> { 685 class ClassHierarchyNodeIterable extends IterableBase<ClassElement> {
715 final ClassHierarchyNode root; 686 final ClassHierarchyNode root;
716 final EnumSet<Instantiation> mask; 687 final EnumSet<Instantiation> mask;
717 final bool includeRoot; 688 final bool includeRoot;
718 689
719 ClassHierarchyNodeIterable( 690 ClassHierarchyNodeIterable(this.root, this.mask, {this.includeRoot: true}) {
720 this.root,
721 this.mask,
722 {this.includeRoot: true}) {
723 if (root == null) throw new StateError("No root for iterable."); 691 if (root == null) throw new StateError("No root for iterable.");
724 } 692 }
725 693
726 @override 694 @override
727 Iterator<ClassElement> get iterator { 695 Iterator<ClassElement> get iterator {
728 return new ClassHierarchyNodeIterator(this); 696 return new ClassHierarchyNodeIterator(this);
729 } 697 }
730 } 698 }
731 699
732 /// Iterator for subclasses of a [ClassHierarchyNode]. 700 /// Iterator for subclasses of a [ClassHierarchyNode].
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
786 return false; 754 return false;
787 } 755 }
788 currentNode = stack.head; 756 currentNode = stack.head;
789 stack = stack.tail; 757 stack = stack.tail;
790 if (!includeUninstantiated && !currentNode.isInstantiated) { 758 if (!includeUninstantiated && !currentNode.isInstantiated) {
791 // We're only iterating instantiated classes so there is no use in 759 // We're only iterating instantiated classes so there is no use in
792 // visiting the current node and its subtree. 760 // visiting the current node and its subtree.
793 continue; 761 continue;
794 } 762 }
795 for (Link<ClassHierarchyNode> link = currentNode._directSubclasses; 763 for (Link<ClassHierarchyNode> link = currentNode._directSubclasses;
796 !link.isEmpty; 764 !link.isEmpty;
797 link = link.tail) { 765 link = link.tail) {
798 stack = stack.prepend(link.head); 766 stack = stack.prepend(link.head);
799 } 767 }
800 if (_isValid(currentNode)) { 768 if (_isValid(currentNode)) {
801 return true; 769 return true;
802 } 770 }
803 } 771 }
804 } 772 }
805 773
806 /// Returns `true` if the class of [node] is a valid result for this iterator. 774 /// Returns `true` if the class of [node] is a valid result for this iterator.
807 bool _isValid(ClassHierarchyNode node) { 775 bool _isValid(ClassHierarchyNode node) {
808 if (!includeRoot && node == root) return false; 776 if (!includeRoot && node == root) return false;
809 return mask.intersects(node._mask); 777 return mask.intersects(node._mask);
810 } 778 }
811 } 779 }
812 780
813 /// Iterable for the subtypes in a [ClassSet]. 781 /// Iterable for the subtypes in a [ClassSet].
814 class SubtypesIterable extends IterableBase<ClassElement> { 782 class SubtypesIterable extends IterableBase<ClassElement> {
815 final ClassSet subtypeSet; 783 final ClassSet subtypeSet;
816 final EnumSet<Instantiation> mask; 784 final EnumSet<Instantiation> mask;
817 final bool includeRoot; 785 final bool includeRoot;
818 786
819 SubtypesIterable.SubtypesIterator( 787 SubtypesIterable.SubtypesIterator(this.subtypeSet, this.mask,
820 this.subtypeSet,
821 this.mask,
822 {this.includeRoot: true}); 788 {this.includeRoot: true});
823 789
824 @override 790 @override
825 Iterator<ClassElement> get iterator => new SubtypesIterator(this); 791 Iterator<ClassElement> get iterator => new SubtypesIterator(this);
826 } 792 }
827 793
828 /// Iterator for the subtypes in a [ClassSet]. 794 /// Iterator for the subtypes in a [ClassSet].
829 class SubtypesIterator extends Iterator<ClassElement> { 795 class SubtypesIterator extends Iterator<ClassElement> {
830 final SubtypesIterable iterable; 796 final SubtypesIterable iterable;
831 Iterator<ClassElement> elements; 797 Iterator<ClassElement> elements;
(...skipping 10 matching lines...) Expand all
842 if (elements != null) { 808 if (elements != null) {
843 return elements.current; 809 return elements.current;
844 } 810 }
845 return null; 811 return null;
846 } 812 }
847 813
848 @override 814 @override
849 bool moveNext() { 815 bool moveNext() {
850 if (elements == null && hierarchyNodes == null) { 816 if (elements == null && hierarchyNodes == null) {
851 // Initial state. Iterate through subclasses. 817 // Initial state. Iterate through subclasses.
852 elements = iterable.subtypeSet.node.subclassesByMask( 818 elements = iterable.subtypeSet.node
853 mask, 819 .subclassesByMask(mask, strict: !includeRoot)
854 strict: !includeRoot).iterator; 820 .iterator;
855 } 821 }
856 if (elements != null && elements.moveNext()) { 822 if (elements != null && elements.moveNext()) {
857 return true; 823 return true;
858 } 824 }
859 if (hierarchyNodes == null) { 825 if (hierarchyNodes == null) {
860 // Start iterating through subtypes. 826 // Start iterating through subtypes.
861 hierarchyNodes = iterable.subtypeSet._subtypes.iterator; 827 hierarchyNodes = iterable.subtypeSet._subtypes.iterator;
862 } 828 }
863 while (hierarchyNodes.moveNext()) { 829 while (hierarchyNodes.moveNext()) {
864 elements = hierarchyNodes.current.subclassesByMask(mask).iterator; 830 elements = hierarchyNodes.current.subclassesByMask(mask).iterator;
865 if (elements.moveNext()) { 831 if (elements.moveNext()) {
866 return true; 832 return true;
867 } 833 }
868 } 834 }
869 return false; 835 return false;
870 } 836 }
871 } 837 }
872 838
873 /// Enum values returned from the [ForEachFunction] provided to the `forEachX` 839 /// Enum values returned from the [ForEachFunction] provided to the `forEachX`
874 /// functions of [ClassHierarchyNode] and [ClassSet]. The value is used to 840 /// functions of [ClassHierarchyNode] and [ClassSet]. The value is used to
875 /// control the continued iteration. 841 /// control the continued iteration.
876 enum IterationStep { 842 enum IterationStep {
877 /// Iteration continues. 843 /// Iteration continues.
878 CONTINUE, 844 CONTINUE,
845
879 /// Iteration stops immediately. 846 /// Iteration stops immediately.
880 STOP, 847 STOP,
848
881 /// Iteration skips the subclasses of the current class. 849 /// Iteration skips the subclasses of the current class.
882 SKIP_SUBCLASSES, 850 SKIP_SUBCLASSES,
883 } 851 }
884 852
885 /// Visiting function used for the `forEachX` functions of [ClassHierarchyNode] 853 /// Visiting function used for the `forEachX` functions of [ClassHierarchyNode]
886 /// and [ClassSet]. The return value controls the continued iteration. If `null` 854 /// and [ClassSet]. The return value controls the continued iteration. If `null`
887 /// is returned, iteration continues to the end. 855 /// is returned, iteration continues to the end.
888 typedef IterationStep ForEachFunction(ClassElement cls); 856 typedef IterationStep ForEachFunction(ClassElement cls);
OLDNEW
« no previous file with comments | « pkg/compiler/lib/src/universe/call_structure.dart ('k') | pkg/compiler/lib/src/universe/function_set.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698