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 |