| 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 |