| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, 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; | 5 part of dart2js.js_emitter; |
| 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 313 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 324 js('var constructorsList = []')]), | 324 js('var constructorsList = []')]), |
| 325 js.forIn('cls', 'collectedClasses', [ | 325 js.forIn('cls', 'collectedClasses', [ |
| 326 js.if_('hasOwnProperty.call(collectedClasses, cls)', [ | 326 js.if_('hasOwnProperty.call(collectedClasses, cls)', [ |
| 327 js('var desc = collectedClasses[cls]'), | 327 js('var desc = collectedClasses[cls]'), |
| 328 js.if_('desc instanceof Array', js('desc = desc[1]')), | 328 js.if_('desc instanceof Array', js('desc = desc[1]')), |
| 329 | 329 |
| 330 /* The 'fields' are either a constructor function or a | 330 /* The 'fields' are either a constructor function or a |
| 331 * string encoding fields, constructor and superclass. Get | 331 * string encoding fields, constructor and superclass. Get |
| 332 * the superclass and the fields in the format | 332 * the superclass and the fields in the format |
| 333 * '[name/]Super;field1,field2' | 333 * '[name/]Super;field1,field2' |
| 334 * from the null-string property on the descriptor. | 334 * from the CLASS_DESCRIPTOR_PROPERTY property on the descriptor. |
| 335 * The 'name/' is optional and contains the name that should be used | 335 * The 'name/' is optional and contains the name that should be used |
| 336 * when printing the runtime type string. It is used, for example, to | 336 * when printing the runtime type string. It is used, for example, to |
| 337 * print the runtime type JSInt as 'int'. | 337 * print the runtime type JSInt as 'int'. |
| 338 */ | 338 */ |
| 339 js('var classData = desc[""], supr, name = cls, fields = classData'), | 339 js('var classData = desc["${namer.classDescriptorProperty}"], ' |
| 340 'supr, name = cls, fields = classData'), |
| 340 optional( | 341 optional( |
| 341 backend.hasRetainedMetadata, | 342 backend.hasRetainedMetadata, |
| 342 js.if_('typeof classData == "object" && ' | 343 js.if_('typeof classData == "object" && ' |
| 343 'classData instanceof Array', | 344 'classData instanceof Array', |
| 344 [js('classData = fields = classData[0]')])), | 345 [js('classData = fields = classData[0]')])), |
| 345 | 346 |
| 346 js.if_('typeof classData == "string"', [ | 347 js.if_('typeof classData == "string"', [ |
| 347 js('var split = classData.split("/")'), | 348 js('var split = classData.split("/")'), |
| 348 js.if_('split.length == 2', [ | 349 js.if_('split.length == 2', [ |
| 349 js('name = split[0]'), | 350 js('name = split[0]'), |
| (...skipping 471 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 821 } | 822 } |
| 822 | 823 |
| 823 void emitStaticFunctions() { | 824 void emitStaticFunctions() { |
| 824 bool isStaticFunction(Element element) => | 825 bool isStaticFunction(Element element) => |
| 825 !element.isInstanceMember() && !element.isField(); | 826 !element.isInstanceMember() && !element.isField(); |
| 826 | 827 |
| 827 Iterable<Element> elements = | 828 Iterable<Element> elements = |
| 828 backend.generatedCode.keys.where(isStaticFunction); | 829 backend.generatedCode.keys.where(isStaticFunction); |
| 829 | 830 |
| 830 for (Element element in Elements.sortedByPosition(elements)) { | 831 for (Element element in Elements.sortedByPosition(elements)) { |
| 831 ClassBuilder builder = new ClassBuilder(); | 832 ClassBuilder builder = new ClassBuilder(namer); |
| 832 containerBuilder.addMember(element, builder); | 833 containerBuilder.addMember(element, builder); |
| 833 getElementDecriptor(element).properties.addAll(builder.properties); | 834 getElementDecriptor(element).properties.addAll(builder.properties); |
| 834 } | 835 } |
| 835 } | 836 } |
| 836 | 837 |
| 837 void emitStaticNonFinalFieldInitializations(CodeBuffer buffer) { | 838 void emitStaticNonFinalFieldInitializations(CodeBuffer buffer) { |
| 838 ConstantHandler handler = compiler.constantHandler; | 839 ConstantHandler handler = compiler.constantHandler; |
| 839 Iterable<VariableElement> staticNonFinalFields = | 840 Iterable<VariableElement> staticNonFinalFields = |
| 840 handler.getStaticNonFinalFieldsForEmission(); | 841 handler.getStaticNonFinalFieldsForEmission(); |
| 841 for (Element element in Elements.sortedByPosition(staticNonFinalFields)) { | 842 for (Element element in Elements.sortedByPosition(staticNonFinalFields)) { |
| (...skipping 380 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1222 // here. It should be relative to the main JavaScript | 1223 // here. It should be relative to the main JavaScript |
| 1223 // output file. | 1224 // output file. |
| 1224 uri = relativize( | 1225 uri = relativize( |
| 1225 compiler.sourceMapUri, library.canonicalUri, false); | 1226 compiler.sourceMapUri, library.canonicalUri, false); |
| 1226 } | 1227 } |
| 1227 Map<OutputUnit, ClassBuilder> descriptors = | 1228 Map<OutputUnit, ClassBuilder> descriptors = |
| 1228 elementDescriptors[library]; | 1229 elementDescriptors[library]; |
| 1229 | 1230 |
| 1230 for (OutputUnit outputUnit in compiler.deferredLoadTask.allOutputUnits) { | 1231 for (OutputUnit outputUnit in compiler.deferredLoadTask.allOutputUnits) { |
| 1231 ClassBuilder descriptor = | 1232 ClassBuilder descriptor = |
| 1232 descriptors.putIfAbsent(outputUnit, () | 1233 descriptors.putIfAbsent(outputUnit, () => new ClassBuilder(namer)); |
| 1233 => new ClassBuilder()); | |
| 1234 if (descriptor.properties.isEmpty) continue; | 1234 if (descriptor.properties.isEmpty) continue; |
| 1235 bool isDeferred = | 1235 bool isDeferred = |
| 1236 outputUnit != compiler.deferredLoadTask.mainOutputUnit; | 1236 outputUnit != compiler.deferredLoadTask.mainOutputUnit; |
| 1237 jsAst.Fun metadata = metadataEmitter.buildMetadataFunction(library); | 1237 jsAst.Fun metadata = metadataEmitter.buildMetadataFunction(library); |
| 1238 | 1238 |
| 1239 jsAst.ObjectInitializer initializers = | 1239 jsAst.ObjectInitializer initializers = |
| 1240 descriptor.toObjectInitializer(); | 1240 descriptor.toObjectInitializer(); |
| 1241 CodeBuffer outputBuffer = | 1241 CodeBuffer outputBuffer = |
| 1242 outputBuffers.putIfAbsent(outputUnit, () => new CodeBuffer()); | 1242 outputBuffers.putIfAbsent(outputUnit, () => new CodeBuffer()); |
| 1243 int sizeBefore = outputBuffer.length; | 1243 int sizeBefore = outputBuffer.length; |
| (...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1341 classesCollector = r"$$"; | 1341 classesCollector = r"$$"; |
| 1342 if (compiler.enableMinification) { | 1342 if (compiler.enableMinification) { |
| 1343 mainBuffer.write(';'); | 1343 mainBuffer.write(';'); |
| 1344 } | 1344 } |
| 1345 | 1345 |
| 1346 for (Element element in elementDescriptors.keys) { | 1346 for (Element element in elementDescriptors.keys) { |
| 1347 // TODO(ahe): Should iterate over all libraries. Otherwise, we will | 1347 // TODO(ahe): Should iterate over all libraries. Otherwise, we will |
| 1348 // not see libraries that only have fields. | 1348 // not see libraries that only have fields. |
| 1349 if (element.isLibrary()) { | 1349 if (element.isLibrary()) { |
| 1350 LibraryElement library = element; | 1350 LibraryElement library = element; |
| 1351 ClassBuilder builder = new ClassBuilder(); | 1351 ClassBuilder builder = new ClassBuilder(namer); |
| 1352 if (classEmitter.emitFields( | 1352 if (classEmitter.emitFields( |
| 1353 library, builder, null, emitStatics: true)) { | 1353 library, builder, null, emitStatics: true)) { |
| 1354 OutputUnit mainUnit = compiler.deferredLoadTask.mainOutputUnit; | 1354 OutputUnit mainUnit = compiler.deferredLoadTask.mainOutputUnit; |
| 1355 getElementDescriptorForOutputUnit(library, mainUnit) | 1355 getElementDescriptorForOutputUnit(library, mainUnit) |
| 1356 .properties.addAll(builder.toObjectInitializer().properties); | 1356 .properties.addAll(builder.toObjectInitializer().properties); |
| 1357 } | 1357 } |
| 1358 } | 1358 } |
| 1359 } | 1359 } |
| 1360 | 1360 |
| 1361 if (!mangledFieldNames.isEmpty) { | 1361 if (!mangledFieldNames.isEmpty) { |
| (...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1539 }); | 1539 }); |
| 1540 return compiler.assembledCode; | 1540 return compiler.assembledCode; |
| 1541 } | 1541 } |
| 1542 | 1542 |
| 1543 ClassBuilder getElementDescriptorForOutputUnit(Element element, | 1543 ClassBuilder getElementDescriptorForOutputUnit(Element element, |
| 1544 OutputUnit outputUnit) { | 1544 OutputUnit outputUnit) { |
| 1545 Map<OutputUnit, ClassBuilder> descriptors = | 1545 Map<OutputUnit, ClassBuilder> descriptors = |
| 1546 elementDescriptors.putIfAbsent( | 1546 elementDescriptors.putIfAbsent( |
| 1547 element, () => new Map<OutputUnit, ClassBuilder>()); | 1547 element, () => new Map<OutputUnit, ClassBuilder>()); |
| 1548 return descriptors.putIfAbsent(outputUnit, | 1548 return descriptors.putIfAbsent(outputUnit, |
| 1549 () => new ClassBuilder()); | 1549 () => new ClassBuilder(namer)); |
| 1550 } | 1550 } |
| 1551 | 1551 |
| 1552 ClassBuilder getElementDecriptor(Element element) { | 1552 ClassBuilder getElementDecriptor(Element element) { |
| 1553 Element owner = element.getLibrary(); | 1553 Element owner = element.getLibrary(); |
| 1554 if (!element.isTopLevel() && !element.isNative()) { | 1554 if (!element.isTopLevel() && !element.isNative()) { |
| 1555 // For static (not top level) elements, record their code in a buffer | 1555 // For static (not top level) elements, record their code in a buffer |
| 1556 // specific to the class. For now, not supported for native classes and | 1556 // specific to the class. For now, not supported for native classes and |
| 1557 // native elements. | 1557 // native elements. |
| 1558 ClassElement cls = | 1558 ClassElement cls = |
| 1559 element.getEnclosingClassOrCompilationUnit().declaration; | 1559 element.getEnclosingClassOrCompilationUnit().declaration; |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1642 String sourceMap = buildSourceMap(mainBuffer, compiledFile); | 1642 String sourceMap = buildSourceMap(mainBuffer, compiledFile); |
| 1643 compiler.outputProvider(name, 'js.map') | 1643 compiler.outputProvider(name, 'js.map') |
| 1644 ..add(sourceMap) | 1644 ..add(sourceMap) |
| 1645 ..close(); | 1645 ..close(); |
| 1646 } | 1646 } |
| 1647 | 1647 |
| 1648 void registerReadTypeVariable(TypeVariableElement element) { | 1648 void registerReadTypeVariable(TypeVariableElement element) { |
| 1649 readTypeVariables.add(element); | 1649 readTypeVariables.add(element); |
| 1650 } | 1650 } |
| 1651 } | 1651 } |
| OLD | NEW |