| 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 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 111 | 111 |
| 112 /** | 112 /** |
| 113 * Compute all the constants that must be emitted. | 113 * Compute all the constants that must be emitted. |
| 114 */ | 114 */ |
| 115 void computeNeededConstants() { | 115 void computeNeededConstants() { |
| 116 // Make sure we retain all metadata of all elements. This could add new | 116 // Make sure we retain all metadata of all elements. This could add new |
| 117 // constants to the handler. | 117 // constants to the handler. |
| 118 if (backend.mirrorsData.mustRetainMetadata) { | 118 if (backend.mirrorsData.mustRetainMetadata) { |
| 119 // TODO(floitsch): verify that we don't run through the same elements | 119 // TODO(floitsch): verify that we don't run through the same elements |
| 120 // multiple times. | 120 // multiple times. |
| 121 for (Element element in backend.generatedCode.keys) { | 121 for (MemberElement element in backend.generatedCode.keys) { |
| 122 if (backend.mirrorsData.isAccessibleByReflection(element)) { | 122 if (backend.mirrorsData.isMemberAccessibleByReflection(element)) { |
| 123 bool shouldRetainMetadata = | 123 bool shouldRetainMetadata = |
| 124 backend.mirrorsData.retainMetadataOf(element); | 124 backend.mirrorsData.retainMetadataOfMember(element); |
| 125 if (shouldRetainMetadata && | 125 if (shouldRetainMetadata && |
| 126 (element.isFunction || | 126 (element.isFunction || |
| 127 element.isConstructor || | 127 element.isConstructor || |
| 128 element.isSetter)) { | 128 element.isSetter)) { |
| 129 FunctionElement function = element; | 129 MethodElement function = element; |
| 130 function.functionSignature | 130 function.functionSignature.forEachParameter( |
| 131 .forEachParameter(backend.mirrorsData.retainMetadataOf); | 131 backend.mirrorsData.retainMetadataOfParameter); |
| 132 } | 132 } |
| 133 } | 133 } |
| 134 } | 134 } |
| 135 for (ClassElement cls in neededClasses) { | 135 for (ClassElement cls in neededClasses) { |
| 136 final onlyForRti = classesOnlyNeededForRti.contains(cls); | 136 final onlyForRti = classesOnlyNeededForRti.contains(cls); |
| 137 if (!onlyForRti) { | 137 if (!onlyForRti) { |
| 138 backend.mirrorsData.retainMetadataOf(cls); | 138 backend.mirrorsData.retainMetadataOfClass(cls); |
| 139 new FieldVisitor(compiler, namer, closedWorld).visitFields(cls, false, | 139 new FieldVisitor(compiler, namer, closedWorld).visitFields(cls, false, |
| 140 (Element member, js.Name name, js.Name accessorName, | 140 (FieldElement member, js.Name name, js.Name accessorName, |
| 141 bool needsGetter, bool needsSetter, bool needsCheckedSetter) { | 141 bool needsGetter, bool needsSetter, bool needsCheckedSetter) { |
| 142 bool needsAccessor = needsGetter || needsSetter; | 142 bool needsAccessor = needsGetter || needsSetter; |
| 143 if (needsAccessor && | 143 if (needsAccessor && |
| 144 backend.mirrorsData.isAccessibleByReflection(member)) { | 144 backend.mirrorsData.isMemberAccessibleByReflection(member)) { |
| 145 backend.mirrorsData.retainMetadataOf(member); | 145 backend.mirrorsData.retainMetadataOfMember(member); |
| 146 } | 146 } |
| 147 }); | 147 }); |
| 148 } | 148 } |
| 149 } | 149 } |
| 150 typedefsNeededForReflection.forEach(backend.mirrorsData.retainMetadataOf); | 150 typedefsNeededForReflection |
| 151 .forEach(backend.mirrorsData.retainMetadataOfTypedef); |
| 151 } | 152 } |
| 152 | 153 |
| 153 JavaScriptConstantCompiler handler = backend.constants; | 154 JavaScriptConstantCompiler handler = backend.constants; |
| 154 List<ConstantValue> constants = | 155 List<ConstantValue> constants = |
| 155 handler.getConstantsForEmission(emitter.compareConstants); | 156 handler.getConstantsForEmission(emitter.compareConstants); |
| 156 for (ConstantValue constant in constants) { | 157 for (ConstantValue constant in constants) { |
| 157 if (emitter.isConstantInlinedOrAlreadyEmitted(constant)) continue; | 158 if (emitter.isConstantInlinedOrAlreadyEmitted(constant)) continue; |
| 158 | 159 |
| 159 if (constant.isList) outputContainsConstantList = true; | 160 if (constant.isList) outputContainsConstantList = true; |
| 160 | 161 |
| 161 OutputUnit constantUnit = | 162 OutputUnit constantUnit = |
| 162 compiler.deferredLoadTask.outputUnitForConstant(constant); | 163 compiler.deferredLoadTask.outputUnitForConstant(constant); |
| 163 if (constantUnit == null) { | 164 if (constantUnit == null) { |
| 164 // The back-end introduces some constants, like "InterceptorConstant" or | 165 // The back-end introduces some constants, like "InterceptorConstant" or |
| 165 // some list constants. They are emitted in the main output-unit. | 166 // some list constants. They are emitted in the main output-unit. |
| 166 // TODO(sigurdm): We should track those constants. | 167 // TODO(sigurdm): We should track those constants. |
| 167 constantUnit = compiler.deferredLoadTask.mainOutputUnit; | 168 constantUnit = compiler.deferredLoadTask.mainOutputUnit; |
| 168 } | 169 } |
| 169 outputConstantLists | 170 outputConstantLists |
| 170 .putIfAbsent(constantUnit, () => new List<ConstantValue>()) | 171 .putIfAbsent(constantUnit, () => new List<ConstantValue>()) |
| 171 .add(constant); | 172 .add(constant); |
| 172 } | 173 } |
| 173 } | 174 } |
| 174 | 175 |
| 175 /// Compute all the classes and typedefs that must be emitted. | 176 /// Compute all the classes and typedefs that must be emitted. |
| 176 void computeNeededDeclarations() { | 177 void computeNeededDeclarations() { |
| 177 // Compute needed typedefs. | 178 // Compute needed typedefs. |
| 178 typedefsNeededForReflection = Elements.sortedByPosition(closedWorld | 179 typedefsNeededForReflection = Elements.sortedByPosition(closedWorld |
| 179 .allTypedefs | 180 .allTypedefs |
| 180 .where(backend.mirrorsData.isAccessibleByReflection) | 181 .where(backend.mirrorsData.isTypedefAccessibleByReflection) |
| 181 .toList()); | 182 .toList()); |
| 182 | 183 |
| 183 // Compute needed classes. | 184 // Compute needed classes. |
| 184 Set<ClassElement> instantiatedClasses = compiler | 185 Set<ClassElement> instantiatedClasses = compiler |
| 185 // TODO(johnniwinther): This should be accessed from a codegen closed | 186 // TODO(johnniwinther): This should be accessed from a codegen closed |
| 186 // world. | 187 // world. |
| 187 .codegenWorldBuilder | 188 .codegenWorldBuilder |
| 188 .directlyInstantiatedClasses | 189 .directlyInstantiatedClasses |
| 189 .where(computeClassFilter()) | 190 .where(computeClassFilter()) |
| 190 .toSet(); | 191 .toSet(); |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 263 outputClassLists | 264 outputClassLists |
| 264 .putIfAbsent( | 265 .putIfAbsent( |
| 265 compiler.deferredLoadTask.outputUnitForElement(element), | 266 compiler.deferredLoadTask.outputUnitForElement(element), |
| 266 () => new List<ClassElement>()) | 267 () => new List<ClassElement>()) |
| 267 .add(element); | 268 .add(element); |
| 268 } | 269 } |
| 269 } | 270 } |
| 270 } | 271 } |
| 271 | 272 |
| 272 void computeNeededStatics() { | 273 void computeNeededStatics() { |
| 273 bool isStaticFunction(Element element) => | 274 bool isStaticFunction(MemberElement element) => |
| 274 !element.isInstanceMember && !element.isField; | 275 !element.isInstanceMember && !element.isField; |
| 275 | 276 |
| 276 Iterable<Element> elements = | 277 Iterable<MemberElement> elements = |
| 277 backend.generatedCode.keys.where(isStaticFunction); | 278 backend.generatedCode.keys.where(isStaticFunction); |
| 278 | 279 |
| 279 for (Element element in Elements.sortedByPosition(elements)) { | 280 for (Element element in Elements.sortedByPosition(elements)) { |
| 280 List<Element> list = outputStaticLists.putIfAbsent( | 281 List<Element> list = outputStaticLists.putIfAbsent( |
| 281 compiler.deferredLoadTask.outputUnitForElement(element), | 282 compiler.deferredLoadTask.outputUnitForElement(element), |
| 282 () => new List<Element>()); | 283 () => new List<Element>()); |
| 283 list.add(element); | 284 list.add(element); |
| 284 } | 285 } |
| 285 } | 286 } |
| 286 | 287 |
| 287 void computeNeededStaticNonFinalFields() { | 288 void computeNeededStaticNonFinalFields() { |
| 288 addToOutputUnit(Element element) { | 289 addToOutputUnit(Element element) { |
| 289 List<VariableElement> list = outputStaticNonFinalFieldLists.putIfAbsent( | 290 List<VariableElement> list = outputStaticNonFinalFieldLists.putIfAbsent( |
| 290 compiler.deferredLoadTask.outputUnitForElement(element), | 291 compiler.deferredLoadTask.outputUnitForElement(element), |
| 291 () => new List<VariableElement>()); | 292 () => new List<VariableElement>()); |
| 292 list.add(element); | 293 list.add(element); |
| 293 } | 294 } |
| 294 | 295 |
| 295 Iterable<Element> fields = compiler | 296 Iterable<FieldElement> fields = compiler |
| 296 // TODO(johnniwinther): This should be accessed from a codegen closed | 297 // TODO(johnniwinther): This should be accessed from a codegen closed |
| 297 // world. | 298 // world. |
| 298 .codegenWorldBuilder | 299 .codegenWorldBuilder |
| 299 .allReferencedStaticFields | 300 .allReferencedStaticFields |
| 300 .where((FieldElement field) { | 301 .where((FieldElement field) { |
| 301 if (!field.isConst) { | 302 if (!field.isConst) { |
| 302 return field.isField && | 303 return field.isField && |
| 303 !field.isInstanceMember && | 304 !field.isInstanceMember && |
| 304 !field.isFinal && | 305 !field.isFinal && |
| 305 field.constant != null; | 306 field.constant != null; |
| 306 } else { | 307 } else { |
| 307 // We also need to emit static const fields if they are available for | 308 // We also need to emit static const fields if they are available for |
| 308 // reflection. | 309 // reflection. |
| 309 return backend.mirrorsData.isAccessibleByReflection(field); | 310 return backend.mirrorsData.isMemberAccessibleByReflection(field); |
| 310 } | 311 } |
| 311 }); | 312 }); |
| 312 | 313 |
| 313 Elements.sortedByPosition(fields).forEach(addToOutputUnit); | 314 Elements.sortedByPosition(fields).forEach(addToOutputUnit); |
| 314 } | 315 } |
| 315 | 316 |
| 316 void computeNeededLibraries() { | 317 void computeNeededLibraries() { |
| 317 void addSurroundingLibraryToSet(Element element) { | 318 void addSurroundingLibraryToSet(Element element) { |
| 318 OutputUnit unit = compiler.deferredLoadTask.outputUnitForElement(element); | 319 OutputUnit unit = compiler.deferredLoadTask.outputUnitForElement(element); |
| 319 LibraryElement library = element.library; | 320 LibraryElement library = element.library; |
| 320 outputLibraryLists | 321 outputLibraryLists |
| 321 .putIfAbsent(unit, () => new Set<LibraryElement>()) | 322 .putIfAbsent(unit, () => new Set<LibraryElement>()) |
| 322 .add(library); | 323 .add(library); |
| 323 } | 324 } |
| 324 | 325 |
| 325 backend.generatedCode.keys.forEach(addSurroundingLibraryToSet); | 326 backend.generatedCode.keys.forEach(addSurroundingLibraryToSet); |
| 326 neededClasses.forEach(addSurroundingLibraryToSet); | 327 neededClasses.forEach(addSurroundingLibraryToSet); |
| 327 } | 328 } |
| 328 | 329 |
| 329 void collect() { | 330 void collect() { |
| 330 computeNeededDeclarations(); | 331 computeNeededDeclarations(); |
| 331 computeNeededConstants(); | 332 computeNeededConstants(); |
| 332 computeNeededStatics(); | 333 computeNeededStatics(); |
| 333 computeNeededStaticNonFinalFields(); | 334 computeNeededStaticNonFinalFields(); |
| 334 computeNeededLibraries(); | 335 computeNeededLibraries(); |
| 335 } | 336 } |
| 336 } | 337 } |
| OLD | NEW |