OLD | NEW |
1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2015, 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 dart2js.js_emitter.program_builder; | 5 part of dart2js.js_emitter.program_builder; |
6 | 6 |
7 /** | 7 /** |
8 * Generates the code for all used classes in the program. Static fields (even | 8 * Generates the code for all used classes in the program. Static fields (even |
9 * in classes) are ignored, since they can be treated as non-class elements. | 9 * in classes) are ignored, since they can be treated as non-class elements. |
10 * | 10 * |
11 * The code for the containing (used) methods must exist in the `universe`. | 11 * The code for the containing (used) methods must exist in the `universe`. |
12 */ | 12 */ |
13 class Collector { | 13 class Collector { |
| 14 final CompilerOptions _options; |
| 15 final CommonElements _commonElements; |
| 16 final DeferredLoadTask _deferredLoadTask; |
| 17 final CodegenWorldBuilder _worldBuilder; |
14 // TODO(floitsch): the code-emitter task should not need a namer. | 18 // TODO(floitsch): the code-emitter task should not need a namer. |
15 final Namer namer; | 19 final Namer _namer; |
16 final Compiler compiler; | 20 final Emitter _emitter; |
17 final ClosedWorld closedWorld; | 21 final JavaScriptConstantCompiler _constantHandler; |
18 final Set<ClassElement> rtiNeededClasses; | 22 final NativeData _nativeData; |
19 final Emitter emitter; | 23 final InterceptorData _interceptorData; |
| 24 final OneShotInterceptorData _oneShotInterceptorData; |
| 25 final MirrorsData _mirrorsData; |
| 26 final ClosedWorld _closedWorld; |
| 27 final Set<ClassElement> _rtiNeededClasses; |
| 28 final Map<MemberElement, js.Expression> _generatedCode; |
20 | 29 |
21 final Set<ClassElement> neededClasses = new Set<ClassElement>(); | 30 final Set<ClassElement> neededClasses = new Set<ClassElement>(); |
22 // This field is set in [computeNeededDeclarations]. | 31 // This field is set in [computeNeededDeclarations]. |
23 Set<ClassElement> classesOnlyNeededForRti; | 32 Set<ClassElement> classesOnlyNeededForRti; |
24 final Map<OutputUnit, List<ClassElement>> outputClassLists = | 33 final Map<OutputUnit, List<ClassElement>> outputClassLists = |
25 new Map<OutputUnit, List<ClassElement>>(); | 34 new Map<OutputUnit, List<ClassElement>>(); |
26 final Map<OutputUnit, List<ConstantValue>> outputConstantLists = | 35 final Map<OutputUnit, List<ConstantValue>> outputConstantLists = |
27 new Map<OutputUnit, List<ConstantValue>>(); | 36 new Map<OutputUnit, List<ConstantValue>>(); |
28 final Map<OutputUnit, List<Element>> outputStaticLists = | 37 final Map<OutputUnit, List<Element>> outputStaticLists = |
29 new Map<OutputUnit, List<Element>>(); | 38 new Map<OutputUnit, List<Element>>(); |
30 final Map<OutputUnit, List<VariableElement>> outputStaticNonFinalFieldLists = | 39 final Map<OutputUnit, List<VariableElement>> outputStaticNonFinalFieldLists = |
31 new Map<OutputUnit, List<VariableElement>>(); | 40 new Map<OutputUnit, List<VariableElement>>(); |
32 final Map<OutputUnit, Set<LibraryElement>> outputLibraryLists = | 41 final Map<OutputUnit, Set<LibraryElement>> outputLibraryLists = |
33 new Map<OutputUnit, Set<LibraryElement>>(); | 42 new Map<OutputUnit, Set<LibraryElement>>(); |
34 | 43 |
35 /// True, if the output contains a constant list. | 44 /// True, if the output contains a constant list. |
36 /// | 45 /// |
37 /// This flag is updated in [computeNeededConstants]. | 46 /// This flag is updated in [computeNeededConstants]. |
38 bool outputContainsConstantList = false; | 47 bool outputContainsConstantList = false; |
39 | 48 |
40 final List<ClassElement> nativeClassesAndSubclasses = <ClassElement>[]; | 49 final List<ClassElement> nativeClassesAndSubclasses = <ClassElement>[]; |
41 | 50 |
42 List<TypedefElement> typedefsNeededForReflection; | 51 List<TypedefElement> typedefsNeededForReflection; |
43 | 52 |
44 JavaScriptBackend get backend => compiler.backend; | 53 Collector( |
45 | 54 this._options, |
46 CommonElements get commonElements => compiler.commonElements; | 55 this._commonElements, |
47 | 56 this._deferredLoadTask, |
48 Collector(this.compiler, this.namer, this.closedWorld, this.rtiNeededClasses, | 57 this._worldBuilder, |
49 this.emitter); | 58 this._namer, |
| 59 this._emitter, |
| 60 this._constantHandler, |
| 61 this._nativeData, |
| 62 this._interceptorData, |
| 63 this._oneShotInterceptorData, |
| 64 this._mirrorsData, |
| 65 this._closedWorld, |
| 66 this._rtiNeededClasses, |
| 67 this._generatedCode); |
50 | 68 |
51 Set<ClassElement> computeInterceptorsReferencedFromConstants() { | 69 Set<ClassElement> computeInterceptorsReferencedFromConstants() { |
52 Set<ClassElement> classes = new Set<ClassElement>(); | 70 Set<ClassElement> classes = new Set<ClassElement>(); |
53 JavaScriptConstantCompiler handler = backend.constants; | 71 JavaScriptConstantCompiler handler = _constantHandler; |
54 List<ConstantValue> constants = handler.getConstantsForEmission(); | 72 List<ConstantValue> constants = handler.getConstantsForEmission(); |
55 for (ConstantValue constant in constants) { | 73 for (ConstantValue constant in constants) { |
56 if (constant is InterceptorConstantValue) { | 74 if (constant is InterceptorConstantValue) { |
57 InterceptorConstantValue interceptorConstant = constant; | 75 InterceptorConstantValue interceptorConstant = constant; |
58 classes.add(interceptorConstant.cls); | 76 classes.add(interceptorConstant.cls); |
59 } | 77 } |
60 } | 78 } |
61 return classes; | 79 return classes; |
62 } | 80 } |
63 | 81 |
64 /** | 82 /** |
65 * Return a function that returns true if its argument is a class | 83 * Return a function that returns true if its argument is a class |
66 * that needs to be emitted. | 84 * that needs to be emitted. |
67 */ | 85 */ |
68 Function computeClassFilter() { | 86 Function computeClassFilter() { |
69 if (backend.mirrorsData.isTreeShakingDisabled) { | 87 if (_mirrorsData.isTreeShakingDisabled) { |
70 return (ClassElement cls) => true; | 88 return (ClassElement cls) => true; |
71 } | 89 } |
72 | 90 |
73 Set<ClassEntity> unneededClasses = new Set<ClassEntity>(); | 91 Set<ClassEntity> unneededClasses = new Set<ClassEntity>(); |
74 // The [Bool] class is not marked as abstract, but has a factory | 92 // The [Bool] class is not marked as abstract, but has a factory |
75 // constructor that always throws. We never need to emit it. | 93 // constructor that always throws. We never need to emit it. |
76 unneededClasses.add(commonElements.boolClass); | 94 unneededClasses.add(_commonElements.boolClass); |
77 | 95 |
78 // Go over specialized interceptors and then constants to know which | 96 // Go over specialized interceptors and then constants to know which |
79 // interceptors are needed. | 97 // interceptors are needed. |
80 Set<ClassEntity> needed = new Set<ClassEntity>(); | 98 Set<ClassEntity> needed = new Set<ClassEntity>(); |
81 for (js.Name name | 99 for (js.Name name |
82 in backend.oneShotInterceptorData.specializedGetInterceptorNames) { | 100 in _oneShotInterceptorData.specializedGetInterceptorNames) { |
83 needed.addAll(backend.oneShotInterceptorData | 101 needed.addAll( |
84 .getSpecializedGetInterceptorsFor(name)); | 102 _oneShotInterceptorData.getSpecializedGetInterceptorsFor(name)); |
85 } | 103 } |
86 | 104 |
87 // Add interceptors referenced by constants. | 105 // Add interceptors referenced by constants. |
88 needed.addAll(computeInterceptorsReferencedFromConstants()); | 106 needed.addAll(computeInterceptorsReferencedFromConstants()); |
89 | 107 |
90 // Add unneeded interceptors to the [unneededClasses] set. | 108 // Add unneeded interceptors to the [unneededClasses] set. |
91 for (ClassEntity interceptor | 109 for (ClassEntity interceptor in _interceptorData.interceptedClasses) { |
92 in backend.interceptorData.interceptedClasses) { | |
93 if (!needed.contains(interceptor) && | 110 if (!needed.contains(interceptor) && |
94 interceptor != commonElements.objectClass) { | 111 interceptor != _commonElements.objectClass) { |
95 unneededClasses.add(interceptor); | 112 unneededClasses.add(interceptor); |
96 } | 113 } |
97 } | 114 } |
98 | 115 |
99 // These classes are just helpers for the backend's type system. | 116 // These classes are just helpers for the backend's type system. |
100 unneededClasses.add(commonElements.jsMutableArrayClass); | 117 unneededClasses.add(_commonElements.jsMutableArrayClass); |
101 unneededClasses.add(commonElements.jsFixedArrayClass); | 118 unneededClasses.add(_commonElements.jsFixedArrayClass); |
102 unneededClasses.add(commonElements.jsExtendableArrayClass); | 119 unneededClasses.add(_commonElements.jsExtendableArrayClass); |
103 unneededClasses.add(commonElements.jsUInt32Class); | 120 unneededClasses.add(_commonElements.jsUInt32Class); |
104 unneededClasses.add(commonElements.jsUInt31Class); | 121 unneededClasses.add(_commonElements.jsUInt31Class); |
105 unneededClasses.add(commonElements.jsPositiveIntClass); | 122 unneededClasses.add(_commonElements.jsPositiveIntClass); |
106 | 123 |
107 return (ClassEntity cls) => !unneededClasses.contains(cls); | 124 return (ClassEntity cls) => !unneededClasses.contains(cls); |
108 } | 125 } |
109 | 126 |
110 /** | 127 /** |
111 * Compute all the constants that must be emitted. | 128 * Compute all the constants that must be emitted. |
112 */ | 129 */ |
113 void computeNeededConstants() { | 130 void computeNeededConstants() { |
114 // Make sure we retain all metadata of all elements. This could add new | 131 // Make sure we retain all metadata of all elements. This could add new |
115 // constants to the handler. | 132 // constants to the handler. |
116 if (backend.mirrorsData.mustRetainMetadata) { | 133 if (_mirrorsData.mustRetainMetadata) { |
117 // TODO(floitsch): verify that we don't run through the same elements | 134 // TODO(floitsch): verify that we don't run through the same elements |
118 // multiple times. | 135 // multiple times. |
119 for (MemberElement element in backend.generatedCode.keys) { | 136 for (MemberElement element in _generatedCode.keys) { |
120 if (backend.mirrorsData.isMemberAccessibleByReflection(element)) { | 137 if (_mirrorsData.isMemberAccessibleByReflection(element)) { |
121 bool shouldRetainMetadata = | 138 bool shouldRetainMetadata = |
122 backend.mirrorsData.retainMetadataOfMember(element); | 139 _mirrorsData.retainMetadataOfMember(element); |
123 if (shouldRetainMetadata && | 140 if (shouldRetainMetadata && |
124 (element.isFunction || | 141 (element.isFunction || |
125 element.isConstructor || | 142 element.isConstructor || |
126 element.isSetter)) { | 143 element.isSetter)) { |
127 MethodElement function = element; | 144 MethodElement function = element; |
128 function.functionSignature.forEachParameter( | 145 function.functionSignature |
129 backend.mirrorsData.retainMetadataOfParameter); | 146 .forEachParameter(_mirrorsData.retainMetadataOfParameter); |
130 } | 147 } |
131 } | 148 } |
132 } | 149 } |
133 for (ClassElement cls in neededClasses) { | 150 for (ClassElement cls in neededClasses) { |
134 final onlyForRti = classesOnlyNeededForRti.contains(cls); | 151 final onlyForRti = classesOnlyNeededForRti.contains(cls); |
135 if (!onlyForRti) { | 152 if (!onlyForRti) { |
136 backend.mirrorsData.retainMetadataOfClass(cls); | 153 _mirrorsData.retainMetadataOfClass(cls); |
137 new FieldVisitor(compiler.options, compiler.codegenWorldBuilder, | 154 new FieldVisitor(_options, _worldBuilder, _nativeData, _mirrorsData, |
138 backend.nativeData, backend.mirrorsData, namer, closedWorld) | 155 _namer, _closedWorld) |
139 .visitFields(cls, false, (FieldElement member, | 156 .visitFields(cls, false, (FieldElement member, |
140 js.Name name, | 157 js.Name name, |
141 js.Name accessorName, | 158 js.Name accessorName, |
142 bool needsGetter, | 159 bool needsGetter, |
143 bool needsSetter, | 160 bool needsSetter, |
144 bool needsCheckedSetter) { | 161 bool needsCheckedSetter) { |
145 bool needsAccessor = needsGetter || needsSetter; | 162 bool needsAccessor = needsGetter || needsSetter; |
146 if (needsAccessor && | 163 if (needsAccessor && |
147 backend.mirrorsData.isMemberAccessibleByReflection(member)) { | 164 _mirrorsData.isMemberAccessibleByReflection(member)) { |
148 backend.mirrorsData.retainMetadataOfMember(member); | 165 _mirrorsData.retainMetadataOfMember(member); |
149 } | 166 } |
150 }); | 167 }); |
151 } | 168 } |
152 } | 169 } |
153 typedefsNeededForReflection | 170 typedefsNeededForReflection.forEach(_mirrorsData.retainMetadataOfTypedef); |
154 .forEach(backend.mirrorsData.retainMetadataOfTypedef); | |
155 } | 171 } |
156 | 172 |
157 JavaScriptConstantCompiler handler = backend.constants; | 173 JavaScriptConstantCompiler handler = _constantHandler; |
158 List<ConstantValue> constants = | 174 List<ConstantValue> constants = |
159 handler.getConstantsForEmission(emitter.compareConstants); | 175 handler.getConstantsForEmission(_emitter.compareConstants); |
160 for (ConstantValue constant in constants) { | 176 for (ConstantValue constant in constants) { |
161 if (emitter.isConstantInlinedOrAlreadyEmitted(constant)) continue; | 177 if (_emitter.isConstantInlinedOrAlreadyEmitted(constant)) continue; |
162 | 178 |
163 if (constant.isList) outputContainsConstantList = true; | 179 if (constant.isList) outputContainsConstantList = true; |
164 | 180 |
165 OutputUnit constantUnit = | 181 OutputUnit constantUnit = |
166 compiler.deferredLoadTask.outputUnitForConstant(constant); | 182 _deferredLoadTask.outputUnitForConstant(constant); |
167 if (constantUnit == null) { | 183 if (constantUnit == null) { |
168 // The back-end introduces some constants, like "InterceptorConstant" or | 184 // The back-end introduces some constants, like "InterceptorConstant" or |
169 // some list constants. They are emitted in the main output-unit. | 185 // some list constants. They are emitted in the main output-unit. |
170 // TODO(sigurdm): We should track those constants. | 186 // TODO(sigurdm): We should track those constants. |
171 constantUnit = compiler.deferredLoadTask.mainOutputUnit; | 187 constantUnit = _deferredLoadTask.mainOutputUnit; |
172 } | 188 } |
173 outputConstantLists | 189 outputConstantLists |
174 .putIfAbsent(constantUnit, () => new List<ConstantValue>()) | 190 .putIfAbsent(constantUnit, () => new List<ConstantValue>()) |
175 .add(constant); | 191 .add(constant); |
176 } | 192 } |
177 } | 193 } |
178 | 194 |
179 /// Compute all the classes and typedefs that must be emitted. | 195 /// Compute all the classes and typedefs that must be emitted. |
180 void computeNeededDeclarations() { | 196 void computeNeededDeclarations() { |
181 // Compute needed typedefs. | 197 // Compute needed typedefs. |
182 typedefsNeededForReflection = Elements.sortedByPosition(closedWorld | 198 typedefsNeededForReflection = Elements.sortedByPosition(_closedWorld |
183 .allTypedefs | 199 .allTypedefs |
184 .where(backend.mirrorsData.isTypedefAccessibleByReflection) | 200 .where(_mirrorsData.isTypedefAccessibleByReflection) |
185 .toList()); | 201 .toList()); |
186 | 202 |
187 // Compute needed classes. | 203 // Compute needed classes. |
188 Set<ClassElement> instantiatedClasses = compiler | 204 Set<ClassElement> instantiatedClasses = |
189 // TODO(johnniwinther): This should be accessed from a codegen closed | 205 // TODO(johnniwinther): This should be accessed from a codegen closed |
190 // world. | 206 // world. |
191 .codegenWorldBuilder | 207 _worldBuilder.directlyInstantiatedClasses |
192 .directlyInstantiatedClasses | 208 .where(computeClassFilter()) |
193 .where(computeClassFilter()) | 209 .toSet(); |
194 .toSet(); | |
195 | 210 |
196 void addClassWithSuperclasses(ClassElement cls) { | 211 void addClassWithSuperclasses(ClassElement cls) { |
197 neededClasses.add(cls); | 212 neededClasses.add(cls); |
198 for (ClassElement superclass = cls.superclass; | 213 for (ClassElement superclass = cls.superclass; |
199 superclass != null; | 214 superclass != null; |
200 superclass = superclass.superclass) { | 215 superclass = superclass.superclass) { |
201 neededClasses.add(superclass); | 216 neededClasses.add(superclass); |
202 } | 217 } |
203 } | 218 } |
204 | 219 |
(...skipping 13 matching lines...) Expand all Loading... |
218 .toSet(); | 233 .toSet(); |
219 neededClasses.addAll(mixinClasses); | 234 neededClasses.addAll(mixinClasses); |
220 | 235 |
221 // 3. Find all classes needed for rti. | 236 // 3. Find all classes needed for rti. |
222 // It is important that this is the penultimate step, at this point, | 237 // It is important that this is the penultimate step, at this point, |
223 // neededClasses must only contain classes that have been resolved and | 238 // neededClasses must only contain classes that have been resolved and |
224 // codegen'd. The rtiNeededClasses may contain additional classes, but | 239 // codegen'd. The rtiNeededClasses may contain additional classes, but |
225 // these are thought to not have been instantiated, so we neeed to be able | 240 // these are thought to not have been instantiated, so we neeed to be able |
226 // to identify them later and make sure we only emit "empty shells" without | 241 // to identify them later and make sure we only emit "empty shells" without |
227 // fields, etc. | 242 // fields, etc. |
228 classesOnlyNeededForRti = rtiNeededClasses.difference(neededClasses); | 243 classesOnlyNeededForRti = _rtiNeededClasses.difference(neededClasses); |
229 | 244 |
230 neededClasses.addAll(classesOnlyNeededForRti); | 245 neededClasses.addAll(classesOnlyNeededForRti); |
231 | 246 |
232 // TODO(18175, floitsch): remove once issue 18175 is fixed. | 247 // TODO(18175, floitsch): remove once issue 18175 is fixed. |
233 if (neededClasses.contains(commonElements.jsIntClass)) { | 248 if (neededClasses.contains(_commonElements.jsIntClass)) { |
234 neededClasses.add(commonElements.intClass); | 249 neededClasses.add(_commonElements.intClass); |
235 } | 250 } |
236 if (neededClasses.contains(commonElements.jsDoubleClass)) { | 251 if (neededClasses.contains(_commonElements.jsDoubleClass)) { |
237 neededClasses.add(commonElements.doubleClass); | 252 neededClasses.add(_commonElements.doubleClass); |
238 } | 253 } |
239 if (neededClasses.contains(commonElements.jsNumberClass)) { | 254 if (neededClasses.contains(_commonElements.jsNumberClass)) { |
240 neededClasses.add(commonElements.numClass); | 255 neededClasses.add(_commonElements.numClass); |
241 } | 256 } |
242 if (neededClasses.contains(commonElements.jsStringClass)) { | 257 if (neededClasses.contains(_commonElements.jsStringClass)) { |
243 neededClasses.add(commonElements.stringClass); | 258 neededClasses.add(_commonElements.stringClass); |
244 } | 259 } |
245 if (neededClasses.contains(commonElements.jsBoolClass)) { | 260 if (neededClasses.contains(_commonElements.jsBoolClass)) { |
246 neededClasses.add(commonElements.boolClass); | 261 neededClasses.add(_commonElements.boolClass); |
247 } | 262 } |
248 if (neededClasses.contains(commonElements.jsArrayClass)) { | 263 if (neededClasses.contains(_commonElements.jsArrayClass)) { |
249 neededClasses.add(commonElements.listClass); | 264 neededClasses.add(_commonElements.listClass); |
250 } | 265 } |
251 | 266 |
252 // 4. Finally, sort the classes. | 267 // 4. Finally, sort the classes. |
253 List<ClassElement> sortedClasses = Elements.sortedByPosition(neededClasses); | 268 List<ClassElement> sortedClasses = Elements.sortedByPosition(neededClasses); |
254 | 269 |
255 for (ClassElement element in sortedClasses) { | 270 for (ClassElement element in sortedClasses) { |
256 if (backend.nativeData.isNativeOrExtendsNative(element) && | 271 if (_nativeData.isNativeOrExtendsNative(element) && |
257 !classesOnlyNeededForRti.contains(element)) { | 272 !classesOnlyNeededForRti.contains(element)) { |
258 // For now, native classes and related classes cannot be deferred. | 273 // For now, native classes and related classes cannot be deferred. |
259 nativeClassesAndSubclasses.add(element); | 274 nativeClassesAndSubclasses.add(element); |
260 assert( | 275 assert(invariant(element, !_deferredLoadTask.isDeferred(element))); |
261 invariant(element, !compiler.deferredLoadTask.isDeferred(element))); | |
262 outputClassLists | 276 outputClassLists |
263 .putIfAbsent(compiler.deferredLoadTask.mainOutputUnit, | 277 .putIfAbsent(_deferredLoadTask.mainOutputUnit, |
264 () => new List<ClassElement>()) | 278 () => new List<ClassElement>()) |
265 .add(element); | 279 .add(element); |
266 } else { | 280 } else { |
267 outputClassLists | 281 outputClassLists |
268 .putIfAbsent( | 282 .putIfAbsent(_deferredLoadTask.outputUnitForElement(element), |
269 compiler.deferredLoadTask.outputUnitForElement(element), | |
270 () => new List<ClassElement>()) | 283 () => new List<ClassElement>()) |
271 .add(element); | 284 .add(element); |
272 } | 285 } |
273 } | 286 } |
274 } | 287 } |
275 | 288 |
276 void computeNeededStatics() { | 289 void computeNeededStatics() { |
277 bool isStaticFunction(MemberElement element) => | 290 bool isStaticFunction(MemberElement element) => |
278 !element.isInstanceMember && !element.isField; | 291 !element.isInstanceMember && !element.isField; |
279 | 292 |
280 Iterable<MemberElement> elements = | 293 Iterable<MemberElement> elements = |
281 backend.generatedCode.keys.where(isStaticFunction); | 294 _generatedCode.keys.where(isStaticFunction); |
282 | 295 |
283 for (Element element in Elements.sortedByPosition(elements)) { | 296 for (Element element in Elements.sortedByPosition(elements)) { |
284 List<Element> list = outputStaticLists.putIfAbsent( | 297 List<Element> list = outputStaticLists.putIfAbsent( |
285 compiler.deferredLoadTask.outputUnitForElement(element), | 298 _deferredLoadTask.outputUnitForElement(element), |
286 () => new List<Element>()); | 299 () => new List<Element>()); |
287 list.add(element); | 300 list.add(element); |
288 } | 301 } |
289 } | 302 } |
290 | 303 |
291 void computeNeededStaticNonFinalFields() { | 304 void computeNeededStaticNonFinalFields() { |
292 addToOutputUnit(Element element) { | 305 addToOutputUnit(Element element) { |
293 List<VariableElement> list = outputStaticNonFinalFieldLists.putIfAbsent( | 306 List<VariableElement> list = outputStaticNonFinalFieldLists.putIfAbsent( |
294 compiler.deferredLoadTask.outputUnitForElement(element), | 307 _deferredLoadTask.outputUnitForElement(element), |
295 () => new List<VariableElement>()); | 308 () => new List<VariableElement>()); |
296 list.add(element); | 309 list.add(element); |
297 } | 310 } |
298 | 311 |
299 Iterable<FieldElement> fields = compiler | 312 Iterable<FieldElement> fields = |
300 // TODO(johnniwinther): This should be accessed from a codegen closed | 313 // TODO(johnniwinther): This should be accessed from a codegen closed |
301 // world. | 314 // world. |
302 .codegenWorldBuilder | 315 _worldBuilder.allReferencedStaticFields.where((FieldElement field) { |
303 .allReferencedStaticFields | |
304 .where((FieldElement field) { | |
305 if (!field.isConst) { | 316 if (!field.isConst) { |
306 return field.isField && | 317 return field.isField && |
307 !field.isInstanceMember && | 318 !field.isInstanceMember && |
308 !field.isFinal && | 319 !field.isFinal && |
309 field.constant != null; | 320 field.constant != null; |
310 } else { | 321 } else { |
311 // We also need to emit static const fields if they are available for | 322 // We also need to emit static const fields if they are available for |
312 // reflection. | 323 // reflection. |
313 return backend.mirrorsData.isMemberAccessibleByReflection(field); | 324 return _mirrorsData.isMemberAccessibleByReflection(field); |
314 } | 325 } |
315 }); | 326 }); |
316 | 327 |
317 Elements.sortedByPosition(fields).forEach(addToOutputUnit); | 328 Elements.sortedByPosition(fields).forEach(addToOutputUnit); |
318 } | 329 } |
319 | 330 |
320 void computeNeededLibraries() { | 331 void computeNeededLibraries() { |
321 void addSurroundingLibraryToSet(Element element) { | 332 void addSurroundingLibraryToSet(Element element) { |
322 OutputUnit unit = compiler.deferredLoadTask.outputUnitForElement(element); | 333 OutputUnit unit = _deferredLoadTask.outputUnitForElement(element); |
323 LibraryElement library = element.library; | 334 LibraryElement library = element.library; |
324 outputLibraryLists | 335 outputLibraryLists |
325 .putIfAbsent(unit, () => new Set<LibraryElement>()) | 336 .putIfAbsent(unit, () => new Set<LibraryElement>()) |
326 .add(library); | 337 .add(library); |
327 } | 338 } |
328 | 339 |
329 backend.generatedCode.keys.forEach(addSurroundingLibraryToSet); | 340 _generatedCode.keys.forEach(addSurroundingLibraryToSet); |
330 neededClasses.forEach(addSurroundingLibraryToSet); | 341 neededClasses.forEach(addSurroundingLibraryToSet); |
331 } | 342 } |
332 | 343 |
333 void collect() { | 344 void collect() { |
334 computeNeededDeclarations(); | 345 computeNeededDeclarations(); |
335 computeNeededConstants(); | 346 computeNeededConstants(); |
336 computeNeededStatics(); | 347 computeNeededStatics(); |
337 computeNeededStaticNonFinalFields(); | 348 computeNeededStaticNonFinalFields(); |
338 computeNeededLibraries(); | 349 computeNeededLibraries(); |
339 } | 350 } |
340 } | 351 } |
OLD | NEW |