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 |