| OLD | NEW |
| 1 // Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2017, 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 part of world_builder; | 5 part of world_builder; |
| 6 | 6 |
| 7 /// World builder specific to codegen. | 7 /// World builder specific to codegen. |
| 8 /// | 8 /// |
| 9 /// This adds additional access to liveness of selectors and elements. | 9 /// This adds additional access to liveness of selectors and elements. |
| 10 abstract class CodegenWorldBuilder implements WorldBuilder { | 10 abstract class CodegenWorldBuilder implements WorldBuilder { |
| (...skipping 10 matching lines...) Expand all Loading... |
| 21 void forEachInvokedName( | 21 void forEachInvokedName( |
| 22 f(String name, Map<Selector, SelectorConstraints> selectors)); | 22 f(String name, Map<Selector, SelectorConstraints> selectors)); |
| 23 | 23 |
| 24 void forEachInvokedGetter( | 24 void forEachInvokedGetter( |
| 25 f(String name, Map<Selector, SelectorConstraints> selectors)); | 25 f(String name, Map<Selector, SelectorConstraints> selectors)); |
| 26 | 26 |
| 27 void forEachInvokedSetter( | 27 void forEachInvokedSetter( |
| 28 f(String name, Map<Selector, SelectorConstraints> selectors)); | 28 f(String name, Map<Selector, SelectorConstraints> selectors)); |
| 29 | 29 |
| 30 /// Returns `true` if [member] is invoked as a setter. | 30 /// Returns `true` if [member] is invoked as a setter. |
| 31 bool hasInvokedSetter(Element member, ClosedWorld world); | 31 bool hasInvokedSetter(MemberEntity member, ClosedWorld world); |
| 32 | 32 |
| 33 bool hasInvokedGetter(Element member, ClosedWorld world); | 33 bool hasInvokedGetter(MemberEntity member, ClosedWorld world); |
| 34 | 34 |
| 35 Map<Selector, SelectorConstraints> invocationsByName(String name); | 35 Map<Selector, SelectorConstraints> invocationsByName(String name); |
| 36 | 36 |
| 37 Map<Selector, SelectorConstraints> getterInvocationsByName(String name); | 37 Map<Selector, SelectorConstraints> getterInvocationsByName(String name); |
| 38 | 38 |
| 39 Map<Selector, SelectorConstraints> setterInvocationsByName(String name); | 39 Map<Selector, SelectorConstraints> setterInvocationsByName(String name); |
| 40 | 40 |
| 41 Iterable<FunctionEntity> get staticFunctionsNeedingGetter; | 41 Iterable<FunctionEntity> get staticFunctionsNeedingGetter; |
| 42 Iterable<FunctionEntity> get methodsNeedingSuperGetter; | 42 Iterable<FunctionEntity> get methodsNeedingSuperGetter; |
| 43 | 43 |
| 44 /// The set of all referenced static fields. | 44 /// The set of all referenced static fields. |
| 45 /// | 45 /// |
| 46 /// Invariant: Elements are declaration elements. | 46 /// Invariant: Elements are declaration elements. |
| 47 Iterable<FieldEntity> get allReferencedStaticFields; | 47 Iterable<FieldEntity> get allReferencedStaticFields; |
| 48 | 48 |
| 49 /// Set of methods in instantiated classes that are potentially closurized. | 49 /// Set of methods in instantiated classes that are potentially closurized. |
| 50 Iterable<FunctionEntity> get closurizedMembers; | 50 Iterable<FunctionEntity> get closurizedMembers; |
| 51 } | 51 } |
| 52 | 52 |
| 53 class CodegenWorldBuilderImpl implements CodegenWorldBuilder { | 53 abstract class CodegenWorldBuilderImpl implements CodegenWorldBuilder { |
| 54 final NativeBasicData _nativeData; | 54 final ElementEnvironment _elementEnvironment; |
| 55 final NativeBasicData _nativeBasicData; |
| 55 final ClosedWorld _world; | 56 final ClosedWorld _world; |
| 56 final JavaScriptConstantCompiler _constants; | |
| 57 | 57 |
| 58 /// The set of all directly instantiated classes, that is, classes with a | 58 /// The set of all directly instantiated classes, that is, classes with a |
| 59 /// generative constructor that has been called directly and not only through | 59 /// generative constructor that has been called directly and not only through |
| 60 /// a super-call. | 60 /// a super-call. |
| 61 /// | 61 /// |
| 62 /// Invariant: Elements are declaration elements. | 62 /// Invariant: Elements are declaration elements. |
| 63 // TODO(johnniwinther): [_directlyInstantiatedClasses] and | 63 // TODO(johnniwinther): [_directlyInstantiatedClasses] and |
| 64 // [_instantiatedTypes] sets should be merged. | 64 // [_instantiatedTypes] sets should be merged. |
| 65 final Set<ClassElement> _directlyInstantiatedClasses = | 65 final Set<ClassEntity> _directlyInstantiatedClasses = new Set<ClassEntity>(); |
| 66 new Set<ClassElement>(); | |
| 67 | 66 |
| 68 /// The set of all directly instantiated types, that is, the types of the | 67 /// The set of all directly instantiated types, that is, the types of the |
| 69 /// directly instantiated classes. | 68 /// directly instantiated classes. |
| 70 /// | 69 /// |
| 71 /// See [_directlyInstantiatedClasses]. | 70 /// See [_directlyInstantiatedClasses]. |
| 72 final Set<InterfaceType> _instantiatedTypes = new Set<InterfaceType>(); | 71 final Set<InterfaceType> _instantiatedTypes = new Set<InterfaceType>(); |
| 73 | 72 |
| 74 /// Classes implemented by directly instantiated classes. | 73 /// Classes implemented by directly instantiated classes. |
| 75 final Set<ClassElement> _implementedClasses = new Set<ClassElement>(); | 74 final Set<ClassEntity> _implementedClasses = new Set<ClassEntity>(); |
| 76 | 75 |
| 77 /// The set of all referenced static fields. | 76 /// The set of all referenced static fields. |
| 78 /// | 77 /// |
| 79 /// Invariant: Elements are declaration elements. | 78 /// Invariant: Elements are declaration elements. |
| 80 final Set<FieldElement> allReferencedStaticFields = new Set<FieldElement>(); | 79 final Set<FieldEntity> allReferencedStaticFields = new Set<FieldEntity>(); |
| 81 | 80 |
| 82 /** | 81 /** |
| 83 * Documentation wanted -- johnniwinther | 82 * Documentation wanted -- johnniwinther |
| 84 * | 83 * |
| 85 * Invariant: Elements are declaration elements. | 84 * Invariant: Elements are declaration elements. |
| 86 */ | 85 */ |
| 87 final Set<FunctionEntity> staticFunctionsNeedingGetter = | 86 final Set<FunctionEntity> staticFunctionsNeedingGetter = |
| 88 new Set<FunctionEntity>(); | 87 new Set<FunctionEntity>(); |
| 89 final Set<FunctionEntity> methodsNeedingSuperGetter = | 88 final Set<FunctionEntity> methodsNeedingSuperGetter = |
| 90 new Set<FunctionEntity>(); | 89 new Set<FunctionEntity>(); |
| 91 final Map<String, Map<Selector, SelectorConstraints>> _invokedNames = | 90 final Map<String, Map<Selector, SelectorConstraints>> _invokedNames = |
| 92 <String, Map<Selector, SelectorConstraints>>{}; | 91 <String, Map<Selector, SelectorConstraints>>{}; |
| 93 final Map<String, Map<Selector, SelectorConstraints>> _invokedGetters = | 92 final Map<String, Map<Selector, SelectorConstraints>> _invokedGetters = |
| 94 <String, Map<Selector, SelectorConstraints>>{}; | 93 <String, Map<Selector, SelectorConstraints>>{}; |
| 95 final Map<String, Map<Selector, SelectorConstraints>> _invokedSetters = | 94 final Map<String, Map<Selector, SelectorConstraints>> _invokedSetters = |
| 96 <String, Map<Selector, SelectorConstraints>>{}; | 95 <String, Map<Selector, SelectorConstraints>>{}; |
| 97 | 96 |
| 98 final Map<ClassElement, _ClassUsage> _processedClasses = | 97 final Map<ClassEntity, _ClassUsage> _processedClasses = |
| 99 <ClassElement, _ClassUsage>{}; | 98 <ClassEntity, _ClassUsage>{}; |
| 100 | 99 |
| 101 /// Map of registered usage of static members of live classes. | 100 /// Map of registered usage of static members of live classes. |
| 102 final Map<Entity, _StaticMemberUsage> _staticMemberUsage = | 101 final Map<Entity, _StaticMemberUsage> _staticMemberUsage = |
| 103 <Entity, _StaticMemberUsage>{}; | 102 <Entity, _StaticMemberUsage>{}; |
| 104 | 103 |
| 105 /// Map of registered usage of instance members of live classes. | 104 /// Map of registered usage of instance members of live classes. |
| 106 final Map<MemberEntity, _MemberUsage> _instanceMemberUsage = | 105 final Map<MemberEntity, _MemberUsage> _instanceMemberUsage = |
| 107 <MemberEntity, _MemberUsage>{}; | 106 <MemberEntity, _MemberUsage>{}; |
| 108 | 107 |
| 109 /// Map containing instance members of live classes that are not yet live | 108 /// Map containing instance members of live classes that are not yet live |
| 110 /// themselves. | 109 /// themselves. |
| 111 final Map<String, Set<_MemberUsage>> _instanceMembersByName = | 110 final Map<String, Set<_MemberUsage>> _instanceMembersByName = |
| 112 <String, Set<_MemberUsage>>{}; | 111 <String, Set<_MemberUsage>>{}; |
| 113 | 112 |
| 114 /// Map containing instance methods of live classes that are not yet | 113 /// Map containing instance methods of live classes that are not yet |
| 115 /// closurized. | 114 /// closurized. |
| 116 final Map<String, Set<_MemberUsage>> _instanceFunctionsByName = | 115 final Map<String, Set<_MemberUsage>> _instanceFunctionsByName = |
| 117 <String, Set<_MemberUsage>>{}; | 116 <String, Set<_MemberUsage>>{}; |
| 118 | 117 |
| 119 final Set<ResolutionDartType> isChecks = new Set<ResolutionDartType>(); | 118 final Set<DartType> isChecks = new Set<DartType>(); |
| 120 | 119 |
| 121 final SelectorConstraintsStrategy selectorConstraintsStrategy; | 120 final SelectorConstraintsStrategy selectorConstraintsStrategy; |
| 122 | 121 |
| 123 final Set<ConstantValue> _constantValues = new Set<ConstantValue>(); | 122 final Set<ConstantValue> _constantValues = new Set<ConstantValue>(); |
| 124 | 123 |
| 125 /// Set of methods in instantiated classes that are potentially closurized. | 124 /// Set of methods in instantiated classes that are potentially closurized. |
| 126 final Set<FunctionEntity> closurizedMembers = new Set<FunctionEntity>(); | 125 final Set<FunctionEntity> closurizedMembers = new Set<FunctionEntity>(); |
| 127 | 126 |
| 128 CodegenWorldBuilderImpl(this._nativeData, this._world, this._constants, | 127 CodegenWorldBuilderImpl(this._elementEnvironment, this._nativeBasicData, |
| 129 this.selectorConstraintsStrategy); | 128 this._world, this.selectorConstraintsStrategy); |
| 130 | 129 |
| 131 /// Calls [f] with every instance field, together with its declarer, in an | 130 Iterable<ClassEntity> get processedClasses => _processedClasses.keys |
| 132 /// instance of [cls]. | |
| 133 void forEachInstanceField( | |
| 134 ClassElement cls, void f(ClassEntity declarer, FieldEntity field)) { | |
| 135 cls.implementation | |
| 136 .forEachInstanceField(f, includeSuperAndInjectedMembers: true); | |
| 137 } | |
| 138 | |
| 139 @override | |
| 140 void forEachParameter( | |
| 141 MethodElement function, void f(DartType type, String name)) { | |
| 142 FunctionSignature parameters = function.functionSignature; | |
| 143 parameters.forEachParameter((ParameterElement parameter) { | |
| 144 f(parameter.type, parameter.name); | |
| 145 }); | |
| 146 } | |
| 147 | |
| 148 Iterable<ClassElement> get processedClasses => _processedClasses.keys | |
| 149 .where((cls) => _processedClasses[cls].isInstantiated); | 131 .where((cls) => _processedClasses[cls].isInstantiated); |
| 150 | 132 |
| 151 /// All directly instantiated classes, that is, classes with a generative | 133 /// All directly instantiated classes, that is, classes with a generative |
| 152 /// constructor that has been called directly and not only through a | 134 /// constructor that has been called directly and not only through a |
| 153 /// super-call. | 135 /// super-call. |
| 154 // TODO(johnniwinther): Improve semantic precision. | 136 // TODO(johnniwinther): Improve semantic precision. |
| 155 Iterable<ClassElement> get directlyInstantiatedClasses { | 137 Iterable<ClassEntity> get directlyInstantiatedClasses { |
| 156 return _directlyInstantiatedClasses; | 138 return _directlyInstantiatedClasses; |
| 157 } | 139 } |
| 158 | 140 |
| 159 /// All directly instantiated types, that is, the types of the directly | 141 /// All directly instantiated types, that is, the types of the directly |
| 160 /// instantiated classes. | 142 /// instantiated classes. |
| 161 /// | 143 /// |
| 162 /// See [directlyInstantiatedClasses]. | 144 /// See [directlyInstantiatedClasses]. |
| 163 // TODO(johnniwinther): Improve semantic precision. | 145 // TODO(johnniwinther): Improve semantic precision. |
| 164 Iterable<InterfaceType> get instantiatedTypes => _instantiatedTypes; | 146 Iterable<InterfaceType> get instantiatedTypes => _instantiatedTypes; |
| 165 | 147 |
| 166 /// Register [type] as (directly) instantiated. | 148 /// Register [type] as (directly) instantiated. |
| 167 /// | 149 /// |
| 168 /// If [byMirrors] is `true`, the instantiation is through mirrors. | 150 /// If [byMirrors] is `true`, the instantiation is through mirrors. |
| 169 // TODO(johnniwinther): Fully enforce the separation between exact, through | 151 // TODO(johnniwinther): Fully enforce the separation between exact, through |
| 170 // subclass and through subtype instantiated types/classes. | 152 // subclass and through subtype instantiated types/classes. |
| 171 // TODO(johnniwinther): Support unknown type arguments for generic types. | 153 // TODO(johnniwinther): Support unknown type arguments for generic types. |
| 172 void registerTypeInstantiation( | 154 void registerTypeInstantiation( |
| 173 ResolutionInterfaceType type, ClassUsedCallback classUsed, | 155 InterfaceType type, ClassUsedCallback classUsed, |
| 174 {bool byMirrors: false}) { | 156 {bool byMirrors: false}) { |
| 175 ClassElement cls = type.element; | 157 ClassEntity cls = type.element; |
| 176 bool isNative = _nativeData.isNativeClass(cls); | 158 bool isNative = _nativeBasicData.isNativeClass(cls); |
| 177 _instantiatedTypes.add(type); | 159 _instantiatedTypes.add(type); |
| 178 if (!cls.isAbstract | 160 if (!cls.isAbstract |
| 179 // We can't use the closed-world assumption with native abstract | 161 // We can't use the closed-world assumption with native abstract |
| 180 // classes; a native abstract class may have non-abstract subclasses | 162 // classes; a native abstract class may have non-abstract subclasses |
| 181 // not declared to the program. Instances of these classes are | 163 // not declared to the program. Instances of these classes are |
| 182 // indistinguishable from the abstract class. | 164 // indistinguishable from the abstract class. |
| 183 || | 165 || |
| 184 isNative | 166 isNative |
| 185 // Likewise, if this registration comes from the mirror system, | 167 // Likewise, if this registration comes from the mirror system, |
| 186 // all bets are off. | 168 // all bets are off. |
| 187 // TODO(herhut): Track classes required by mirrors separately. | 169 // TODO(herhut): Track classes required by mirrors separately. |
| 188 || | 170 || |
| 189 byMirrors) { | 171 byMirrors) { |
| 190 _directlyInstantiatedClasses.add(cls); | 172 _directlyInstantiatedClasses.add(cls); |
| 191 _processInstantiatedClass(cls, classUsed); | 173 _processInstantiatedClass(cls, classUsed); |
| 192 } | 174 } |
| 193 | 175 |
| 194 // TODO(johnniwinther): Replace this by separate more specific mappings that | 176 // TODO(johnniwinther): Replace this by separate more specific mappings that |
| 195 // include the type arguments. | 177 // include the type arguments. |
| 196 if (_implementedClasses.add(cls)) { | 178 if (_implementedClasses.add(cls)) { |
| 197 classUsed(cls, _getClassUsage(cls).implement()); | 179 classUsed(cls, _getClassUsage(cls).implement()); |
| 198 cls.allSupertypes.forEach((ResolutionInterfaceType supertype) { | 180 _elementEnvironment.forEachSupertype(cls, (InterfaceType supertype) { |
| 199 if (_implementedClasses.add(supertype.element)) { | 181 if (_implementedClasses.add(supertype.element)) { |
| 200 classUsed( | 182 classUsed( |
| 201 supertype.element, _getClassUsage(supertype.element).implement()); | 183 supertype.element, _getClassUsage(supertype.element).implement()); |
| 202 } | 184 } |
| 203 }); | 185 }); |
| 204 } | 186 } |
| 205 } | 187 } |
| 206 | 188 |
| 207 bool _hasMatchingSelector(Map<Selector, SelectorConstraints> selectors, | 189 bool _hasMatchingSelector(Map<Selector, SelectorConstraints> selectors, |
| 208 MemberElement member, ClosedWorld world) { | 190 MemberEntity member, ClosedWorld world) { |
| 209 if (selectors == null) return false; | 191 if (selectors == null) return false; |
| 210 for (Selector selector in selectors.keys) { | 192 for (Selector selector in selectors.keys) { |
| 211 if (selector.appliesUnnamed(member)) { | 193 if (selector.appliesUnnamed(member)) { |
| 212 SelectorConstraints masks = selectors[selector]; | 194 SelectorConstraints masks = selectors[selector]; |
| 213 if (masks.applies(member, selector, world)) { | 195 if (masks.applies(member, selector, world)) { |
| 214 return true; | 196 return true; |
| 215 } | 197 } |
| 216 } | 198 } |
| 217 } | 199 } |
| 218 return false; | 200 return false; |
| 219 } | 201 } |
| 220 | 202 |
| 221 bool hasInvocation(Element member, ClosedWorld world) { | 203 bool hasInvocation(MemberEntity member, ClosedWorld world) { |
| 222 return _hasMatchingSelector(_invokedNames[member.name], member, world); | 204 return _hasMatchingSelector(_invokedNames[member.name], member, world); |
| 223 } | 205 } |
| 224 | 206 |
| 225 bool hasInvokedGetter(Element member, ClosedWorld world) { | 207 bool hasInvokedGetter(MemberEntity member, ClosedWorld world) { |
| 226 return _hasMatchingSelector(_invokedGetters[member.name], member, world) || | 208 return _hasMatchingSelector(_invokedGetters[member.name], member, world) || |
| 227 member.isFunction && methodsNeedingSuperGetter.contains(member); | 209 member.isFunction && methodsNeedingSuperGetter.contains(member); |
| 228 } | 210 } |
| 229 | 211 |
| 230 bool hasInvokedSetter(Element member, ClosedWorld world) { | 212 bool hasInvokedSetter(MemberEntity member, ClosedWorld world) { |
| 231 return _hasMatchingSelector(_invokedSetters[member.name], member, world); | 213 return _hasMatchingSelector(_invokedSetters[member.name], member, world); |
| 232 } | 214 } |
| 233 | 215 |
| 234 bool registerDynamicUse( | 216 bool registerDynamicUse( |
| 235 DynamicUse dynamicUse, MemberUsedCallback memberUsed) { | 217 DynamicUse dynamicUse, MemberUsedCallback memberUsed) { |
| 236 Selector selector = dynamicUse.selector; | 218 Selector selector = dynamicUse.selector; |
| 237 String methodName = selector.name; | 219 String methodName = selector.name; |
| 238 | 220 |
| 239 void _process(Map<String, Set<_MemberUsage>> memberMap, | 221 void _process(Map<String, Set<_MemberUsage>> memberMap, |
| 240 EnumSet<MemberUse> action(_MemberUsage usage)) { | 222 EnumSet<MemberUse> action(_MemberUsage usage)) { |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 311 void forEachInvokedGetter( | 293 void forEachInvokedGetter( |
| 312 f(String name, Map<Selector, SelectorConstraints> selectors)) { | 294 f(String name, Map<Selector, SelectorConstraints> selectors)) { |
| 313 _invokedGetters.forEach(f); | 295 _invokedGetters.forEach(f); |
| 314 } | 296 } |
| 315 | 297 |
| 316 void forEachInvokedSetter( | 298 void forEachInvokedSetter( |
| 317 f(String name, Map<Selector, SelectorConstraints> selectors)) { | 299 f(String name, Map<Selector, SelectorConstraints> selectors)) { |
| 318 _invokedSetters.forEach(f); | 300 _invokedSetters.forEach(f); |
| 319 } | 301 } |
| 320 | 302 |
| 321 void registerIsCheck(ResolutionDartType type) { | 303 void registerIsCheck(DartType type) { |
| 322 type = type.unaliased; | 304 isChecks.add(type.unaliased); |
| 323 // Even in checked mode, type annotations for return type and argument | |
| 324 // types do not imply type checks, so there should never be a check | |
| 325 // against the type variable of a typedef. | |
| 326 assert(!type.isTypeVariable || !type.element.enclosingElement.isTypedef); | |
| 327 isChecks.add(type); | |
| 328 } | 305 } |
| 329 | 306 |
| 330 void _registerStaticUse(StaticUse staticUse) { | 307 void _registerStaticUse(StaticUse staticUse) { |
| 331 Element element = staticUse.element; | 308 if (staticUse.element is FieldEntity) { |
| 332 if (Elements.isStaticOrTopLevel(element) && element.isField) { | 309 FieldEntity field = staticUse.element; |
| 333 allReferencedStaticFields.add(element); | 310 if (field.isTopLevel || field.isStatic) { |
| 311 allReferencedStaticFields.add(field); |
| 312 } |
| 334 } | 313 } |
| 335 switch (staticUse.kind) { | 314 switch (staticUse.kind) { |
| 336 case StaticUseKind.STATIC_TEAR_OFF: | 315 case StaticUseKind.STATIC_TEAR_OFF: |
| 337 MethodElement method = element; | 316 staticFunctionsNeedingGetter.add(staticUse.element); |
| 338 staticFunctionsNeedingGetter.add(method); | |
| 339 break; | 317 break; |
| 340 case StaticUseKind.SUPER_TEAR_OFF: | 318 case StaticUseKind.SUPER_TEAR_OFF: |
| 341 MethodElement method = element; | 319 methodsNeedingSuperGetter.add(staticUse.element); |
| 342 methodsNeedingSuperGetter.add(method); | |
| 343 break; | 320 break; |
| 344 case StaticUseKind.SUPER_FIELD_SET: | 321 case StaticUseKind.SUPER_FIELD_SET: |
| 345 case StaticUseKind.FIELD_SET: | 322 case StaticUseKind.FIELD_SET: |
| 346 case StaticUseKind.GENERAL: | 323 case StaticUseKind.GENERAL: |
| 347 case StaticUseKind.DIRECT_USE: | 324 case StaticUseKind.DIRECT_USE: |
| 348 case StaticUseKind.CLOSURE: | 325 case StaticUseKind.CLOSURE: |
| 349 case StaticUseKind.FIELD_GET: | 326 case StaticUseKind.FIELD_GET: |
| 350 case StaticUseKind.CONSTRUCTOR_INVOKE: | 327 case StaticUseKind.CONSTRUCTOR_INVOKE: |
| 351 case StaticUseKind.CONST_CONSTRUCTOR_INVOKE: | 328 case StaticUseKind.CONST_CONSTRUCTOR_INVOKE: |
| 352 case StaticUseKind.REDIRECTION: | 329 case StaticUseKind.REDIRECTION: |
| 353 case StaticUseKind.DIRECT_INVOKE: | 330 case StaticUseKind.DIRECT_INVOKE: |
| 354 case StaticUseKind.INLINING: | 331 case StaticUseKind.INLINING: |
| 355 break; | 332 break; |
| 356 } | 333 } |
| 357 } | 334 } |
| 358 | 335 |
| 359 void registerStaticUse(StaticUse staticUse, MemberUsedCallback memberUsed) { | 336 void registerStaticUse(StaticUse staticUse, MemberUsedCallback memberUsed) { |
| 360 Element element = staticUse.element; | 337 Entity element = staticUse.element; |
| 361 assert(invariant(element, element.isDeclaration, | |
| 362 message: "Element ${element} is not the declaration.")); | |
| 363 _registerStaticUse(staticUse); | 338 _registerStaticUse(staticUse); |
| 364 _StaticMemberUsage usage = _staticMemberUsage.putIfAbsent(element, () { | 339 _StaticMemberUsage usage = _staticMemberUsage.putIfAbsent(element, () { |
| 365 if ((element.isStatic || element.isTopLevel) && element.isFunction) { | 340 if (element is MemberEntity && |
| 341 (element.isStatic || element.isTopLevel) && |
| 342 element.isFunction) { |
| 366 return new _StaticFunctionUsage(element); | 343 return new _StaticFunctionUsage(element); |
| 367 } else { | 344 } else { |
| 368 return new _GeneralStaticMemberUsage(element); | 345 return new _GeneralStaticMemberUsage(element); |
| 369 } | 346 } |
| 370 }); | 347 }); |
| 371 EnumSet<MemberUse> useSet = new EnumSet<MemberUse>(); | 348 EnumSet<MemberUse> useSet = new EnumSet<MemberUse>(); |
| 372 switch (staticUse.kind) { | 349 switch (staticUse.kind) { |
| 373 case StaticUseKind.STATIC_TEAR_OFF: | 350 case StaticUseKind.STATIC_TEAR_OFF: |
| 374 useSet.addAll(usage.tearOff()); | 351 useSet.addAll(usage.tearOff()); |
| 375 break; | 352 break; |
| (...skipping 30 matching lines...) Expand all Loading... |
| 406 if (useSet.isNotEmpty) { | 383 if (useSet.isNotEmpty) { |
| 407 memberUsed(usage.entity, useSet); | 384 memberUsed(usage.entity, useSet); |
| 408 } | 385 } |
| 409 } | 386 } |
| 410 | 387 |
| 411 /// Registers that [element] has been closurized. | 388 /// Registers that [element] has been closurized. |
| 412 void registerClosurizedMember(MemberEntity element) { | 389 void registerClosurizedMember(MemberEntity element) { |
| 413 closurizedMembers.add(element); | 390 closurizedMembers.add(element); |
| 414 } | 391 } |
| 415 | 392 |
| 416 void processClassMembers(ClassElement cls, MemberUsedCallback memberUsed) { | 393 void processClassMembers(ClassEntity cls, MemberUsedCallback memberUsed) { |
| 417 cls.implementation.forEachMember((_, MemberElement member) { | 394 _elementEnvironment.forEachClassMember(cls, |
| 418 assert(invariant(member, member.isDeclaration)); | 395 (ClassEntity cls, MemberEntity member) { |
| 419 if (!member.isInstanceMember) return; | 396 _processInstantiatedClassMember(cls, member, memberUsed); |
| 420 if (member.isMalformed) return; | |
| 421 _getMemberUsage(member, memberUsed); | |
| 422 }); | 397 }); |
| 423 } | 398 } |
| 424 | 399 |
| 400 void _processInstantiatedClassMember( |
| 401 ClassEntity cls, MemberEntity member, MemberUsedCallback memberUsed) { |
| 402 if (!member.isInstanceMember) return; |
| 403 _getMemberUsage(member, memberUsed); |
| 404 } |
| 405 |
| 425 _MemberUsage _getMemberUsage( | 406 _MemberUsage _getMemberUsage( |
| 426 MemberElement member, MemberUsedCallback memberUsed) { | 407 MemberEntity member, MemberUsedCallback memberUsed) { |
| 427 assert(invariant(member, member.isDeclaration)); | |
| 428 return _instanceMemberUsage.putIfAbsent(member, () { | 408 return _instanceMemberUsage.putIfAbsent(member, () { |
| 429 String memberName = member.name; | 409 String memberName = member.name; |
| 430 ClassElement cls = member.enclosingClass; | 410 ClassEntity cls = member.enclosingClass; |
| 431 bool isNative = _nativeData.isNativeClass(cls); | 411 bool isNative = _nativeBasicData.isNativeClass(cls); |
| 432 _MemberUsage usage = new _MemberUsage(member, isNative: isNative); | 412 _MemberUsage usage = new _MemberUsage(member, isNative: isNative); |
| 433 EnumSet<MemberUse> useSet = new EnumSet<MemberUse>(); | 413 EnumSet<MemberUse> useSet = new EnumSet<MemberUse>(); |
| 434 useSet.addAll(usage.appliedUse); | 414 useSet.addAll(usage.appliedUse); |
| 435 if (hasInvokedGetter(member, _world)) { | 415 if (hasInvokedGetter(member, _world)) { |
| 436 useSet.addAll(usage.read()); | 416 useSet.addAll(usage.read()); |
| 437 } | 417 } |
| 438 if (hasInvokedSetter(member, _world)) { | 418 if (hasInvokedSetter(member, _world)) { |
| 439 useSet.addAll(usage.write()); | 419 useSet.addAll(usage.write()); |
| 440 } | 420 } |
| 441 if (hasInvocation(member, _world)) { | 421 if (hasInvocation(member, _world)) { |
| (...skipping 28 matching lines...) Expand all Loading... |
| 470 // [remaining] members after the loop. | 450 // [remaining] members after the loop. |
| 471 map[memberName] = new Set<_MemberUsage>(); | 451 map[memberName] = new Set<_MemberUsage>(); |
| 472 Set<_MemberUsage> remaining = new Set<_MemberUsage>(); | 452 Set<_MemberUsage> remaining = new Set<_MemberUsage>(); |
| 473 for (_MemberUsage member in members) { | 453 for (_MemberUsage member in members) { |
| 474 if (!f(member)) remaining.add(member); | 454 if (!f(member)) remaining.add(member); |
| 475 } | 455 } |
| 476 map[memberName].addAll(remaining); | 456 map[memberName].addAll(remaining); |
| 477 } | 457 } |
| 478 | 458 |
| 479 /// Return the canonical [_ClassUsage] for [cls]. | 459 /// Return the canonical [_ClassUsage] for [cls]. |
| 480 _ClassUsage _getClassUsage(ClassElement cls) { | 460 _ClassUsage _getClassUsage(ClassEntity cls) { |
| 481 return _processedClasses.putIfAbsent(cls, () => new _ClassUsage(cls)); | 461 return _processedClasses.putIfAbsent(cls, () => new _ClassUsage(cls)); |
| 482 } | 462 } |
| 483 | 463 |
| 484 void _processInstantiatedClass( | 464 void _processInstantiatedClass(ClassEntity cls, ClassUsedCallback classUsed) { |
| 485 ClassElement cls, ClassUsedCallback classUsed) { | |
| 486 // Registers [superclass] as instantiated. Returns `true` if it wasn't | 465 // Registers [superclass] as instantiated. Returns `true` if it wasn't |
| 487 // already instantiated and we therefore have to process its superclass as | 466 // already instantiated and we therefore have to process its superclass as |
| 488 // well. | 467 // well. |
| 489 bool processClass(ClassElement superclass) { | 468 bool processClass(ClassEntity superclass) { |
| 490 _ClassUsage usage = _getClassUsage(superclass); | 469 _ClassUsage usage = _getClassUsage(superclass); |
| 491 if (!usage.isInstantiated) { | 470 if (!usage.isInstantiated) { |
| 492 classUsed(usage.cls, usage.instantiate()); | 471 classUsed(usage.cls, usage.instantiate()); |
| 493 return true; | 472 return true; |
| 494 } | 473 } |
| 495 return false; | 474 return false; |
| 496 } | 475 } |
| 497 | 476 |
| 498 while (cls != null && processClass(cls)) { | 477 while (cls != null && processClass(cls)) { |
| 499 cls = cls.superclass; | 478 cls = _elementEnvironment.getSuperClass(cls); |
| 500 } | 479 } |
| 501 } | 480 } |
| 502 | 481 |
| 482 bool registerConstantUse(ConstantUse use); |
| 483 } |
| 484 |
| 485 class ElementCodegenWorldBuilderImpl extends CodegenWorldBuilderImpl { |
| 486 final JavaScriptConstantCompiler _constants; |
| 487 |
| 488 ElementCodegenWorldBuilderImpl( |
| 489 ElementEnvironment elementEnvironment, |
| 490 NativeBasicData nativeBasicData, |
| 491 ClosedWorld world, |
| 492 this._constants, |
| 493 SelectorConstraintsStrategy selectorConstraintsStrategy) |
| 494 : super(elementEnvironment, nativeBasicData, world, |
| 495 selectorConstraintsStrategy); |
| 496 |
| 497 /// Calls [f] with every instance field, together with its declarer, in an |
| 498 /// instance of [cls]. |
| 499 void forEachInstanceField( |
| 500 ClassElement cls, void f(ClassEntity declarer, FieldEntity field)) { |
| 501 cls.implementation |
| 502 .forEachInstanceField(f, includeSuperAndInjectedMembers: true); |
| 503 } |
| 504 |
| 505 @override |
| 506 void forEachParameter( |
| 507 MethodElement function, void f(DartType type, String name)) { |
| 508 FunctionSignature parameters = function.functionSignature; |
| 509 parameters.forEachParameter((ParameterElement parameter) { |
| 510 f(parameter.type, parameter.name); |
| 511 }); |
| 512 } |
| 513 |
| 514 @override |
| 515 void _processInstantiatedClassMember( |
| 516 ClassEntity cls, MemberElement member, MemberUsedCallback memberUsed) { |
| 517 assert(invariant(member, member.isDeclaration)); |
| 518 if (member.isMalformed) return; |
| 519 super._processInstantiatedClassMember(cls, member, memberUsed); |
| 520 } |
| 521 |
| 522 @override |
| 523 _MemberUsage _getMemberUsage( |
| 524 MemberElement member, MemberUsedCallback memberUsed) { |
| 525 assert(invariant(member, member.isDeclaration)); |
| 526 return super._getMemberUsage(member, memberUsed); |
| 527 } |
| 528 |
| 529 void registerStaticUse(StaticUse staticUse, MemberUsedCallback memberUsed) { |
| 530 Element element = staticUse.element; |
| 531 assert(invariant(element, element.isDeclaration, |
| 532 message: "Element ${element} is not the declaration.")); |
| 533 super.registerStaticUse(staticUse, memberUsed); |
| 534 } |
| 535 |
| 503 /// Register the constant [use] with this world builder. Returns `true` if | 536 /// Register the constant [use] with this world builder. Returns `true` if |
| 504 /// the constant use was new to the world. | 537 /// the constant use was new to the world. |
| 538 @override |
| 505 bool registerConstantUse(ConstantUse use) { | 539 bool registerConstantUse(ConstantUse use) { |
| 506 if (use.kind == ConstantUseKind.DIRECT) { | 540 if (use.kind == ConstantUseKind.DIRECT) { |
| 507 _constants.addCompileTimeConstantForEmission(use.value); | 541 _constants.addCompileTimeConstantForEmission(use.value); |
| 508 } | 542 } |
| 509 return _constantValues.add(use.value); | 543 return _constantValues.add(use.value); |
| 510 } | 544 } |
| 545 |
| 546 void registerIsCheck(ResolutionDartType type) { |
| 547 // Even in checked mode, type annotations for return type and argument |
| 548 // types do not imply type checks, so there should never be a check |
| 549 // against the type variable of a typedef. |
| 550 assert(!type.isTypeVariable || !type.element.enclosingElement.isTypedef); |
| 551 super.registerIsCheck(type); |
| 552 } |
| 511 } | 553 } |
| 554 |
| 555 class KernelCodegenWorldBuilder extends CodegenWorldBuilderImpl { |
| 556 KernelCodegenWorldBuilder( |
| 557 ElementEnvironment elementEnvironment, |
| 558 NativeBasicData nativeBasicData, |
| 559 ClosedWorld world, |
| 560 SelectorConstraintsStrategy selectorConstraintsStrategy) |
| 561 : super(elementEnvironment, nativeBasicData, world, |
| 562 selectorConstraintsStrategy); |
| 563 |
| 564 @override |
| 565 bool registerConstantUse(ConstantUse use) { |
| 566 throw new UnimplementedError( |
| 567 'KernelCodegenWorldBuilder.registerConstantUse'); |
| 568 } |
| 569 |
| 570 @override |
| 571 void forEachParameter( |
| 572 FunctionEntity function, void f(DartType type, String name)) { |
| 573 throw new UnimplementedError('KernelCodegenWorldBuilder.forEachParameter'); |
| 574 } |
| 575 |
| 576 @override |
| 577 void forEachInstanceField( |
| 578 ClassEntity cls, void f(ClassEntity declarer, FieldEntity field)) { |
| 579 throw new UnimplementedError( |
| 580 'KernelCodegenWorldBuilder.forEachInstanceField'); |
| 581 } |
| 582 } |
| OLD | NEW |