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 * |
(...skipping 24 matching lines...) Expand all Loading... |
35 /// | 35 /// |
36 /// This flag is updated in [computeNeededConstants]. | 36 /// This flag is updated in [computeNeededConstants]. |
37 bool outputContainsConstantList = false; | 37 bool outputContainsConstantList = false; |
38 | 38 |
39 final List<ClassElement> nativeClassesAndSubclasses = <ClassElement>[]; | 39 final List<ClassElement> nativeClassesAndSubclasses = <ClassElement>[]; |
40 | 40 |
41 List<TypedefElement> typedefsNeededForReflection; | 41 List<TypedefElement> typedefsNeededForReflection; |
42 | 42 |
43 JavaScriptBackend get backend => compiler.backend; | 43 JavaScriptBackend get backend => compiler.backend; |
44 | 44 |
| 45 CoreClasses get coreClasses => compiler.coreClasses; |
| 46 |
45 Collector(this.compiler, this.namer, this.rtiNeededClasses, this.emitter); | 47 Collector(this.compiler, this.namer, this.rtiNeededClasses, this.emitter); |
46 | 48 |
47 Set<ClassElement> computeInterceptorsReferencedFromConstants() { | 49 Set<ClassElement> computeInterceptorsReferencedFromConstants() { |
48 Set<ClassElement> classes = new Set<ClassElement>(); | 50 Set<ClassElement> classes = new Set<ClassElement>(); |
49 JavaScriptConstantCompiler handler = backend.constants; | 51 JavaScriptConstantCompiler handler = backend.constants; |
50 List<ConstantValue> constants = handler.getConstantsForEmission(); | 52 List<ConstantValue> constants = handler.getConstantsForEmission(); |
51 for (ConstantValue constant in constants) { | 53 for (ConstantValue constant in constants) { |
52 if (constant is InterceptorConstantValue) { | 54 if (constant is InterceptorConstantValue) { |
53 InterceptorConstantValue interceptorConstant = constant; | 55 InterceptorConstantValue interceptorConstant = constant; |
54 classes.add(interceptorConstant.dispatchedType.element); | 56 classes.add(interceptorConstant.dispatchedType.element); |
55 } | 57 } |
56 } | 58 } |
57 return classes; | 59 return classes; |
58 } | 60 } |
59 | 61 |
60 /** | 62 /** |
61 * Return a function that returns true if its argument is a class | 63 * Return a function that returns true if its argument is a class |
62 * that needs to be emitted. | 64 * that needs to be emitted. |
63 */ | 65 */ |
64 Function computeClassFilter() { | 66 Function computeClassFilter() { |
65 if (backend.isTreeShakingDisabled) return (ClassElement cls) => true; | 67 if (backend.isTreeShakingDisabled) return (ClassElement cls) => true; |
66 | 68 |
67 Set<ClassElement> unneededClasses = new Set<ClassElement>(); | 69 Set<ClassElement> unneededClasses = new Set<ClassElement>(); |
68 // The [Bool] class is not marked as abstract, but has a factory | 70 // The [Bool] class is not marked as abstract, but has a factory |
69 // constructor that always throws. We never need to emit it. | 71 // constructor that always throws. We never need to emit it. |
70 unneededClasses.add(compiler.boolClass); | 72 unneededClasses.add(coreClasses.boolClass); |
71 | 73 |
72 // Go over specialized interceptors and then constants to know which | 74 // Go over specialized interceptors and then constants to know which |
73 // interceptors are needed. | 75 // interceptors are needed. |
74 Set<ClassElement> needed = new Set<ClassElement>(); | 76 Set<ClassElement> needed = new Set<ClassElement>(); |
75 backend.specializedGetInterceptors.forEach( | 77 backend.specializedGetInterceptors.forEach( |
76 (_, Iterable<ClassElement> elements) { | 78 (_, Iterable<ClassElement> elements) { |
77 needed.addAll(elements); | 79 needed.addAll(elements); |
78 } | 80 } |
79 ); | 81 ); |
80 | 82 |
81 // Add interceptors referenced by constants. | 83 // Add interceptors referenced by constants. |
82 needed.addAll(computeInterceptorsReferencedFromConstants()); | 84 needed.addAll(computeInterceptorsReferencedFromConstants()); |
83 | 85 |
84 // Add unneeded interceptors to the [unneededClasses] set. | 86 // Add unneeded interceptors to the [unneededClasses] set. |
85 for (ClassElement interceptor in backend.interceptedClasses) { | 87 for (ClassElement interceptor in backend.interceptedClasses) { |
86 if (!needed.contains(interceptor) | 88 if (!needed.contains(interceptor) |
87 && interceptor != compiler.objectClass) { | 89 && interceptor != coreClasses.objectClass) { |
88 unneededClasses.add(interceptor); | 90 unneededClasses.add(interceptor); |
89 } | 91 } |
90 } | 92 } |
91 | 93 |
92 // These classes are just helpers for the backend's type system. | 94 // These classes are just helpers for the backend's type system. |
93 unneededClasses.add(backend.jsMutableArrayClass); | 95 unneededClasses.add(backend.jsMutableArrayClass); |
94 unneededClasses.add(backend.jsFixedArrayClass); | 96 unneededClasses.add(backend.jsFixedArrayClass); |
95 unneededClasses.add(backend.jsExtendableArrayClass); | 97 unneededClasses.add(backend.jsExtendableArrayClass); |
96 unneededClasses.add(backend.jsUInt32Class); | 98 unneededClasses.add(backend.jsUInt32Class); |
97 unneededClasses.add(backend.jsUInt31Class); | 99 unneededClasses.add(backend.jsUInt31Class); |
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
207 // codegen'd. The rtiNeededClasses may contain additional classes, but | 209 // codegen'd. The rtiNeededClasses may contain additional classes, but |
208 // these are thought to not have been instantiated, so we neeed to be able | 210 // these are thought to not have been instantiated, so we neeed to be able |
209 // to identify them later and make sure we only emit "empty shells" without | 211 // to identify them later and make sure we only emit "empty shells" without |
210 // fields, etc. | 212 // fields, etc. |
211 classesOnlyNeededForRti = rtiNeededClasses.difference(neededClasses); | 213 classesOnlyNeededForRti = rtiNeededClasses.difference(neededClasses); |
212 | 214 |
213 neededClasses.addAll(classesOnlyNeededForRti); | 215 neededClasses.addAll(classesOnlyNeededForRti); |
214 | 216 |
215 // TODO(18175, floitsch): remove once issue 18175 is fixed. | 217 // TODO(18175, floitsch): remove once issue 18175 is fixed. |
216 if (neededClasses.contains(backend.jsIntClass)) { | 218 if (neededClasses.contains(backend.jsIntClass)) { |
217 neededClasses.add(compiler.intClass); | 219 neededClasses.add(coreClasses.intClass); |
218 } | 220 } |
219 if (neededClasses.contains(backend.jsDoubleClass)) { | 221 if (neededClasses.contains(backend.jsDoubleClass)) { |
220 neededClasses.add(compiler.doubleClass); | 222 neededClasses.add(coreClasses.doubleClass); |
221 } | 223 } |
222 if (neededClasses.contains(backend.jsNumberClass)) { | 224 if (neededClasses.contains(backend.jsNumberClass)) { |
223 neededClasses.add(compiler.numClass); | 225 neededClasses.add(coreClasses.numClass); |
224 } | 226 } |
225 if (neededClasses.contains(backend.jsStringClass)) { | 227 if (neededClasses.contains(backend.jsStringClass)) { |
226 neededClasses.add(compiler.stringClass); | 228 neededClasses.add(coreClasses.stringClass); |
227 } | 229 } |
228 if (neededClasses.contains(backend.jsBoolClass)) { | 230 if (neededClasses.contains(backend.jsBoolClass)) { |
229 neededClasses.add(compiler.boolClass); | 231 neededClasses.add(coreClasses.boolClass); |
230 } | 232 } |
231 if (neededClasses.contains(backend.jsArrayClass)) { | 233 if (neededClasses.contains(backend.jsArrayClass)) { |
232 neededClasses.add(compiler.listClass); | 234 neededClasses.add(coreClasses.listClass); |
233 } | 235 } |
234 | 236 |
235 // 4. Finally, sort the classes. | 237 // 4. Finally, sort the classes. |
236 List<ClassElement> sortedClasses = Elements.sortedByPosition(neededClasses); | 238 List<ClassElement> sortedClasses = Elements.sortedByPosition(neededClasses); |
237 | 239 |
238 for (ClassElement element in sortedClasses) { | 240 for (ClassElement element in sortedClasses) { |
239 if (backend.isNativeOrExtendsNative(element) && | 241 if (backend.isNativeOrExtendsNative(element) && |
240 !classesOnlyNeededForRti.contains(element)) { | 242 !classesOnlyNeededForRti.contains(element)) { |
241 // For now, native classes and related classes cannot be deferred. | 243 // For now, native classes and related classes cannot be deferred. |
242 nativeClassesAndSubclasses.add(element); | 244 nativeClassesAndSubclasses.add(element); |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
304 } | 306 } |
305 | 307 |
306 void collect() { | 308 void collect() { |
307 computeNeededDeclarations(); | 309 computeNeededDeclarations(); |
308 computeNeededConstants(); | 310 computeNeededConstants(); |
309 computeNeededStatics(); | 311 computeNeededStatics(); |
310 computeNeededStaticNonFinalFields(); | 312 computeNeededStaticNonFinalFields(); |
311 computeNeededLibraries(); | 313 computeNeededLibraries(); |
312 } | 314 } |
313 } | 315 } |
OLD | NEW |