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

Side by Side Diff: pkg/compiler/lib/src/world.dart

Issue 2443953002: Introduce isAbstractlyInstantiated to avoid exact masks of abstract classes. (Closed)
Patch Set: Updated cf. comments. Created 4 years, 1 month 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) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, 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; 5 library dart2js.world;
6 6
7 import 'closure.dart' show SynthesizedCallMethodElementX; 7 import 'closure.dart' show SynthesizedCallMethodElementX;
8 import 'common/backend_api.dart' show BackendClasses; 8 import 'common/backend_api.dart' show BackendClasses;
9 import 'common.dart'; 9 import 'common.dart';
10 import 'compiler.dart' show Compiler; 10 import 'compiler.dart' show Compiler;
11 import 'core_types.dart' show CoreClasses; 11 import 'core_types.dart' show CoreClasses;
12 import 'dart_types.dart'; 12 import 'dart_types.dart';
13 import 'elements/elements.dart' 13 import 'elements/elements.dart'
14 show 14 show
15 ClassElement, 15 ClassElement,
16 Element, 16 Element,
17 FunctionElement, 17 FunctionElement,
18 MixinApplicationElement, 18 MixinApplicationElement,
19 TypedefElement, 19 TypedefElement,
20 VariableElement; 20 VariableElement;
21 import 'js_backend/backend.dart' show JavaScriptBackend; 21 import 'js_backend/backend.dart' show JavaScriptBackend;
22 import 'ordered_typeset.dart'; 22 import 'ordered_typeset.dart';
23 import 'types/masks.dart' show CommonMasks, FlatTypeMask, TypeMask; 23 import 'types/masks.dart' show CommonMasks, FlatTypeMask, TypeMask;
24 import 'universe/class_set.dart'; 24 import 'universe/class_set.dart';
25 import 'universe/function_set.dart' show FunctionSet; 25 import 'universe/function_set.dart' show FunctionSet;
26 import 'universe/selector.dart' show Selector; 26 import 'universe/selector.dart' show Selector;
27 import 'universe/side_effects.dart' show SideEffects; 27 import 'universe/side_effects.dart' show SideEffects;
28 import 'util/enumset.dart';
28 import 'util/util.dart' show Link; 29 import 'util/util.dart' show Link;
29 30
30 /// Common superinterface for [OpenWorld] and [ClosedWorld]. 31 /// Common superinterface for [OpenWorld] and [ClosedWorld].
31 abstract class World {} 32 abstract class World {}
32 33
33 /// The [ClosedWorld] represents the information known about a program when 34 /// The [ClosedWorld] represents the information known about a program when
34 /// compiling with closed-world semantics. 35 /// compiling with closed-world semantics.
35 /// 36 ///
36 /// Given the entrypoint of an application, we can track what's reachable from 37 /// Given the entrypoint of an application, we can track what's reachable from
37 /// it, what functions are called, what classes are allocated, which native 38 /// it, what functions are called, what classes are allocated, which native
38 /// JavaScript types are touched, what language features are used, and so on. 39 /// JavaScript types are touched, what language features are used, and so on.
39 /// This precise knowledge about what's live in the program is later used in 40 /// This precise knowledge about what's live in the program is later used in
40 /// optimizations and other compiler decisions during code generation. 41 /// optimizations and other compiler decisions during code generation.
41 abstract class ClosedWorld implements World { 42 abstract class ClosedWorld implements World {
42 /// Access to core classes used by the backend. 43 /// Access to core classes used by the backend.
43 BackendClasses get backendClasses; 44 BackendClasses get backendClasses;
44 45
45 /// Access to core classes used in the Dart language. 46 /// Access to core classes used in the Dart language.
46 CoreClasses get coreClasses; 47 CoreClasses get coreClasses;
47 48
48 /// Returns `true` if [cls] is either directly or indirectly instantiated. 49 /// Returns `true` if [cls] is either directly or indirectly instantiated.
49 bool isInstantiated(ClassElement cls); 50 bool isInstantiated(ClassElement cls);
50 51
51 /// Returns `true` if [cls] is directly instantiated. 52 /// Returns `true` if [cls] is directly instantiated. This means that at
53 /// runtime instances of exactly [cls] are assumed to exist.
52 bool isDirectlyInstantiated(ClassElement cls); 54 bool isDirectlyInstantiated(ClassElement cls);
53 55
56 /// Returns `true` if [cls] is abstractly instantiated. This means that at
57 /// runtime instances of [cls] or unknown subclasses of [cls] are assumed to
58 /// exist.
59 ///
60 /// This is used to mark native and/or reflectable classes as instantiated.
61 /// For native classes we do not know the exact class that instantiates [cls]
62 /// so [cls] here represents the root of the subclasses. For reflectable
63 /// classes we need event abstract classes to be 'live' even though they
64 /// cannot themselves be instantiated.
65 bool isAbstractlyInstantiated(ClassElement cls);
66
67 /// Returns `true` if [cls] is either directly or abstractly instantiated.
68 ///
69 /// See [isDirectlyInstantiated] and [isAbstractlyInstantiated].
70 bool isExplicitlyInstantiated(ClassElement cls);
71
54 /// Returns `true` if [cls] is indirectly instantiated, that is through a 72 /// Returns `true` if [cls] is indirectly instantiated, that is through a
55 /// subclass. 73 /// subclass.
56 bool isIndirectlyInstantiated(ClassElement cls); 74 bool isIndirectlyInstantiated(ClassElement cls);
57 75
58 /// Returns `true` if [cls] is abstract and thus can only be instantiated 76 /// Returns `true` if [cls] is abstract and thus can only be instantiated
59 /// through subclasses. 77 /// through subclasses.
60 bool isAbstract(ClassElement cls); 78 bool isAbstract(ClassElement cls);
61 79
62 /// Returns `true` if [cls] is implemented by an instantiated class. 80 /// Returns `true` if [cls] is implemented by an instantiated class.
63 bool isImplemented(ClassElement cls); 81 bool isImplemented(ClassElement cls);
(...skipping 322 matching lines...) Expand 10 before | Expand all | Expand 10 after
386 } 404 }
387 405
388 @override 406 @override
389 bool isDirectlyInstantiated(ClassElement cls) { 407 bool isDirectlyInstantiated(ClassElement cls) {
390 assert(isClosed); 408 assert(isClosed);
391 ClassHierarchyNode node = _classHierarchyNodes[cls.declaration]; 409 ClassHierarchyNode node = _classHierarchyNodes[cls.declaration];
392 return node != null && node.isDirectlyInstantiated; 410 return node != null && node.isDirectlyInstantiated;
393 } 411 }
394 412
395 @override 413 @override
414 bool isAbstractlyInstantiated(ClassElement cls) {
415 assert(isClosed);
416 ClassHierarchyNode node = _classHierarchyNodes[cls.declaration];
417 return node != null && node.isAbstractlyInstantiated;
418 }
419
420 @override
421 bool isExplicitlyInstantiated(ClassElement cls) {
422 assert(isClosed);
423 ClassHierarchyNode node = _classHierarchyNodes[cls.declaration];
424 return node != null && node.isExplicitlyInstantiated;
425 }
426
427 @override
396 bool isIndirectlyInstantiated(ClassElement cls) { 428 bool isIndirectlyInstantiated(ClassElement cls) {
397 assert(isClosed); 429 assert(isClosed);
398 ClassHierarchyNode node = _classHierarchyNodes[cls.declaration]; 430 ClassHierarchyNode node = _classHierarchyNodes[cls.declaration];
399 return node != null && node.isIndirectlyInstantiated; 431 return node != null && node.isIndirectlyInstantiated;
400 } 432 }
401 433
402 @override 434 @override
403 bool isAbstract(ClassElement cls) => cls.isAbstract; 435 bool isAbstract(ClassElement cls) => cls.isAbstract;
404 436
405 /// Returns `true` if [cls] is implemented by an instantiated class. 437 /// Returns `true` if [cls] is implemented by an instantiated class.
406 bool isImplemented(ClassElement cls) { 438 bool isImplemented(ClassElement cls) {
407 assert(isClosed); 439 assert(isClosed);
408 return _compiler.resolverWorld.isImplemented(cls); 440 return _compiler.resolverWorld.isImplemented(cls);
409 } 441 }
410 442
411 /// Returns an iterable over the directly instantiated classes that extend 443 /// Returns an iterable over the directly instantiated classes that extend
412 /// [cls] possibly including [cls] itself, if it is live. 444 /// [cls] possibly including [cls] itself, if it is live.
413 Iterable<ClassElement> subclassesOf(ClassElement cls) { 445 Iterable<ClassElement> subclassesOf(ClassElement cls) {
414 assert(isClosed); 446 assert(isClosed);
415 ClassHierarchyNode hierarchy = _classHierarchyNodes[cls.declaration]; 447 ClassHierarchyNode hierarchy = _classHierarchyNodes[cls.declaration];
416 if (hierarchy == null) return const <ClassElement>[]; 448 if (hierarchy == null) return const <ClassElement>[];
417 return hierarchy.subclassesByMask(ClassHierarchyNode.DIRECTLY_INSTANTIATED); 449 return hierarchy
450 .subclassesByMask(ClassHierarchyNode.EXPLICITLY_INSTANTIATED);
418 } 451 }
419 452
420 /// Returns an iterable over the directly instantiated classes that extend 453 /// Returns an iterable over the directly instantiated classes that extend
421 /// [cls] _not_ including [cls] itself. 454 /// [cls] _not_ including [cls] itself.
422 Iterable<ClassElement> strictSubclassesOf(ClassElement cls) { 455 Iterable<ClassElement> strictSubclassesOf(ClassElement cls) {
423 assert(isClosed); 456 assert(isClosed);
424 ClassHierarchyNode subclasses = _classHierarchyNodes[cls.declaration]; 457 ClassHierarchyNode subclasses = _classHierarchyNodes[cls.declaration];
425 if (subclasses == null) return const <ClassElement>[]; 458 if (subclasses == null) return const <ClassElement>[];
426 return subclasses.subclassesByMask(ClassHierarchyNode.DIRECTLY_INSTANTIATED, 459 return subclasses.subclassesByMask(
460 ClassHierarchyNode.EXPLICITLY_INSTANTIATED,
427 strict: true); 461 strict: true);
428 } 462 }
429 463
430 /// Returns the number of live classes that extend [cls] _not_ 464 /// Returns the number of live classes that extend [cls] _not_
431 /// including [cls] itself. 465 /// including [cls] itself.
432 int strictSubclassCount(ClassElement cls) { 466 int strictSubclassCount(ClassElement cls) {
433 assert(isClosed); 467 assert(isClosed);
434 ClassHierarchyNode subclasses = _classHierarchyNodes[cls.declaration]; 468 ClassHierarchyNode subclasses = _classHierarchyNodes[cls.declaration];
435 if (subclasses == null) return 0; 469 if (subclasses == null) return 0;
436 return subclasses.instantiatedSubclassCount; 470 return subclasses.instantiatedSubclassCount;
437 } 471 }
438 472
439 /// Applies [f] to each live class that extend [cls] _not_ including [cls] 473 /// Applies [f] to each live class that extend [cls] _not_ including [cls]
440 /// itself. 474 /// itself.
441 void forEachStrictSubclassOf( 475 void forEachStrictSubclassOf(
442 ClassElement cls, IterationStep f(ClassElement cls)) { 476 ClassElement cls, IterationStep f(ClassElement cls)) {
443 assert(isClosed); 477 assert(isClosed);
444 ClassHierarchyNode subclasses = _classHierarchyNodes[cls.declaration]; 478 ClassHierarchyNode subclasses = _classHierarchyNodes[cls.declaration];
445 if (subclasses == null) return; 479 if (subclasses == null) return;
446 subclasses.forEachSubclass(f, ClassHierarchyNode.DIRECTLY_INSTANTIATED, 480 subclasses.forEachSubclass(f, ClassHierarchyNode.EXPLICITLY_INSTANTIATED,
447 strict: true); 481 strict: true);
448 } 482 }
449 483
450 /// Returns `true` if [predicate] applies to any live class that extend [cls] 484 /// Returns `true` if [predicate] applies to any live class that extend [cls]
451 /// _not_ including [cls] itself. 485 /// _not_ including [cls] itself.
452 bool anyStrictSubclassOf(ClassElement cls, bool predicate(ClassElement cls)) { 486 bool anyStrictSubclassOf(ClassElement cls, bool predicate(ClassElement cls)) {
453 assert(isClosed); 487 assert(isClosed);
454 ClassHierarchyNode subclasses = _classHierarchyNodes[cls.declaration]; 488 ClassHierarchyNode subclasses = _classHierarchyNodes[cls.declaration];
455 if (subclasses == null) return false; 489 if (subclasses == null) return false;
456 return subclasses.anySubclass( 490 return subclasses.anySubclass(
457 predicate, ClassHierarchyNode.DIRECTLY_INSTANTIATED, 491 predicate, ClassHierarchyNode.EXPLICITLY_INSTANTIATED,
458 strict: true); 492 strict: true);
459 } 493 }
460 494
461 /// Returns an iterable over the directly instantiated that implement [cls] 495 /// Returns an iterable over the directly instantiated that implement [cls]
462 /// possibly including [cls] itself, if it is live. 496 /// possibly including [cls] itself, if it is live.
463 Iterable<ClassElement> subtypesOf(ClassElement cls) { 497 Iterable<ClassElement> subtypesOf(ClassElement cls) {
464 assert(isClosed); 498 assert(isClosed);
465 ClassSet classSet = _classSets[cls.declaration]; 499 ClassSet classSet = _classSets[cls.declaration];
466 if (classSet == null) { 500 if (classSet == null) {
467 return const <ClassElement>[]; 501 return const <ClassElement>[];
468 } else { 502 } else {
469 return classSet.subtypesByMask(ClassHierarchyNode.DIRECTLY_INSTANTIATED); 503 return classSet
504 .subtypesByMask(ClassHierarchyNode.EXPLICITLY_INSTANTIATED);
470 } 505 }
471 } 506 }
472 507
473 /// Returns an iterable over the directly instantiated that implement [cls] 508 /// Returns an iterable over the directly instantiated that implement [cls]
474 /// _not_ including [cls]. 509 /// _not_ including [cls].
475 Iterable<ClassElement> strictSubtypesOf(ClassElement cls) { 510 Iterable<ClassElement> strictSubtypesOf(ClassElement cls) {
476 assert(isClosed); 511 assert(isClosed);
477 ClassSet classSet = _classSets[cls.declaration]; 512 ClassSet classSet = _classSets[cls.declaration];
478 if (classSet == null) { 513 if (classSet == null) {
479 return const <ClassElement>[]; 514 return const <ClassElement>[];
480 } else { 515 } else {
481 return classSet.subtypesByMask(ClassHierarchyNode.DIRECTLY_INSTANTIATED, 516 return classSet.subtypesByMask(ClassHierarchyNode.EXPLICITLY_INSTANTIATED,
482 strict: true); 517 strict: true);
483 } 518 }
484 } 519 }
485 520
486 /// Returns the number of live classes that implement [cls] _not_ 521 /// Returns the number of live classes that implement [cls] _not_
487 /// including [cls] itself. 522 /// including [cls] itself.
488 int strictSubtypeCount(ClassElement cls) { 523 int strictSubtypeCount(ClassElement cls) {
489 assert(isClosed); 524 assert(isClosed);
490 ClassSet classSet = _classSets[cls.declaration]; 525 ClassSet classSet = _classSets[cls.declaration];
491 if (classSet == null) return 0; 526 if (classSet == null) return 0;
492 return classSet.instantiatedSubtypeCount; 527 return classSet.instantiatedSubtypeCount;
493 } 528 }
494 529
495 /// Applies [f] to each live class that implements [cls] _not_ including [cls] 530 /// Applies [f] to each live class that implements [cls] _not_ including [cls]
496 /// itself. 531 /// itself.
497 void forEachStrictSubtypeOf( 532 void forEachStrictSubtypeOf(
498 ClassElement cls, IterationStep f(ClassElement cls)) { 533 ClassElement cls, IterationStep f(ClassElement cls)) {
499 assert(isClosed); 534 assert(isClosed);
500 ClassSet classSet = _classSets[cls.declaration]; 535 ClassSet classSet = _classSets[cls.declaration];
501 if (classSet == null) return; 536 if (classSet == null) return;
502 classSet.forEachSubtype(f, ClassHierarchyNode.DIRECTLY_INSTANTIATED, 537 classSet.forEachSubtype(f, ClassHierarchyNode.EXPLICITLY_INSTANTIATED,
503 strict: true); 538 strict: true);
504 } 539 }
505 540
506 /// Returns `true` if [predicate] applies to any live class that extend [cls] 541 /// Returns `true` if [predicate] applies to any live class that extend [cls]
507 /// _not_ including [cls] itself. 542 /// _not_ including [cls] itself.
508 bool anyStrictSubtypeOf(ClassElement cls, bool predicate(ClassElement cls)) { 543 bool anyStrictSubtypeOf(ClassElement cls, bool predicate(ClassElement cls)) {
509 assert(isClosed); 544 assert(isClosed);
510 ClassSet classSet = _classSets[cls.declaration]; 545 ClassSet classSet = _classSets[cls.declaration];
511 if (classSet == null) return false; 546 if (classSet == null) return false;
512 return classSet.anySubtype( 547 return classSet.anySubtype(
513 predicate, ClassHierarchyNode.DIRECTLY_INSTANTIATED, 548 predicate, ClassHierarchyNode.EXPLICITLY_INSTANTIATED,
514 strict: true); 549 strict: true);
515 } 550 }
516 551
517 /// Returns `true` if [a] and [b] have any known common subtypes. 552 /// Returns `true` if [a] and [b] have any known common subtypes.
518 bool haveAnyCommonSubtypes(ClassElement a, ClassElement b) { 553 bool haveAnyCommonSubtypes(ClassElement a, ClassElement b) {
519 assert(isClosed); 554 assert(isClosed);
520 ClassSet classSetA = _classSets[a.declaration]; 555 ClassSet classSetA = _classSets[a.declaration];
521 ClassSet classSetB = _classSets[b.declaration]; 556 ClassSet classSetB = _classSets[b.declaration];
522 if (classSetA == null || classSetB == null) return false; 557 if (classSetA == null || classSetB == null) return false;
523 // TODO(johnniwinther): Implement an optimized query on [ClassSet]. 558 // TODO(johnniwinther): Implement an optimized query on [ClassSet].
(...skipping 238 matching lines...) Expand 10 before | Expand all | Expand 10 after
762 if (!rootNode.isInstantiated) { 797 if (!rootNode.isInstantiated) {
763 // No subclass needs noSuchMethod handling since they are all 798 // No subclass needs noSuchMethod handling since they are all
764 // uninstantiated. 799 // uninstantiated.
765 return false; 800 return false;
766 } 801 }
767 ClassElement rootClass = rootNode.cls; 802 ClassElement rootClass = rootNode.cls;
768 if (hasConcreteMatch(rootClass, selector)) { 803 if (hasConcreteMatch(rootClass, selector)) {
769 // The root subclass has a concrete implementation so no subclass needs 804 // The root subclass has a concrete implementation so no subclass needs
770 // noSuchMethod handling. 805 // noSuchMethod handling.
771 return false; 806 return false;
772 } else if (rootNode.isDirectlyInstantiated) { 807 } else if (rootNode.isExplicitlyInstantiated) {
773 // The root class need noSuchMethod handling. 808 // The root class need noSuchMethod handling.
774 return true; 809 return true;
775 } 810 }
776 IterationStep result = rootNode.forEachSubclass((ClassElement subclass) { 811 IterationStep result = rootNode.forEachSubclass((ClassElement subclass) {
777 if (hasConcreteMatch(subclass, selector, stopAtSuperclass: rootClass)) { 812 if (hasConcreteMatch(subclass, selector, stopAtSuperclass: rootClass)) {
778 // Found a match - skip all subclasses. 813 // Found a match - skip all subclasses.
779 return IterationStep.SKIP_SUBCLASSES; 814 return IterationStep.SKIP_SUBCLASSES;
780 } else { 815 } else {
781 // Stop fast - we found a need for noSuchMethod handling. 816 // Stop fast - we found a need for noSuchMethod handling.
782 return IterationStep.STOP; 817 return IterationStep.STOP;
783 } 818 }
784 }, ClassHierarchyNode.DIRECTLY_INSTANTIATED, strict: true); 819 }, ClassHierarchyNode.EXPLICITLY_INSTANTIATED, strict: true);
785 // We stopped fast so we need noSuchMethod handling. 820 // We stopped fast so we need noSuchMethod handling.
786 return result == IterationStep.STOP; 821 return result == IterationStep.STOP;
787 } 822 }
788 823
789 ClassSet classSet = getClassSet(base); 824 ClassSet classSet = getClassSet(base);
790 ClassHierarchyNode node = classSet.node; 825 ClassHierarchyNode node = classSet.node;
791 if (query == ClassQuery.EXACT) { 826 if (query == ClassQuery.EXACT) {
792 return node.isDirectlyInstantiated && !hasConcreteMatch(base, selector); 827 return node.isDirectlyInstantiated && !hasConcreteMatch(base, selector);
793 } else if (query == ClassQuery.SUBCLASS) { 828 } else if (query == ClassQuery.SUBCLASS) {
794 return subclassesNeedNoSuchMethod(node); 829 return subclassesNeedNoSuchMethod(node);
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after
936 cls.implementsFunction(coreClasses)) { 971 cls.implementsFunction(coreClasses)) {
937 ClassSet subtypeSet = _ensureClassSet(coreClasses.functionClass); 972 ClassSet subtypeSet = _ensureClassSet(coreClasses.functionClass);
938 subtypeSet.addSubtype(node); 973 subtypeSet.addSubtype(node);
939 } 974 }
940 if (!node.isInstantiated && node.parentNode != null) { 975 if (!node.isInstantiated && node.parentNode != null) {
941 _updateSuperClassHierarchyNodeForClass(node.parentNode); 976 _updateSuperClassHierarchyNodeForClass(node.parentNode);
942 } 977 }
943 } 978 }
944 979
945 void _updateClassHierarchyNodeForClass(ClassElement cls, 980 void _updateClassHierarchyNodeForClass(ClassElement cls,
946 {bool directlyInstantiated: false}) { 981 {bool directlyInstantiated: false, bool abstractlyInstantiated: false}) {
947 ClassHierarchyNode node = getClassHierarchyNode(cls); 982 ClassHierarchyNode node = getClassHierarchyNode(cls);
948 _updateSuperClassHierarchyNodeForClass(node); 983 _updateSuperClassHierarchyNodeForClass(node);
949 if (directlyInstantiated) { 984 if (directlyInstantiated) {
950 node.isDirectlyInstantiated = true; 985 node.isDirectlyInstantiated = true;
951 } 986 }
987 if (abstractlyInstantiated) {
988 node.isAbstractlyInstantiated = true;
989 }
952 } 990 }
953 991
954 ClosedWorld closeWorld() { 992 ClosedWorld closeWorld() {
955 /// Updates the `isDirectlyInstantiated` and `isIndirectlyInstantiated` 993 /// Updates the `isDirectlyInstantiated` and `isIndirectlyInstantiated`
956 /// properties of the [ClassHierarchyNode] for [cls]. 994 /// properties of the [ClassHierarchyNode] for [cls].
957 995
958 void addSubtypes(ClassElement cls) { 996 void addSubtypes(ClassElement cls, EnumSet<Instantiation> instantiations) {
959 if (_compiler.options.hasIncrementalSupport && 997 if (_compiler.options.hasIncrementalSupport &&
960 !alreadyPopulated.add(cls)) { 998 !alreadyPopulated.add(cls)) {
961 return; 999 return;
962 } 1000 }
963 assert(cls.isDeclaration); 1001 assert(cls.isDeclaration);
964 if (!cls.isResolved) { 1002 if (!cls.isResolved) {
965 reporter.internalError(cls, 'Class "${cls.name}" is not resolved.'); 1003 reporter.internalError(cls, 'Class "${cls.name}" is not resolved.');
966 } 1004 }
967 1005
968 _updateClassHierarchyNodeForClass(cls, directlyInstantiated: true); 1006 _updateClassHierarchyNodeForClass(cls,
1007 directlyInstantiated:
1008 instantiations.contains(Instantiation.DIRECTLY_INSTANTIATED),
1009 abstractlyInstantiated:
1010 instantiations.contains(Instantiation.ABSTRACTLY_INSTANTIATED));
969 1011
970 // Walk through the superclasses, and record the types 1012 // Walk through the superclasses, and record the types
971 // implemented by that type on the superclasses. 1013 // implemented by that type on the superclasses.
972 ClassElement superclass = cls.superclass; 1014 ClassElement superclass = cls.superclass;
973 while (superclass != null) { 1015 while (superclass != null) {
974 Set<Element> typesImplementedBySubclassesOfCls = 1016 Set<Element> typesImplementedBySubclassesOfCls =
975 _typesImplementedBySubclasses.putIfAbsent( 1017 _typesImplementedBySubclasses.putIfAbsent(
976 superclass, () => new Set<ClassElement>()); 1018 superclass, () => new Set<ClassElement>());
977 for (DartType current in cls.allSupertypes) { 1019 for (DartType current in cls.allSupertypes) {
978 typesImplementedBySubclassesOfCls.add(current.element); 1020 typesImplementedBySubclassesOfCls.add(current.element);
979 } 1021 }
980 superclass = superclass.superclass; 1022 superclass = superclass.superclass;
981 } 1023 }
982 } 1024 }
983 1025
984 // Use the [:seenClasses:] set to include non-instantiated 1026 // Use the [:seenClasses:] set to include non-instantiated
985 // classes: if the superclass of these classes require RTI, then 1027 // classes: if the superclass of these classes require RTI, then
986 // they also need RTI, so that a constructor passes the type 1028 // they also need RTI, so that a constructor passes the type
987 // variables to the super constructor. 1029 // variables to the super constructor.
988 _compiler.resolverWorld.directlyInstantiatedClasses.forEach(addSubtypes); 1030 _compiler.resolverWorld.forEachInstantiatedClass(addSubtypes);
989 1031
990 _closed = true; 1032 _closed = true;
991 return this; 1033 return this;
992 } 1034 }
993 1035
994 @override 1036 @override
995 String dump([ClassElement cls]) { 1037 String dump([ClassElement cls]) {
996 StringBuffer sb = new StringBuffer(); 1038 StringBuffer sb = new StringBuffer();
997 if (cls != null) { 1039 if (cls != null) {
998 sb.write("Classes in the closed world related to $cls:\n"); 1040 sb.write("Classes in the closed world related to $cls:\n");
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after
1160 /// Only the class itself is included. 1202 /// Only the class itself is included.
1161 EXACT, 1203 EXACT,
1162 1204
1163 /// The class and all subclasses (transitively) are included. 1205 /// The class and all subclasses (transitively) are included.
1164 SUBCLASS, 1206 SUBCLASS,
1165 1207
1166 /// The class and all classes that implement or subclass it (transitively) 1208 /// The class and all classes that implement or subclass it (transitively)
1167 /// are included. 1209 /// are included.
1168 SUBTYPE, 1210 SUBTYPE,
1169 } 1211 }
OLDNEW
« no previous file with comments | « pkg/compiler/lib/src/universe/world_builder.dart ('k') | tests/compiler/dart2js/class_set_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698