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 CLASS_DESCRIPTOR_PROPERTY property on the descriptor. | 334 * from the null-string 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["${namer.classDescriptorProperty}"], ' | 339 js('var classData = desc[""], supr, name = cls, fields = classData'), |
340 'supr, name = cls, fields = classData'), | |
341 optional( | 340 optional( |
342 backend.hasRetainedMetadata, | 341 backend.hasRetainedMetadata, |
343 js.if_('typeof classData == "object" && ' | 342 js.if_('typeof classData == "object" && ' |
344 'classData instanceof Array', | 343 'classData instanceof Array', |
345 [js('classData = fields = classData[0]')])), | 344 [js('classData = fields = classData[0]')])), |
346 | 345 |
347 js.if_('typeof classData == "string"', [ | 346 js.if_('typeof classData == "string"', [ |
348 js('var split = classData.split("/")'), | 347 js('var split = classData.split("/")'), |
349 js.if_('split.length == 2', [ | 348 js.if_('split.length == 2', [ |
350 js('name = split[0]'), | 349 js('name = split[0]'), |
(...skipping 471 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
822 } | 821 } |
823 | 822 |
824 void emitStaticFunctions() { | 823 void emitStaticFunctions() { |
825 bool isStaticFunction(Element element) => | 824 bool isStaticFunction(Element element) => |
826 !element.isInstanceMember() && !element.isField(); | 825 !element.isInstanceMember() && !element.isField(); |
827 | 826 |
828 Iterable<Element> elements = | 827 Iterable<Element> elements = |
829 backend.generatedCode.keys.where(isStaticFunction); | 828 backend.generatedCode.keys.where(isStaticFunction); |
830 | 829 |
831 for (Element element in Elements.sortedByPosition(elements)) { | 830 for (Element element in Elements.sortedByPosition(elements)) { |
832 ClassBuilder builder = new ClassBuilder(namer); | 831 ClassBuilder builder = new ClassBuilder(); |
833 containerBuilder.addMember(element, builder); | 832 containerBuilder.addMember(element, builder); |
834 getElementDecriptor(element).properties.addAll(builder.properties); | 833 getElementDecriptor(element).properties.addAll(builder.properties); |
835 } | 834 } |
836 } | 835 } |
837 | 836 |
838 void emitStaticNonFinalFieldInitializations(CodeBuffer buffer) { | 837 void emitStaticNonFinalFieldInitializations(CodeBuffer buffer) { |
839 ConstantHandler handler = compiler.constantHandler; | 838 ConstantHandler handler = compiler.constantHandler; |
840 Iterable<VariableElement> staticNonFinalFields = | 839 Iterable<VariableElement> staticNonFinalFields = |
841 handler.getStaticNonFinalFieldsForEmission(); | 840 handler.getStaticNonFinalFieldsForEmission(); |
842 for (Element element in Elements.sortedByPosition(staticNonFinalFields)) { | 841 for (Element element in Elements.sortedByPosition(staticNonFinalFields)) { |
(...skipping 501 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1344 classesCollector = r"$$"; | 1343 classesCollector = r"$$"; |
1345 if (compiler.enableMinification) { | 1344 if (compiler.enableMinification) { |
1346 mainBuffer.write(';'); | 1345 mainBuffer.write(';'); |
1347 } | 1346 } |
1348 | 1347 |
1349 for (Element element in elementDescriptors.keys) { | 1348 for (Element element in elementDescriptors.keys) { |
1350 // TODO(ahe): Should iterate over all libraries. Otherwise, we will | 1349 // TODO(ahe): Should iterate over all libraries. Otherwise, we will |
1351 // not see libraries that only have fields. | 1350 // not see libraries that only have fields. |
1352 if (element.isLibrary()) { | 1351 if (element.isLibrary()) { |
1353 LibraryElement library = element; | 1352 LibraryElement library = element; |
1354 ClassBuilder builder = new ClassBuilder(namer); | 1353 ClassBuilder builder = new ClassBuilder(); |
1355 if (classEmitter.emitFields( | 1354 if (classEmitter.emitFields( |
1356 library, builder, null, emitStatics: true)) { | 1355 library, builder, null, emitStatics: true)) { |
1357 OutputUnit mainUnit = compiler.deferredLoadTask.mainOutputUnit; | 1356 OutputUnit mainUnit = compiler.deferredLoadTask.mainOutputUnit; |
1358 getElementDescriptorForOutputUnit(library, mainUnit) | 1357 getElementDescriptorForOutputUnit(library, mainUnit) |
1359 .properties.addAll(builder.toObjectInitializer().properties); | 1358 .properties.addAll(builder.toObjectInitializer().properties); |
1360 } | 1359 } |
1361 } | 1360 } |
1362 } | 1361 } |
1363 | 1362 |
1364 if (!mangledFieldNames.isEmpty) { | 1363 if (!mangledFieldNames.isEmpty) { |
(...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1542 }); | 1541 }); |
1543 return compiler.assembledCode; | 1542 return compiler.assembledCode; |
1544 } | 1543 } |
1545 | 1544 |
1546 ClassBuilder getElementDescriptorForOutputUnit(Element element, | 1545 ClassBuilder getElementDescriptorForOutputUnit(Element element, |
1547 OutputUnit outputUnit) { | 1546 OutputUnit outputUnit) { |
1548 Map<OutputUnit, ClassBuilder> descriptors = | 1547 Map<OutputUnit, ClassBuilder> descriptors = |
1549 elementDescriptors.putIfAbsent( | 1548 elementDescriptors.putIfAbsent( |
1550 element, () => new Map<OutputUnit, ClassBuilder>()); | 1549 element, () => new Map<OutputUnit, ClassBuilder>()); |
1551 return descriptors.putIfAbsent(outputUnit, | 1550 return descriptors.putIfAbsent(outputUnit, |
1552 () => new ClassBuilder(namer)); | 1551 () => new ClassBuilder()); |
1553 } | 1552 } |
1554 | 1553 |
1555 ClassBuilder getElementDecriptor(Element element) { | 1554 ClassBuilder getElementDecriptor(Element element) { |
1556 Element owner = element.getLibrary(); | 1555 Element owner = element.getLibrary(); |
1557 if (!element.isTopLevel() && !element.isNative()) { | 1556 if (!element.isTopLevel() && !element.isNative()) { |
1558 // For static (not top level) elements, record their code in a buffer | 1557 // For static (not top level) elements, record their code in a buffer |
1559 // specific to the class. For now, not supported for native classes and | 1558 // specific to the class. For now, not supported for native classes and |
1560 // native elements. | 1559 // native elements. |
1561 ClassElement cls = | 1560 ClassElement cls = |
1562 element.getEnclosingClassOrCompilationUnit().declaration; | 1561 element.getEnclosingClassOrCompilationUnit().declaration; |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1645 String sourceMap = buildSourceMap(mainBuffer, compiledFile); | 1644 String sourceMap = buildSourceMap(mainBuffer, compiledFile); |
1646 compiler.outputProvider(name, 'js.map') | 1645 compiler.outputProvider(name, 'js.map') |
1647 ..add(sourceMap) | 1646 ..add(sourceMap) |
1648 ..close(); | 1647 ..close(); |
1649 } | 1648 } |
1650 | 1649 |
1651 void registerReadTypeVariable(TypeVariableElement element) { | 1650 void registerReadTypeVariable(TypeVariableElement element) { |
1652 readTypeVariables.add(element); | 1651 readTypeVariables.add(element); |
1653 } | 1652 } |
1654 } | 1653 } |
OLD | NEW |