| OLD | NEW |
| 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 'cache_strategy.dart'; |
| 7 import 'closure.dart' show SynthesizedCallMethodElementX; | 8 import 'closure.dart' show SynthesizedCallMethodElementX; |
| 8 import 'common/backend_api.dart' show BackendClasses; | 9 import 'common/backend_api.dart' show BackendClasses; |
| 9 import 'common.dart'; | 10 import 'common.dart'; |
| 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 FieldElement; | 20 FieldElement; |
| 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 'universe/world_builder.dart' show ResolutionWorldBuilder; |
| 28 import 'util/enumset.dart'; | 29 import 'util/enumset.dart'; |
| 29 import 'util/util.dart' show Link; | 30 import 'util/util.dart' show Link; |
| 30 | 31 |
| 31 /// Common superinterface for [OpenWorld] and [ClosedWorld]. | 32 /// Common superinterface for [OpenWorld] and [ClosedWorld]. |
| 32 abstract class World {} | 33 abstract class World {} |
| 33 | 34 |
| 34 /// The [ClosedWorld] represents the information known about a program when | 35 /// The [ClosedWorld] represents the information known about a program when |
| 35 /// compiling with closed-world semantics. | 36 /// compiling with closed-world semantics. |
| 36 /// | 37 /// |
| 37 /// Given the entrypoint of an application, we can track what's reachable from | 38 /// Given the entrypoint of an application, we can track what's reachable from |
| 38 /// it, what functions are called, what classes are allocated, which native | 39 /// it, what functions are called, what classes are allocated, which native |
| 39 /// JavaScript types are touched, what language features are used, and so on. | 40 /// JavaScript types are touched, what language features are used, and so on. |
| 40 /// This precise knowledge about what's live in the program is later used in | 41 /// This precise knowledge about what's live in the program is later used in |
| 41 /// optimizations and other compiler decisions during code generation. | 42 /// optimizations and other compiler decisions during code generation. |
| 42 abstract class ClosedWorld implements World { | 43 abstract class ClosedWorld implements World { |
| 43 /// Access to core classes used by the backend. | 44 /// Access to core classes used by the backend. |
| 44 BackendClasses get backendClasses; | 45 BackendClasses get backendClasses; |
| 45 | 46 |
| 46 /// Access to core classes used in the Dart language. | 47 /// Access to core classes used in the Dart language. |
| 47 CoreClasses get coreClasses; | 48 CoreClasses get coreClasses; |
| 48 | 49 |
| 50 CommonMasks get commonMasks; |
| 51 |
| 49 /// Returns `true` if [cls] is either directly or indirectly instantiated. | 52 /// Returns `true` if [cls] is either directly or indirectly instantiated. |
| 50 bool isInstantiated(ClassElement cls); | 53 bool isInstantiated(ClassElement cls); |
| 51 | 54 |
| 52 /// Returns `true` if [cls] is directly instantiated. This means that at | 55 /// Returns `true` if [cls] is directly instantiated. This means that at |
| 53 /// runtime instances of exactly [cls] are assumed to exist. | 56 /// runtime instances of exactly [cls] are assumed to exist. |
| 54 bool isDirectlyInstantiated(ClassElement cls); | 57 bool isDirectlyInstantiated(ClassElement cls); |
| 55 | 58 |
| 56 /// Returns `true` if [cls] is abstractly instantiated. This means that at | 59 /// Returns `true` if [cls] is abstractly instantiated. This means that at |
| 57 /// runtime instances of [cls] or unknown subclasses of [cls] are assumed to | 60 /// runtime instances of [cls] or unknown subclasses of [cls] are assumed to |
| 58 /// exist. | 61 /// exist. |
| (...skipping 268 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 327 abstract class OpenWorld implements World { | 330 abstract class OpenWorld implements World { |
| 328 /// Called to add [cls] to the set of known classes. | 331 /// Called to add [cls] to the set of known classes. |
| 329 /// | 332 /// |
| 330 /// This ensures that class hierarchy queries can be performed on [cls] and | 333 /// This ensures that class hierarchy queries can be performed on [cls] and |
| 331 /// classes that extend or implement it. | 334 /// classes that extend or implement it. |
| 332 void registerClass(ClassElement cls); | 335 void registerClass(ClassElement cls); |
| 333 | 336 |
| 334 void registerUsedElement(Element element); | 337 void registerUsedElement(Element element); |
| 335 void registerTypedef(TypedefElement typedef); | 338 void registerTypedef(TypedefElement typedef); |
| 336 | 339 |
| 337 ClosedWorld closeWorld(); | 340 ClosedWorld closeWorld(DiagnosticReporter reporter); |
| 338 | 341 |
| 339 /// Returns an iterable over all mixin applications that mixin [cls]. | 342 /// Returns an iterable over all mixin applications that mixin [cls]. |
| 340 Iterable<MixinApplicationElement> allMixinUsesOf(ClassElement cls); | 343 Iterable<MixinApplicationElement> allMixinUsesOf(ClassElement cls); |
| 341 } | 344 } |
| 342 | 345 |
| 343 class WorldImpl implements ClosedWorld, ClosedWorldRefiner, OpenWorld { | 346 class WorldImpl implements ClosedWorld, ClosedWorldRefiner, OpenWorld { |
| 344 bool _closed = false; | 347 bool _closed = false; |
| 345 | 348 |
| 346 TypeMask getCachedMask(ClassElement base, int flags, TypeMask createMask()) { | 349 TypeMask getCachedMask(ClassElement base, int flags, TypeMask createMask()) { |
| 347 Map<ClassElement, TypeMask> cachedMasks = | 350 Map<ClassElement, TypeMask> cachedMasks = |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 430 ClassHierarchyNode node = _classHierarchyNodes[cls.declaration]; | 433 ClassHierarchyNode node = _classHierarchyNodes[cls.declaration]; |
| 431 return node != null && node.isIndirectlyInstantiated; | 434 return node != null && node.isIndirectlyInstantiated; |
| 432 } | 435 } |
| 433 | 436 |
| 434 @override | 437 @override |
| 435 bool isAbstract(ClassElement cls) => cls.isAbstract; | 438 bool isAbstract(ClassElement cls) => cls.isAbstract; |
| 436 | 439 |
| 437 /// Returns `true` if [cls] is implemented by an instantiated class. | 440 /// Returns `true` if [cls] is implemented by an instantiated class. |
| 438 bool isImplemented(ClassElement cls) { | 441 bool isImplemented(ClassElement cls) { |
| 439 assert(isClosed); | 442 assert(isClosed); |
| 440 return _compiler.resolverWorld.isImplemented(cls); | 443 return resolverWorld.isImplemented(cls); |
| 441 } | 444 } |
| 442 | 445 |
| 443 /// Returns an iterable over the directly instantiated classes that extend | 446 /// Returns an iterable over the directly instantiated classes that extend |
| 444 /// [cls] possibly including [cls] itself, if it is live. | 447 /// [cls] possibly including [cls] itself, if it is live. |
| 445 Iterable<ClassElement> subclassesOf(ClassElement cls) { | 448 Iterable<ClassElement> subclassesOf(ClassElement cls) { |
| 446 assert(isClosed); | 449 assert(isClosed); |
| 447 ClassHierarchyNode hierarchy = _classHierarchyNodes[cls.declaration]; | 450 ClassHierarchyNode hierarchy = _classHierarchyNodes[cls.declaration]; |
| 448 if (hierarchy == null) return const <ClassElement>[]; | 451 if (hierarchy == null) return const <ClassElement>[]; |
| 449 return hierarchy | 452 return hierarchy |
| 450 .subclassesByMask(ClassHierarchyNode.EXPLICITLY_INSTANTIATED); | 453 .subclassesByMask(ClassHierarchyNode.EXPLICITLY_INSTANTIATED); |
| (...skipping 378 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 829 return subclassesNeedNoSuchMethod(node); | 832 return subclassesNeedNoSuchMethod(node); |
| 830 } else { | 833 } else { |
| 831 if (subclassesNeedNoSuchMethod(node)) return true; | 834 if (subclassesNeedNoSuchMethod(node)) return true; |
| 832 for (ClassHierarchyNode subtypeNode in classSet.subtypeNodes) { | 835 for (ClassHierarchyNode subtypeNode in classSet.subtypeNodes) { |
| 833 if (subclassesNeedNoSuchMethod(subtypeNode)) return true; | 836 if (subclassesNeedNoSuchMethod(subtypeNode)) return true; |
| 834 } | 837 } |
| 835 return false; | 838 return false; |
| 836 } | 839 } |
| 837 } | 840 } |
| 838 | 841 |
| 839 final Compiler _compiler; | 842 final JavaScriptBackend _backend; |
| 840 BackendClasses get backendClasses => _backend.backendClasses; | 843 BackendClasses get backendClasses => _backend.backendClasses; |
| 841 JavaScriptBackend get _backend => _compiler.backend; | 844 FunctionSet _allFunctions; |
| 842 CommonMasks get commonMasks => _compiler.commonMasks; | |
| 843 final FunctionSet allFunctions; | |
| 844 final Set<Element> functionsCalledInLoop = new Set<Element>(); | 845 final Set<Element> functionsCalledInLoop = new Set<Element>(); |
| 845 final Map<Element, SideEffects> sideEffects = new Map<Element, SideEffects>(); | 846 final Map<Element, SideEffects> sideEffects = new Map<Element, SideEffects>(); |
| 846 | 847 |
| 847 final Set<TypedefElement> _allTypedefs = new Set<TypedefElement>(); | 848 final Set<TypedefElement> _allTypedefs = new Set<TypedefElement>(); |
| 848 | 849 |
| 849 final Map<ClassElement, Set<MixinApplicationElement>> _mixinUses = | 850 final Map<ClassElement, Set<MixinApplicationElement>> _mixinUses = |
| 850 new Map<ClassElement, Set<MixinApplicationElement>>(); | 851 new Map<ClassElement, Set<MixinApplicationElement>>(); |
| 851 Map<ClassElement, List<MixinApplicationElement>> _liveMixinUses; | 852 Map<ClassElement, List<MixinApplicationElement>> _liveMixinUses; |
| 852 | 853 |
| 853 final Map<ClassElement, Set<ClassElement>> _typesImplementedBySubclasses = | 854 final Map<ClassElement, Set<ClassElement>> _typesImplementedBySubclasses = |
| (...skipping 10 matching lines...) Expand all Loading... |
| 864 | 865 |
| 865 final Set<Element> sideEffectsFreeElements = new Set<Element>(); | 866 final Set<Element> sideEffectsFreeElements = new Set<Element>(); |
| 866 | 867 |
| 867 final Set<Element> elementsThatCannotThrow = new Set<Element>(); | 868 final Set<Element> elementsThatCannotThrow = new Set<Element>(); |
| 868 | 869 |
| 869 final Set<Element> functionsThatMightBePassedToApply = | 870 final Set<Element> functionsThatMightBePassedToApply = |
| 870 new Set<FunctionElement>(); | 871 new Set<FunctionElement>(); |
| 871 | 872 |
| 872 final Set<Element> alreadyPopulated; | 873 final Set<Element> alreadyPopulated; |
| 873 | 874 |
| 875 CommonMasks _commonMasks; |
| 876 |
| 877 final CoreClasses coreClasses; |
| 878 |
| 879 final CacheStrategy cacheStrategy; |
| 880 |
| 881 final ResolutionWorldBuilder resolverWorld; |
| 882 |
| 874 bool get isClosed => _closed; | 883 bool get isClosed => _closed; |
| 875 | 884 |
| 876 Set<ClassElement> typesImplementedBySubclassesOf(ClassElement cls) { | 885 Set<ClassElement> typesImplementedBySubclassesOf(ClassElement cls) { |
| 877 return _typesImplementedBySubclasses[cls.declaration]; | 886 return _typesImplementedBySubclasses[cls.declaration]; |
| 878 } | 887 } |
| 879 | 888 |
| 880 WorldImpl(Compiler compiler) | 889 WorldImpl(this.resolverWorld, this._backend, this.coreClasses, |
| 881 : allFunctions = new FunctionSet(compiler), | 890 CacheStrategy cacheStrategy) |
| 882 this._compiler = compiler, | 891 : this.cacheStrategy = cacheStrategy, |
| 883 alreadyPopulated = compiler.cacheStrategy.newSet(); | 892 alreadyPopulated = cacheStrategy.newSet() { |
| 893 _allFunctions = new FunctionSet(this); |
| 894 } |
| 884 | 895 |
| 885 CoreClasses get coreClasses => _compiler.coreClasses; | 896 FunctionSet get allFunctions => _allFunctions; |
| 886 | 897 |
| 887 DiagnosticReporter get reporter => _compiler.reporter; | 898 CommonMasks get commonMasks { |
| 899 assert(isClosed); |
| 900 return _commonMasks; |
| 901 } |
| 888 | 902 |
| 889 /// Called to add [cls] to the set of known classes. | 903 /// Called to add [cls] to the set of known classes. |
| 890 /// | 904 /// |
| 891 /// This ensures that class hierarchy queries can be performed on [cls] and | 905 /// This ensures that class hierarchy queries can be performed on [cls] and |
| 892 /// classes that extend or implement it. | 906 /// classes that extend or implement it. |
| 893 void registerClass(ClassElement cls) => _registerClass(cls); | 907 void registerClass(ClassElement cls) => _registerClass(cls); |
| 894 | 908 |
| 895 void registerClosureClass(ClassElement cls) { | 909 void registerClosureClass(ClassElement cls) { |
| 896 _registerClass(cls, isDirectlyInstantiated: true); | 910 _registerClass(cls, isDirectlyInstantiated: true); |
| 897 } | 911 } |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 972 ClassSet subtypeSet = _ensureClassSet(coreClasses.functionClass); | 986 ClassSet subtypeSet = _ensureClassSet(coreClasses.functionClass); |
| 973 subtypeSet.addSubtype(node); | 987 subtypeSet.addSubtype(node); |
| 974 } | 988 } |
| 975 if (!node.isInstantiated && node.parentNode != null) { | 989 if (!node.isInstantiated && node.parentNode != null) { |
| 976 _updateSuperClassHierarchyNodeForClass(node.parentNode); | 990 _updateSuperClassHierarchyNodeForClass(node.parentNode); |
| 977 } | 991 } |
| 978 } | 992 } |
| 979 | 993 |
| 980 void _updateClassHierarchyNodeForClass(ClassElement cls, | 994 void _updateClassHierarchyNodeForClass(ClassElement cls, |
| 981 {bool directlyInstantiated: false, bool abstractlyInstantiated: false}) { | 995 {bool directlyInstantiated: false, bool abstractlyInstantiated: false}) { |
| 982 ClassHierarchyNode node = getClassHierarchyNode(cls); | 996 ClassHierarchyNode node = _ensureClassHierarchyNode(cls); |
| 983 _updateSuperClassHierarchyNodeForClass(node); | 997 _updateSuperClassHierarchyNodeForClass(node); |
| 984 if (directlyInstantiated) { | 998 if (directlyInstantiated) { |
| 985 node.isDirectlyInstantiated = true; | 999 node.isDirectlyInstantiated = true; |
| 986 } | 1000 } |
| 987 if (abstractlyInstantiated) { | 1001 if (abstractlyInstantiated) { |
| 988 node.isAbstractlyInstantiated = true; | 1002 node.isAbstractlyInstantiated = true; |
| 989 } | 1003 } |
| 990 } | 1004 } |
| 991 | 1005 |
| 992 ClosedWorld closeWorld() { | 1006 ClosedWorld closeWorld(DiagnosticReporter reporter) { |
| 993 /// Updates the `isDirectlyInstantiated` and `isIndirectlyInstantiated` | 1007 /// Updates the `isDirectlyInstantiated` and `isIndirectlyInstantiated` |
| 994 /// properties of the [ClassHierarchyNode] for [cls]. | 1008 /// properties of the [ClassHierarchyNode] for [cls]. |
| 995 | 1009 |
| 996 void addSubtypes(ClassElement cls, EnumSet<Instantiation> instantiations) { | 1010 void addSubtypes(ClassElement cls, EnumSet<Instantiation> instantiations) { |
| 997 if (_compiler.options.hasIncrementalSupport && | 1011 if (cacheStrategy.hasIncrementalSupport && !alreadyPopulated.add(cls)) { |
| 998 !alreadyPopulated.add(cls)) { | |
| 999 return; | 1012 return; |
| 1000 } | 1013 } |
| 1001 assert(cls.isDeclaration); | 1014 assert(cls.isDeclaration); |
| 1002 if (!cls.isResolved) { | 1015 if (!cls.isResolved) { |
| 1003 reporter.internalError(cls, 'Class "${cls.name}" is not resolved.'); | 1016 reporter.internalError(cls, 'Class "${cls.name}" is not resolved.'); |
| 1004 } | 1017 } |
| 1005 | 1018 |
| 1006 _updateClassHierarchyNodeForClass(cls, | 1019 _updateClassHierarchyNodeForClass(cls, |
| 1007 directlyInstantiated: | 1020 directlyInstantiated: |
| 1008 instantiations.contains(Instantiation.DIRECTLY_INSTANTIATED), | 1021 instantiations.contains(Instantiation.DIRECTLY_INSTANTIATED), |
| (...skipping 11 matching lines...) Expand all Loading... |
| 1020 typesImplementedBySubclassesOfCls.add(current.element); | 1033 typesImplementedBySubclassesOfCls.add(current.element); |
| 1021 } | 1034 } |
| 1022 superclass = superclass.superclass; | 1035 superclass = superclass.superclass; |
| 1023 } | 1036 } |
| 1024 } | 1037 } |
| 1025 | 1038 |
| 1026 // Use the [:seenClasses:] set to include non-instantiated | 1039 // Use the [:seenClasses:] set to include non-instantiated |
| 1027 // classes: if the superclass of these classes require RTI, then | 1040 // classes: if the superclass of these classes require RTI, then |
| 1028 // they also need RTI, so that a constructor passes the type | 1041 // they also need RTI, so that a constructor passes the type |
| 1029 // variables to the super constructor. | 1042 // variables to the super constructor. |
| 1030 _compiler.resolverWorld.forEachInstantiatedClass(addSubtypes); | 1043 resolverWorld.forEachInstantiatedClass(addSubtypes); |
| 1031 | 1044 |
| 1032 _closed = true; | 1045 _closed = true; |
| 1046 _commonMasks = new CommonMasks(this); |
| 1033 return this; | 1047 return this; |
| 1034 } | 1048 } |
| 1035 | 1049 |
| 1036 @override | 1050 @override |
| 1037 String dump([ClassElement cls]) { | 1051 String dump([ClassElement cls]) { |
| 1038 StringBuffer sb = new StringBuffer(); | 1052 StringBuffer sb = new StringBuffer(); |
| 1039 if (cls != null) { | 1053 if (cls != null) { |
| 1040 sb.write("Classes in the closed world related to $cls:\n"); | 1054 sb.write("Classes in the closed world related to $cls:\n"); |
| 1041 } else { | 1055 } else { |
| 1042 sb.write("Instantiated classes in the closed world:\n"); | 1056 sb.write("Instantiated classes in the closed world:\n"); |
| (...skipping 22 matching lines...) Expand all Loading... |
| 1065 allFunctions.add(element); | 1079 allFunctions.add(element); |
| 1066 } | 1080 } |
| 1067 } | 1081 } |
| 1068 | 1082 |
| 1069 FieldElement locateSingleField(Selector selector, TypeMask mask) { | 1083 FieldElement locateSingleField(Selector selector, TypeMask mask) { |
| 1070 Element result = locateSingleElement(selector, mask); | 1084 Element result = locateSingleElement(selector, mask); |
| 1071 return (result != null && result.isField) ? result : null; | 1085 return (result != null && result.isField) ? result : null; |
| 1072 } | 1086 } |
| 1073 | 1087 |
| 1074 Element locateSingleElement(Selector selector, TypeMask mask) { | 1088 Element locateSingleElement(Selector selector, TypeMask mask) { |
| 1089 assert(isClosed); |
| 1075 mask ??= commonMasks.dynamicType; | 1090 mask ??= commonMasks.dynamicType; |
| 1076 return mask.locateSingleElement(selector, _compiler); | 1091 return mask.locateSingleElement(selector, this); |
| 1077 } | 1092 } |
| 1078 | 1093 |
| 1079 TypeMask extendMaskIfReachesAll(Selector selector, TypeMask mask) { | 1094 TypeMask extendMaskIfReachesAll(Selector selector, TypeMask mask) { |
| 1095 assert(isClosed); |
| 1080 bool canReachAll = true; | 1096 bool canReachAll = true; |
| 1081 if (mask != null) { | 1097 if (mask != null) { |
| 1082 canReachAll = _compiler.enabledInvokeOn && | 1098 canReachAll = _backend.hasInvokeOnSupport && |
| 1083 mask.needsNoSuchMethodHandling(selector, this); | 1099 mask.needsNoSuchMethodHandling(selector, this); |
| 1084 } | 1100 } |
| 1085 return canReachAll ? commonMasks.dynamicType : mask; | 1101 return canReachAll ? commonMasks.dynamicType : mask; |
| 1086 } | 1102 } |
| 1087 | 1103 |
| 1088 void addFunctionCalledInLoop(Element element) { | 1104 void addFunctionCalledInLoop(Element element) { |
| 1089 functionsCalledInLoop.add(element.declaration); | 1105 functionsCalledInLoop.add(element.declaration); |
| 1090 } | 1106 } |
| 1091 | 1107 |
| 1092 bool isCalledInLoop(Element element) { | 1108 bool isCalledInLoop(Element element) { |
| 1093 return functionsCalledInLoop.contains(element.declaration); | 1109 return functionsCalledInLoop.contains(element.declaration); |
| 1094 } | 1110 } |
| 1095 | 1111 |
| 1096 bool fieldNeverChanges(Element element) { | 1112 bool fieldNeverChanges(Element element) { |
| 1097 if (!element.isField) return false; | 1113 if (!element.isField) return false; |
| 1098 if (_backend.isNative(element)) { | 1114 if (_backend.isNative(element)) { |
| 1099 // Some native fields are views of data that may be changed by operations. | 1115 // Some native fields are views of data that may be changed by operations. |
| 1100 // E.g. node.firstChild depends on parentNode.removeBefore(n1, n2). | 1116 // E.g. node.firstChild depends on parentNode.removeBefore(n1, n2). |
| 1101 // TODO(sra): Refine the effect classification so that native effects are | 1117 // TODO(sra): Refine the effect classification so that native effects are |
| 1102 // distinct from ordinary Dart effects. | 1118 // distinct from ordinary Dart effects. |
| 1103 return false; | 1119 return false; |
| 1104 } | 1120 } |
| 1105 | 1121 |
| 1106 if (element.isFinal || element.isConst) { | 1122 if (element.isFinal || element.isConst) { |
| 1107 return true; | 1123 return true; |
| 1108 } | 1124 } |
| 1109 if (element.isInstanceMember) { | 1125 if (element.isInstanceMember) { |
| 1110 return !_compiler.resolverWorld.hasInvokedSetter(element, this) && | 1126 return !resolverWorld.hasInvokedSetter(element, this) && |
| 1111 !_compiler.resolverWorld.fieldSetters.contains(element); | 1127 !resolverWorld.fieldSetters.contains(element); |
| 1112 } | 1128 } |
| 1113 return false; | 1129 return false; |
| 1114 } | 1130 } |
| 1115 | 1131 |
| 1116 SideEffects getSideEffectsOfElement(Element element) { | 1132 SideEffects getSideEffectsOfElement(Element element) { |
| 1117 // The type inferrer (where the side effects are being computed), | 1133 // The type inferrer (where the side effects are being computed), |
| 1118 // does not see generative constructor bodies because they are | 1134 // does not see generative constructor bodies because they are |
| 1119 // created by the backend. Also, it does not make any distinction | 1135 // created by the backend. Also, it does not make any distinction |
| 1120 // between a constructor and its body for side effects. This | 1136 // between a constructor and its body for side effects. This |
| 1121 // implies that currently, the side effects of a constructor body | 1137 // implies that currently, the side effects of a constructor body |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1202 /// Only the class itself is included. | 1218 /// Only the class itself is included. |
| 1203 EXACT, | 1219 EXACT, |
| 1204 | 1220 |
| 1205 /// The class and all subclasses (transitively) are included. | 1221 /// The class and all subclasses (transitively) are included. |
| 1206 SUBCLASS, | 1222 SUBCLASS, |
| 1207 | 1223 |
| 1208 /// The class and all classes that implement or subclass it (transitively) | 1224 /// The class and all classes that implement or subclass it (transitively) |
| 1209 /// are included. | 1225 /// are included. |
| 1210 SUBTYPE, | 1226 SUBTYPE, |
| 1211 } | 1227 } |
| OLD | NEW |