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

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

Issue 2828873002: Revert "Remove JavaScriptBackend from ClosedWorldBase" (Closed)
Patch Set: Created 3 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) 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 ClosureClassElement, SynthesizedCallMethodElementX; 7 import 'closure.dart' show ClosureClassElement, SynthesizedCallMethodElementX;
8 import 'common.dart'; 8 import 'common.dart';
9 import 'constants/constant_system.dart'; 9 import 'constants/constant_system.dart';
10 import 'common_elements.dart' show CommonElements; 10 import 'common_elements.dart' show CommonElements;
11 import 'elements/entities.dart'; 11 import 'elements/entities.dart';
12 import 'elements/elements.dart' 12 import 'elements/elements.dart'
13 show 13 show
14 ClassElement, 14 ClassElement,
15 Element, 15 Element,
16 MemberElement, 16 MemberElement,
17 MixinApplicationElement, 17 MixinApplicationElement,
18 TypedefElement; 18 TypedefElement;
19 import 'elements/resolution_types.dart'; 19 import 'elements/resolution_types.dart';
20 import 'elements/types.dart'; 20 import 'elements/types.dart';
21 import 'js_backend/backend_usage.dart' show BackendUsage; 21 import 'js_backend/backend.dart' show JavaScriptBackend;
22 import 'js_backend/interceptor_data.dart' show InterceptorData; 22 import 'js_backend/interceptor_data.dart' show InterceptorData;
23 import 'js_backend/native_data.dart' show NativeData; 23 import 'js_backend/native_data.dart' show NativeData;
24 import 'ordered_typeset.dart'; 24 import 'ordered_typeset.dart';
25 import 'types/masks.dart' show CommonMasks, FlatTypeMask, TypeMask; 25 import 'types/masks.dart' show CommonMasks, FlatTypeMask, TypeMask;
26 import 'universe/class_set.dart'; 26 import 'universe/class_set.dart';
27 import 'universe/function_set.dart' show FunctionSet, FunctionSetBuilder; 27 import 'universe/function_set.dart' show FunctionSet, FunctionSetBuilder;
28 import 'universe/selector.dart' show Selector; 28 import 'universe/selector.dart' show Selector;
29 import 'universe/side_effects.dart' show SideEffects; 29 import 'universe/side_effects.dart' show SideEffects;
30 import 'universe/world_builder.dart' show ResolutionWorldBuilder; 30 import 'universe/world_builder.dart' show ResolutionWorldBuilder;
31 import 'util/util.dart' show Link; 31 import 'util/util.dart' show Link;
(...skipping 325 matching lines...) Expand 10 before | Expand all | Expand 10 after
357 abstract class OpenWorld implements World { 357 abstract class OpenWorld implements World {
358 /// Called to add [cls] to the set of known classes. 358 /// Called to add [cls] to the set of known classes.
359 /// 359 ///
360 /// This ensures that class hierarchy queries can be performed on [cls] and 360 /// This ensures that class hierarchy queries can be performed on [cls] and
361 /// classes that extend or implement it. 361 /// classes that extend or implement it.
362 void registerClass(ClassEntity cls); 362 void registerClass(ClassEntity cls);
363 363
364 void registerUsedElement(MemberEntity element); 364 void registerUsedElement(MemberEntity element);
365 void registerTypedef(TypedefElement typedef); 365 void registerTypedef(TypedefElement typedef);
366 366
367 ClosedWorld closeWorld(); 367 ClosedWorld closeWorld(DiagnosticReporter reporter);
368 368
369 /// Returns an iterable over all mixin applications that mixin [cls]. 369 /// Returns an iterable over all mixin applications that mixin [cls].
370 Iterable<ClassEntity> allMixinUsesOf(ClassEntity cls); 370 Iterable<ClassEntity> allMixinUsesOf(ClassEntity cls);
371 } 371 }
372 372
373 /// Enum values defining subset of classes included in queries. 373 /// Enum values defining subset of classes included in queries.
374 enum ClassQuery { 374 enum ClassQuery {
375 /// Only the class itself is included. 375 /// Only the class itself is included.
376 EXACT, 376 EXACT,
377 377
378 /// The class and all subclasses (transitively) are included. 378 /// The class and all subclasses (transitively) are included.
379 SUBCLASS, 379 SUBCLASS,
380 380
381 /// The class and all classes that implement or subclass it (transitively) 381 /// The class and all classes that implement or subclass it (transitively)
382 /// are included. 382 /// are included.
383 SUBTYPE, 383 SUBTYPE,
384 } 384 }
385 385
386 abstract class ClosedWorldBase implements ClosedWorld, ClosedWorldRefiner { 386 abstract class ClosedWorldBase implements ClosedWorld, ClosedWorldRefiner {
387 final ConstantSystem constantSystem; 387 final JavaScriptBackend _backend;
388 final NativeData nativeData; 388 InterceptorData get interceptorData => _backend.interceptorData;
389 final InterceptorData interceptorData;
390 final BackendUsage _backendUsage;
391
392 FunctionSet _allFunctions; 389 FunctionSet _allFunctions;
393 390
394 final Iterable<TypedefElement> _allTypedefs; 391 final Iterable<TypedefElement> _allTypedefs;
395 392
396 final Map<ClassEntity, Set<ClassEntity>> _mixinUses; 393 final Map<ClassEntity, Set<ClassEntity>> _mixinUses;
397 Map<ClassEntity, List<ClassEntity>> _liveMixinUses; 394 Map<ClassEntity, List<ClassEntity>> _liveMixinUses;
398 395
399 final Map<ClassEntity, Set<ClassEntity>> _typesImplementedBySubclasses; 396 final Map<ClassEntity, Set<ClassEntity>> _typesImplementedBySubclasses;
400 397
401 // We keep track of subtype and subclass relationships in four 398 // We keep track of subtype and subclass relationships in four
(...skipping 13 matching lines...) Expand all
415 412
416 final Set<Entity> _functionsThatMightBePassedToApply = new Set<Entity>(); 413 final Set<Entity> _functionsThatMightBePassedToApply = new Set<Entity>();
417 414
418 CommonMasks _commonMasks; 415 CommonMasks _commonMasks;
419 416
420 final CommonElements commonElements; 417 final CommonElements commonElements;
421 418
422 final ResolutionWorldBuilder _resolverWorld; 419 final ResolutionWorldBuilder _resolverWorld;
423 420
424 ClosedWorldBase( 421 ClosedWorldBase(
425 {this.commonElements, 422 {JavaScriptBackend backend,
426 this.constantSystem, 423 this.commonElements,
427 this.nativeData,
428 this.interceptorData,
429 BackendUsage backendUsage,
430 ResolutionWorldBuilder resolutionWorldBuilder, 424 ResolutionWorldBuilder resolutionWorldBuilder,
431 FunctionSetBuilder functionSetBuilder, 425 FunctionSetBuilder functionSetBuilder,
432 Iterable<TypedefElement> allTypedefs, 426 Iterable<TypedefElement> allTypedefs,
433 Map<ClassEntity, Set<ClassEntity>> mixinUses, 427 Map<ClassEntity, Set<ClassEntity>> mixinUses,
434 Map<ClassEntity, Set<ClassEntity>> typesImplementedBySubclasses, 428 Map<ClassEntity, Set<ClassEntity>> typesImplementedBySubclasses,
435 Map<ClassEntity, ClassHierarchyNode> classHierarchyNodes, 429 Map<ClassEntity, ClassHierarchyNode> classHierarchyNodes,
436 Map<ClassEntity, ClassSet> classSets}) 430 Map<ClassEntity, ClassSet> classSets})
437 : this._backendUsage = backendUsage, 431 : this._backend = backend,
438 this._resolverWorld = resolutionWorldBuilder, 432 this._resolverWorld = resolutionWorldBuilder,
439 this._allTypedefs = allTypedefs, 433 this._allTypedefs = allTypedefs,
440 this._mixinUses = mixinUses, 434 this._mixinUses = mixinUses,
441 this._typesImplementedBySubclasses = typesImplementedBySubclasses, 435 this._typesImplementedBySubclasses = typesImplementedBySubclasses,
442 this._classHierarchyNodes = classHierarchyNodes, 436 this._classHierarchyNodes = classHierarchyNodes,
443 this._classSets = classSets { 437 this._classSets = classSets {
444 _commonMasks = new CommonMasks(this); 438 _commonMasks = new CommonMasks(this);
445 _allFunctions = functionSetBuilder.close(this); 439 _allFunctions = functionSetBuilder.close(this);
446 } 440 }
447 441
442 NativeData get nativeData => _backend.nativeData;
443
448 @override 444 @override
449 ClosedWorld get closedWorld => this; 445 ClosedWorld get closedWorld => this;
450 446
451 /// Cache of [FlatTypeMask]s grouped by the 8 possible values of the 447 /// Cache of [FlatTypeMask]s grouped by the 8 possible values of the
452 /// `FlatTypeMask.flags` property. 448 /// `FlatTypeMask.flags` property.
453 final List<Map<ClassEntity, TypeMask>> _canonicalizedTypeMasks = 449 final List<Map<ClassEntity, TypeMask>> _canonicalizedTypeMasks =
454 new List<Map<ClassEntity, TypeMask>>.filled(8, null); 450 new List<Map<ClassEntity, TypeMask>>.filled(8, null);
455 451
456 FunctionSet get allFunctions => _allFunctions; 452 FunctionSet get allFunctions => _allFunctions;
457 453
458 CommonMasks get commonMasks { 454 CommonMasks get commonMasks {
459 return _commonMasks; 455 return _commonMasks;
460 } 456 }
461 457
458 ConstantSystem get constantSystem => _backend.constantSystem;
459
462 TypeMask getCachedMask(ClassEntity base, int flags, TypeMask createMask()) { 460 TypeMask getCachedMask(ClassEntity base, int flags, TypeMask createMask()) {
463 Map<ClassEntity, TypeMask> cachedMasks = 461 Map<ClassEntity, TypeMask> cachedMasks =
464 _canonicalizedTypeMasks[flags] ??= <ClassEntity, TypeMask>{}; 462 _canonicalizedTypeMasks[flags] ??= <ClassEntity, TypeMask>{};
465 return cachedMasks.putIfAbsent(base, createMask); 463 return cachedMasks.putIfAbsent(base, createMask);
466 } 464 }
467 465
468 bool _checkEntity(Entity element); 466 bool _checkEntity(Entity element);
469 467
470 bool _checkClass(ClassEntity cls); 468 bool _checkClass(ClassEntity cls);
471 469
472 bool _checkInvariants(ClassEntity cls, {bool mustBeInstantiated: true}); 470 bool _checkInvariants(ClassEntity cls, {bool mustBeInstantiated: true});
473 471
474 OrderedTypeSet _getOrderedTypeSet(ClassEntity cls);
475
476 int _getHierarchyDepth(ClassEntity cls);
477
478 ClassEntity _getSuperClass(ClassEntity cls);
479
480 Iterable<ClassEntity> _getInterfaces(ClassEntity cls);
481
482 ClassEntity _getAppliedMixin(ClassEntity cls);
483
484 bool _isNamedMixinApplication(ClassEntity cls);
485
486 @override 472 @override
487 bool isInstantiated(ClassEntity cls) { 473 bool isInstantiated(ClassEntity cls) {
488 assert(_checkClass(cls)); 474 assert(_checkClass(cls));
489 ClassHierarchyNode node = _classHierarchyNodes[cls]; 475 ClassHierarchyNode node = _classHierarchyNodes[cls];
490 return node != null && node.isInstantiated; 476 return node != null && node.isInstantiated;
491 } 477 }
492 478
493 @override 479 @override
494 bool isDirectlyInstantiated(ClassEntity cls) { 480 bool isDirectlyInstantiated(ClassEntity cls) {
495 assert(_checkClass(cls)); 481 assert(_checkClass(cls));
(...skipping 320 matching lines...) Expand 10 before | Expand all | Expand 10 after
816 return subclassesNeedNoSuchMethod(node); 802 return subclassesNeedNoSuchMethod(node);
817 } else { 803 } else {
818 if (subclassesNeedNoSuchMethod(node)) return true; 804 if (subclassesNeedNoSuchMethod(node)) return true;
819 for (ClassHierarchyNode subtypeNode in classSet.subtypeNodes) { 805 for (ClassHierarchyNode subtypeNode in classSet.subtypeNodes) {
820 if (subclassesNeedNoSuchMethod(subtypeNode)) return true; 806 if (subclassesNeedNoSuchMethod(subtypeNode)) return true;
821 } 807 }
822 return false; 808 return false;
823 } 809 }
824 } 810 }
825 811
826 /// Returns an iterable over the common supertypes of the [classes].
827 Iterable<ClassEntity> commonSupertypesOf(Iterable<ClassEntity> classes) {
828 Iterator<ClassEntity> iterator = classes.iterator;
829 if (!iterator.moveNext()) return const <ClassEntity>[];
830
831 ClassEntity cls = iterator.current;
832 assert(_checkInvariants(cls));
833 OrderedTypeSet typeSet = _getOrderedTypeSet(cls);
834 if (!iterator.moveNext()) return typeSet.types.map((type) => type.element);
835
836 int depth = typeSet.maxDepth;
837 Link<OrderedTypeSet> otherTypeSets = const Link<OrderedTypeSet>();
838 do {
839 ClassEntity otherClass = iterator.current;
840 assert(_checkInvariants(otherClass));
841 OrderedTypeSet otherTypeSet = _getOrderedTypeSet(otherClass);
842 otherTypeSets = otherTypeSets.prepend(otherTypeSet);
843 if (otherTypeSet.maxDepth < depth) {
844 depth = otherTypeSet.maxDepth;
845 }
846 } while (iterator.moveNext());
847
848 List<ClassEntity> commonSupertypes = <ClassEntity>[];
849 OUTER:
850 for (Link<InterfaceType> link = typeSet[depth];
851 link.head.element != commonElements.objectClass;
852 link = link.tail) {
853 ClassEntity cls = link.head.element;
854 for (Link<OrderedTypeSet> link = otherTypeSets;
855 !link.isEmpty;
856 link = link.tail) {
857 if (link.head.asInstanceOf(cls, _getHierarchyDepth(cls)) == null) {
858 continue OUTER;
859 }
860 }
861 commonSupertypes.add(cls);
862 }
863 commonSupertypes.add(commonElements.objectClass);
864 return commonSupertypes;
865 }
866
867 Iterable<ClassEntity> commonSubclasses(ClassEntity cls1, ClassQuery query1,
868 ClassEntity cls2, ClassQuery query2) {
869 // TODO(johnniwinther): Use [ClassSet] to compute this.
870 // Compute the set of classes that are contained in both class subsets.
871 Set<ClassEntity> common =
872 _commonContainedClasses(cls1, query1, cls2, query2);
873 if (common == null || common.isEmpty) return const <ClassEntity>[];
874 // Narrow down the candidates by only looking at common classes
875 // that do not have a superclass or supertype that will be a
876 // better candidate.
877 return common.where((ClassEntity each) {
878 bool containsSuperclass = common.contains(_getSuperClass(each));
879 // If the superclass is also a candidate, then we don't want to
880 // deal with this class. If we're only looking for a subclass we
881 // know we don't have to look at the list of interfaces because
882 // they can never be in the common set.
883 if (containsSuperclass ||
884 query1 == ClassQuery.SUBCLASS ||
885 query2 == ClassQuery.SUBCLASS) {
886 return !containsSuperclass;
887 }
888 // Run through the direct supertypes of the class. If the common
889 // set contains the direct supertype of the class, we ignore the
890 // the class because the supertype is a better candidate.
891
892 for (ClassEntity interface in _getInterfaces(each)) {
893 if (common.contains(interface)) return false;
894 }
895 return true;
896 });
897 }
898
899 /// Returns an iterable over the live mixin applications that mixin [cls].
900 Iterable<ClassEntity> mixinUsesOf(ClassEntity cls) {
901 if (_liveMixinUses == null) {
902 _liveMixinUses = new Map<ClassEntity, List<ClassEntity>>();
903 for (ClassEntity mixin in _mixinUses.keys) {
904 List<ClassEntity> uses = <ClassEntity>[];
905
906 void addLiveUse(ClassEntity mixinApplication) {
907 if (isInstantiated(mixinApplication)) {
908 uses.add(mixinApplication);
909 } else if (_isNamedMixinApplication(mixinApplication)) {
910 Set<ClassEntity> next = _mixinUses[mixinApplication];
911 if (next != null) {
912 next.forEach(addLiveUse);
913 }
914 }
915 }
916
917 _mixinUses[mixin].forEach(addLiveUse);
918 if (uses.isNotEmpty) {
919 _liveMixinUses[mixin] = uses;
920 }
921 }
922 }
923 Iterable<ClassEntity> uses = _liveMixinUses[cls];
924 return uses != null ? uses : const <ClassEntity>[];
925 }
926
927 /// Returns `true` if any live class that mixes in [mixin] is also a subclass
928 /// of [superclass].
929 bool hasAnySubclassThatMixes(ClassEntity superclass, ClassEntity mixin) {
930 return mixinUsesOf(mixin).any((ClassEntity each) {
931 return isSubclassOf(each, superclass);
932 });
933 }
934
935 /// Returns `true` if [cls] or any superclass mixes in [mixin].
936 bool isSubclassOfMixinUseOf(ClassEntity cls, ClassEntity mixin) {
937 assert(_checkClass(cls));
938 assert(_checkClass(mixin));
939 if (isUsedAsMixin(mixin)) {
940 ClassEntity current = cls;
941 while (current != null) {
942 ClassEntity currentMixin = _getAppliedMixin(cls);
943 if (currentMixin == mixin) return true;
944 current = _getSuperClass(current);
945 }
946 }
947 return false;
948 }
949
950 /// Returns [ClassHierarchyNode] for [cls] used to model the class hierarchies 812 /// Returns [ClassHierarchyNode] for [cls] used to model the class hierarchies
951 /// of known classes. 813 /// of known classes.
952 /// 814 ///
953 /// This method is only provided for testing. For queries on classes, use the 815 /// This method is only provided for testing. For queries on classes, use the
954 /// methods defined in [ClosedWorld]. 816 /// methods defined in [ClosedWorld].
955 ClassHierarchyNode getClassHierarchyNode(ClassEntity cls) { 817 ClassHierarchyNode getClassHierarchyNode(ClassEntity cls) {
956 assert(_checkClass(cls)); 818 assert(_checkClass(cls));
957 return _classHierarchyNodes[cls]; 819 return _classHierarchyNodes[cls];
958 } 820 }
959 821
(...skipping 19 matching lines...) Expand all
979 } 841 }
980 842
981 MemberEntity locateSingleElement(Selector selector, TypeMask mask) { 843 MemberEntity locateSingleElement(Selector selector, TypeMask mask) {
982 mask ??= commonMasks.dynamicType; 844 mask ??= commonMasks.dynamicType;
983 return mask.locateSingleElement(selector, this); 845 return mask.locateSingleElement(selector, this);
984 } 846 }
985 847
986 TypeMask extendMaskIfReachesAll(Selector selector, TypeMask mask) { 848 TypeMask extendMaskIfReachesAll(Selector selector, TypeMask mask) {
987 bool canReachAll = true; 849 bool canReachAll = true;
988 if (mask != null) { 850 if (mask != null) {
989 canReachAll = _backendUsage.isInvokeOnUsed && 851 canReachAll = _backend.backendUsage.isInvokeOnUsed &&
990 mask.needsNoSuchMethodHandling(selector, this); 852 mask.needsNoSuchMethodHandling(selector, this);
991 } 853 }
992 return canReachAll ? commonMasks.dynamicType : mask; 854 return canReachAll ? commonMasks.dynamicType : mask;
993 } 855 }
994 856
995 bool fieldNeverChanges(MemberEntity element) { 857 bool fieldNeverChanges(MemberEntity element) {
996 if (!element.isField) return false; 858 if (!element.isField) return false;
997 if (nativeData.isNativeMember(element)) { 859 if (nativeData.isNativeMember(element)) {
998 // Some native fields are views of data that may be changed by operations. 860 // Some native fields are views of data that may be changed by operations.
999 // E.g. node.firstChild depends on parentNode.removeBefore(n1, n2). 861 // E.g. node.firstChild depends on parentNode.removeBefore(n1, n2).
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
1097 } 959 }
1098 960
1099 @override 961 @override
1100 bool getCurrentlyKnownMightBePassedToApply(Entity element) { 962 bool getCurrentlyKnownMightBePassedToApply(Entity element) {
1101 return getMightBePassedToApply(element); 963 return getMightBePassedToApply(element);
1102 } 964 }
1103 } 965 }
1104 966
1105 class ClosedWorldImpl extends ClosedWorldBase { 967 class ClosedWorldImpl extends ClosedWorldBase {
1106 ClosedWorldImpl( 968 ClosedWorldImpl(
1107 {CommonElements commonElements, 969 {JavaScriptBackend backend,
1108 ConstantSystem constantSystem, 970 CommonElements commonElements,
1109 NativeData nativeData,
1110 InterceptorData interceptorData,
1111 BackendUsage backendUsage,
1112 ResolutionWorldBuilder resolutionWorldBuilder, 971 ResolutionWorldBuilder resolutionWorldBuilder,
1113 FunctionSetBuilder functionSetBuilder, 972 FunctionSetBuilder functionSetBuilder,
1114 Iterable<TypedefElement> allTypedefs, 973 Iterable<TypedefElement> allTypedefs,
1115 Map<ClassEntity, Set<ClassEntity>> mixinUses, 974 Map<ClassEntity, Set<ClassEntity>> mixinUses,
1116 Map<ClassEntity, Set<ClassEntity>> typesImplementedBySubclasses, 975 Map<ClassEntity, Set<ClassEntity>> typesImplementedBySubclasses,
1117 Map<ClassEntity, ClassHierarchyNode> classHierarchyNodes, 976 Map<ClassEntity, ClassHierarchyNode> classHierarchyNodes,
1118 Map<ClassEntity, ClassSet> classSets}) 977 Map<ClassEntity, ClassSet> classSets})
1119 : super( 978 : super(
979 backend: backend,
1120 commonElements: commonElements, 980 commonElements: commonElements,
1121 constantSystem: constantSystem,
1122 nativeData: nativeData,
1123 interceptorData: interceptorData,
1124 backendUsage: backendUsage,
1125 resolutionWorldBuilder: resolutionWorldBuilder, 981 resolutionWorldBuilder: resolutionWorldBuilder,
1126 functionSetBuilder: functionSetBuilder, 982 functionSetBuilder: functionSetBuilder,
1127 allTypedefs: allTypedefs, 983 allTypedefs: allTypedefs,
1128 mixinUses: mixinUses, 984 mixinUses: mixinUses,
1129 typesImplementedBySubclasses: typesImplementedBySubclasses, 985 typesImplementedBySubclasses: typesImplementedBySubclasses,
1130 classHierarchyNodes: classHierarchyNodes, 986 classHierarchyNodes: classHierarchyNodes,
1131 classSets: classSets); 987 classSets: classSets);
1132 988
1133 bool _checkClass(ClassElement cls) => cls.isDeclaration; 989 bool _checkClass(ClassElement cls) => cls.isDeclaration;
1134
1135 bool _checkEntity(Element element) => element.isDeclaration; 990 bool _checkEntity(Element element) => element.isDeclaration;
1136 991
1137 bool _checkInvariants(ClassElement cls, {bool mustBeInstantiated: true}) { 992 bool _checkInvariants(ClassElement cls, {bool mustBeInstantiated: true}) {
1138 return invariant(cls, cls.isDeclaration, 993 return invariant(cls, cls.isDeclaration,
1139 message: '$cls must be the declaration.') && 994 message: '$cls must be the declaration.') &&
1140 invariant(cls, cls.isResolved, 995 invariant(cls, cls.isResolved,
1141 message: 996 message:
1142 '$cls must be resolved.') /* && 997 '$cls must be resolved.') /* &&
1143 // TODO(johnniwinther): Reinsert this or similar invariant. Currently 998 // TODO(johnniwinther): Reinsert this or similar invariant. Currently
1144 // various call sites use uninstantiated classes for isSubtypeOf or 999 // various call sites use uninstantiated classes for isSubtypeOf or
1145 // isSubclassOf. Some are valid, some are not. Work out better invariants 1000 // isSubclassOf. Some are valid, some are not. Work out better invariants
1146 // to catch the latter. 1001 // to catch the latter.
1147 (!mustBeInstantiated || 1002 (!mustBeInstantiated ||
1148 invariant(cls, isInstantiated(cls), 1003 invariant(cls, isInstantiated(cls),
1149 message: '$cls is not instantiated.'))*/ 1004 message: '$cls is not instantiated.'))*/
1150 ; 1005 ;
1151 } 1006 }
1152 1007
1153 OrderedTypeSet _getOrderedTypeSet(ClassElement cls) => 1008 /// Returns an iterable over the common supertypes of the [classes].
1154 cls.allSupertypesAndSelf; 1009 Iterable<ClassElement> commonSupertypesOf(Iterable<ClassElement> classes) {
1010 Iterator<ClassElement> iterator = classes.iterator;
1011 if (!iterator.moveNext()) return const <ClassElement>[];
1155 1012
1156 int _getHierarchyDepth(ClassElement cls) => cls.hierarchyDepth; 1013 ClassElement cls = iterator.current;
1014 assert(_checkInvariants(cls));
1015 OrderedTypeSet typeSet = cls.allSupertypesAndSelf;
1016 if (!iterator.moveNext()) return typeSet.types.map((type) => type.element);
1157 1017
1158 ClassEntity _getSuperClass(ClassElement cls) => cls.superclass; 1018 int depth = typeSet.maxDepth;
1019 Link<OrderedTypeSet> otherTypeSets = const Link<OrderedTypeSet>();
1020 do {
1021 ClassElement otherClass = iterator.current;
1022 assert(_checkInvariants(otherClass));
1023 OrderedTypeSet otherTypeSet = otherClass.allSupertypesAndSelf;
1024 otherTypeSets = otherTypeSets.prepend(otherTypeSet);
1025 if (otherTypeSet.maxDepth < depth) {
1026 depth = otherTypeSet.maxDepth;
1027 }
1028 } while (iterator.moveNext());
1159 1029
1160 Iterable<ClassEntity> _getInterfaces(ClassElement cls) sync* { 1030 List<ClassElement> commonSupertypes = <ClassElement>[];
1161 for (Link link = cls.interfaces; !link.isEmpty; link = link.tail) { 1031 OUTER:
1162 yield link.head.element; 1032 for (Link<InterfaceType> link = typeSet[depth];
1033 link.head.element != commonElements.objectClass;
1034 link = link.tail) {
1035 ClassElement cls = link.head.element;
1036 for (Link<OrderedTypeSet> link = otherTypeSets;
1037 !link.isEmpty;
1038 link = link.tail) {
1039 if (link.head.asInstanceOf(cls, cls.hierarchyDepth) == null) {
1040 continue OUTER;
1041 }
1042 }
1043 commonSupertypes.add(cls);
1163 } 1044 }
1045 commonSupertypes.add(commonElements.objectClass);
1046 return commonSupertypes;
1164 } 1047 }
1165 1048
1166 bool _isNamedMixinApplication(ClassElement cls) => 1049 Iterable<ClassEntity> commonSubclasses(ClassEntity cls1, ClassQuery query1,
1167 cls.isNamedMixinApplication; 1050 ClassEntity cls2, ClassQuery query2) {
1051 // TODO(johnniwinther): Use [ClassSet] to compute this.
1052 // Compute the set of classes that are contained in both class subsets.
1053 Set<ClassEntity> common =
1054 _commonContainedClasses(cls1, query1, cls2, query2);
1055 if (common == null || common.isEmpty) return const <ClassEntity>[];
1056 // Narrow down the candidates by only looking at common classes
1057 // that do not have a superclass or supertype that will be a
1058 // better candidate.
1059 return common.where((ClassElement each) {
1060 bool containsSuperclass = common.contains(each.supertype.element);
1061 // If the superclass is also a candidate, then we don't want to
1062 // deal with this class. If we're only looking for a subclass we
1063 // know we don't have to look at the list of interfaces because
1064 // they can never be in the common set.
1065 if (containsSuperclass ||
1066 query1 == ClassQuery.SUBCLASS ||
1067 query2 == ClassQuery.SUBCLASS) {
1068 return !containsSuperclass;
1069 }
1070 // Run through the direct supertypes of the class. If the common
1071 // set contains the direct supertype of the class, we ignore the
1072 // the class because the supertype is a better candidate.
1073 for (Link link = each.interfaces; !link.isEmpty; link = link.tail) {
1074 if (common.contains(link.head.element)) return false;
1075 }
1076 return true;
1077 });
1078 }
1168 1079
1169 ClassEntity _getAppliedMixin(ClassElement cls) { 1080 /// Returns an iterable over the live mixin applications that mixin [cls].
1170 if (cls.isMixinApplication) { 1081 Iterable<ClassEntity> mixinUsesOf(ClassEntity cls) {
1171 MixinApplicationElement application = cls; 1082 if (_liveMixinUses == null) {
1172 return application.mixin; 1083 _liveMixinUses = new Map<ClassEntity, List<ClassEntity>>();
1084 for (ClassElement mixin in _mixinUses.keys) {
1085 List<ClassEntity> uses = <ClassEntity>[];
1086
1087 void addLiveUse(MixinApplicationElement mixinApplication) {
1088 if (isInstantiated(mixinApplication)) {
1089 uses.add(mixinApplication);
1090 } else if (mixinApplication.isNamedMixinApplication) {
1091 Set<ClassEntity> next = _mixinUses[mixinApplication];
1092 if (next != null) {
1093 next.forEach(addLiveUse);
1094 }
1095 }
1096 }
1097
1098 _mixinUses[mixin].forEach(addLiveUse);
1099 if (uses.isNotEmpty) {
1100 _liveMixinUses[mixin] = uses;
1101 }
1102 }
1173 } 1103 }
1174 return null; 1104 Iterable<ClassEntity> uses = _liveMixinUses[cls];
1105 return uses != null ? uses : const <ClassEntity>[];
1106 }
1107
1108 /// Returns `true` if any live class that mixes in [mixin] is also a subclass
1109 /// of [superclass].
1110 bool hasAnySubclassThatMixes(ClassEntity superclass, ClassEntity mixin) {
1111 return mixinUsesOf(mixin).any((ClassElement each) {
1112 return each.isSubclassOf(superclass);
1113 });
1114 }
1115
1116 /// Returns `true` if [cls] or any superclass mixes in [mixin].
1117 bool isSubclassOfMixinUseOf(ClassEntity cls, ClassEntity mixin) {
1118 assert(_checkClass(cls));
1119 assert(_checkClass(mixin));
1120 if (isUsedAsMixin(mixin)) {
1121 ClassElement current = cls;
1122 while (current != null) {
1123 if (current.isMixinApplication) {
1124 MixinApplicationElement application = current;
1125 if (application.mixin == mixin) return true;
1126 }
1127 current = current.superclass;
1128 }
1129 }
1130 return false;
1175 } 1131 }
1176 1132
1177 @override 1133 @override
1178 bool hasElementIn(ClassEntity cls, Selector selector, Element element) { 1134 bool hasElementIn(ClassEntity cls, Selector selector, Element element) {
1179 // Use [:implementation:] of [element] 1135 // Use [:implementation:] of [element]
1180 // because our function set only stores declarations. 1136 // because our function set only stores declarations.
1181 Element result = findMatchIn(cls, selector); 1137 Element result = findMatchIn(cls, selector);
1182 return result == null 1138 return result == null
1183 ? false 1139 ? false
1184 : result.implementation == element.implementation; 1140 : result.implementation == element.implementation;
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
1253 // does not see generative constructor bodies because they are 1209 // does not see generative constructor bodies because they are
1254 // created by the backend. Also, it does not make any distinction 1210 // created by the backend. Also, it does not make any distinction
1255 // between a constructor and its body for side effects. This 1211 // between a constructor and its body for side effects. This
1256 // implies that currently, the side effects of a constructor body 1212 // implies that currently, the side effects of a constructor body
1257 // contain the side effects of the initializers. 1213 // contain the side effects of the initializers.
1258 assert(!element.isGenerativeConstructorBody); 1214 assert(!element.isGenerativeConstructorBody);
1259 assert(!element.isField); 1215 assert(!element.isField);
1260 return super.getSideEffectsOfElement(element); 1216 return super.getSideEffectsOfElement(element);
1261 } 1217 }
1262 } 1218 }
1263
1264 class KernelClosedWorld extends ClosedWorldBase {
1265 KernelClosedWorld(
1266 {CommonElements commonElements,
1267 ConstantSystem constantSystem,
1268 NativeData nativeData,
1269 InterceptorData interceptorData,
1270 BackendUsage backendUsage,
1271 ResolutionWorldBuilder resolutionWorldBuilder,
1272 FunctionSetBuilder functionSetBuilder,
1273 Iterable<TypedefElement> allTypedefs,
1274 Map<ClassEntity, Set<ClassEntity>> mixinUses,
1275 Map<ClassEntity, Set<ClassEntity>> typesImplementedBySubclasses,
1276 Map<ClassEntity, ClassHierarchyNode> classHierarchyNodes,
1277 Map<ClassEntity, ClassSet> classSets})
1278 : super(
1279 commonElements: commonElements,
1280 constantSystem: constantSystem,
1281 nativeData: nativeData,
1282 interceptorData: interceptorData,
1283 backendUsage: backendUsage,
1284 resolutionWorldBuilder: resolutionWorldBuilder,
1285 functionSetBuilder: functionSetBuilder,
1286 allTypedefs: allTypedefs,
1287 mixinUses: mixinUses,
1288 typesImplementedBySubclasses: typesImplementedBySubclasses,
1289 classHierarchyNodes: classHierarchyNodes,
1290 classSets: classSets);
1291
1292 @override
1293 bool hasConcreteMatch(ClassEntity cls, Selector selector,
1294 {ClassEntity stopAtSuperclass}) {
1295 throw new UnimplementedError('KernelClosedWorld.hasConcreteMatch');
1296 }
1297
1298 @override
1299 bool _isNamedMixinApplication(ClassEntity cls) {
1300 throw new UnimplementedError('KernelClosedWorld._isNamedMixinApplication');
1301 }
1302
1303 @override
1304 ClassEntity _getAppliedMixin(ClassEntity cls) {
1305 throw new UnimplementedError('KernelClosedWorld._getAppliedMixin');
1306 }
1307
1308 @override
1309 Iterable<ClassEntity> _getInterfaces(ClassEntity cls) {
1310 throw new UnimplementedError('KernelClosedWorld._getInterfaces');
1311 }
1312
1313 @override
1314 ClassEntity _getSuperClass(ClassEntity cls) {
1315 throw new UnimplementedError('KernelClosedWorld._getSuperClass');
1316 }
1317
1318 @override
1319 int _getHierarchyDepth(ClassEntity cls) {
1320 throw new UnimplementedError('KernelClosedWorld._getHierarchyDepth');
1321 }
1322
1323 @override
1324 OrderedTypeSet _getOrderedTypeSet(ClassEntity cls) {
1325 throw new UnimplementedError('KernelClosedWorld._getOrderedTypeSet');
1326 }
1327
1328 @override
1329 bool _checkInvariants(ClassEntity cls, {bool mustBeInstantiated: true}) =>
1330 true;
1331
1332 @override
1333 bool _checkClass(ClassEntity cls) => true;
1334
1335 @override
1336 bool _checkEntity(Entity element) => true;
1337
1338 @override
1339 void registerClosureClass(ClassElement cls) {
1340 throw new UnimplementedError('KernelClosedWorld.registerClosureClass');
1341 }
1342
1343 @override
1344 String dump([ClassEntity cls]) {
1345 throw new UnimplementedError('KernelClosedWorld.dump');
1346 }
1347
1348 @override
1349 bool hasElementIn(ClassEntity cls, Selector selector, Entity element) {
1350 throw new UnimplementedError('KernelClosedWorld.hasElementIn');
1351 }
1352 }
OLDNEW
« no previous file with comments | « pkg/compiler/lib/src/universe/world_builder.dart ('k') | tests/compiler/dart2js/kernel/closed_world2_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698