| 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 js_backend; | 5 part of js_backend; |
| 6 | 6 |
| 7 /** | 7 /** |
| 8 * A function element that represents a closure call. The signature is copied | 8 * A function element that represents a closure call. The signature is copied |
| 9 * from the given element. | 9 * from the given element. |
| 10 */ | 10 */ |
| (...skipping 1539 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1550 String mixinName = namer.getName(computeMixinClass(classElement)); | 1550 String mixinName = namer.getName(computeMixinClass(classElement)); |
| 1551 superName = '$superName+$mixinName'; | 1551 superName = '$superName+$mixinName'; |
| 1552 needsMixinSupport = true; | 1552 needsMixinSupport = true; |
| 1553 } | 1553 } |
| 1554 | 1554 |
| 1555 ClassBuilder builder = new ClassBuilder(); | 1555 ClassBuilder builder = new ClassBuilder(); |
| 1556 emitClassConstructor(classElement, builder); | 1556 emitClassConstructor(classElement, builder); |
| 1557 emitSuper(superName, builder); | 1557 emitSuper(superName, builder); |
| 1558 emitRuntimeName(runtimeName, builder); | 1558 emitRuntimeName(runtimeName, builder); |
| 1559 emitClassFields(classElement, builder, superName); | 1559 emitClassFields(classElement, builder, superName); |
| 1560 var metadata = buildMetadataFunction(classElement); |
| 1561 if (metadata != null) { |
| 1562 builder.addProperty("@", metadata); |
| 1563 } |
| 1560 emitClassGettersSetters(classElement, builder); | 1564 emitClassGettersSetters(classElement, builder); |
| 1561 if (!classElement.isMixinApplication) { | 1565 if (!classElement.isMixinApplication) { |
| 1562 emitInstanceMembers(classElement, builder); | 1566 emitInstanceMembers(classElement, builder); |
| 1563 } | 1567 } |
| 1564 emitIsTests(classElement, builder); | 1568 emitIsTests(classElement, builder); |
| 1565 | 1569 |
| 1566 // TODO(ahe): This method (generateClass) should return a jsAst.Expression. | 1570 // TODO(ahe): This method (generateClass) should return a jsAst.Expression. |
| 1567 if (!buffer.isEmpty) { | 1571 if (!buffer.isEmpty) { |
| 1568 buffer.write(',$n$n'); | 1572 buffer.write(',$n$n'); |
| 1569 } | 1573 } |
| (...skipping 1355 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2925 buffer.write(jsAst.prettyPrint(decl, compiler).getText()); | 2929 buffer.write(jsAst.prettyPrint(decl, compiler).getText()); |
| 2926 if (compiler.enableMinification) buffer.write('\n'); | 2930 if (compiler.enableMinification) buffer.write('\n'); |
| 2927 } | 2931 } |
| 2928 | 2932 |
| 2929 /// The metadata function returns the metadata associated with | 2933 /// The metadata function returns the metadata associated with |
| 2930 /// [element] in generated code. The metadata needs to be wrapped | 2934 /// [element] in generated code. The metadata needs to be wrapped |
| 2931 /// in a function as it refers to constants that may not have been | 2935 /// in a function as it refers to constants that may not have been |
| 2932 /// constructed yet. For example, a class is allowed to be | 2936 /// constructed yet. For example, a class is allowed to be |
| 2933 /// annotated with itself. The metadata function is used by | 2937 /// annotated with itself. The metadata function is used by |
| 2934 /// mirrors_patch to implement DeclarationMirror.metadata. | 2938 /// mirrors_patch to implement DeclarationMirror.metadata. |
| 2935 jsAst.Expression buildMetadataFunction(Element element) { | 2939 jsAst.Fun buildMetadataFunction(Element element) { |
| 2936 if (compiler.mirrorSystemClass == null) { | 2940 if (compiler.mirrorSystemClass == null) return null; |
| 2937 // Since the string is not quoted, this just becomes an empty | |
| 2938 // node. Since the result is added to a list, this implicitly | |
| 2939 // makes the value undefined. | |
| 2940 return new jsAst.LiteralString(''); | |
| 2941 } | |
| 2942 var metadata = []; | 2941 var metadata = []; |
| 2943 Link link = element.metadata; | 2942 Link link = element.metadata; |
| 2944 // TODO(ahe): Why is metadata sometimes null? | 2943 // TODO(ahe): Why is metadata sometimes null? |
| 2945 if (link != null) { | 2944 if (link != null) { |
| 2946 for (; !link.isEmpty; link = link.tail) { | 2945 for (; !link.isEmpty; link = link.tail) { |
| 2947 metadata.add(constantReference(link.head.value)); | 2946 metadata.add(constantReference(link.head.value)); |
| 2948 } | 2947 } |
| 2949 } | 2948 } |
| 2949 if (metadata.isEmpty) return null; |
| 2950 return js.fun([], [js.return_(new jsAst.ArrayInitializer.from(metadata))]); | 2950 return js.fun([], [js.return_(new jsAst.ArrayInitializer.from(metadata))]); |
| 2951 } | 2951 } |
| 2952 | 2952 |
| 2953 String assembleProgram() { | 2953 String assembleProgram() { |
| 2954 measure(() { | 2954 measure(() { |
| 2955 // Compute the required type checks to know which classes need a | 2955 // Compute the required type checks to know which classes need a |
| 2956 // 'is$' method. | 2956 // 'is$' method. |
| 2957 computeRequiredTypeChecks(); | 2957 computeRequiredTypeChecks(); |
| 2958 | 2958 |
| 2959 computeNeededClasses(); | 2959 computeNeededClasses(); |
| (...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3044 var buffer = buffers[0]; | 3044 var buffer = buffers[0]; |
| 3045 var uri = library.canonicalUri; | 3045 var uri = library.canonicalUri; |
| 3046 if (uri.scheme == 'file' && compiler.sourceMapUri != null) { | 3046 if (uri.scheme == 'file' && compiler.sourceMapUri != null) { |
| 3047 // TODO(ahe): It is a hack to use compiler.sourceMapUri | 3047 // TODO(ahe): It is a hack to use compiler.sourceMapUri |
| 3048 // here. It should be relative to the main JavaScript | 3048 // here. It should be relative to the main JavaScript |
| 3049 // output file. | 3049 // output file. |
| 3050 uri = relativize( | 3050 uri = relativize( |
| 3051 compiler.sourceMapUri, library.canonicalUri, false); | 3051 compiler.sourceMapUri, library.canonicalUri, false); |
| 3052 } | 3052 } |
| 3053 if (buffer != null) { | 3053 if (buffer != null) { |
| 3054 var metadata = buildMetadataFunction(library); |
| 3054 mainBuffer | 3055 mainBuffer |
| 3055 ..write('["${library.getLibraryOrScriptName()}",$_') | 3056 ..write('["${library.getLibraryOrScriptName()}",$_') |
| 3056 ..write('"${uri}",$_') | 3057 ..write('"${uri}",$_') |
| 3057 ..write( | 3058 ..write(metadata == null |
| 3058 jsAst.prettyPrint(buildMetadataFunction(library), compiler)) | 3059 ? "" : jsAst.prettyPrint(metadata, compiler)) |
| 3059 ..write(',$_') | 3060 ..write(',$_') |
| 3060 ..write('{$n') | 3061 ..write('{$n') |
| 3061 ..addBuffer(buffer) | 3062 ..addBuffer(buffer) |
| 3062 ..write('}],$n'); | 3063 ..write('}],$n'); |
| 3063 } | 3064 } |
| 3064 buffer = buffers[1]; | 3065 buffer = buffers[1]; |
| 3065 if (buffer != null) { | 3066 if (buffer != null) { |
| 3066 deferredBuffer | 3067 deferredBuffer |
| 3067 ..write('["${library.getLibraryOrScriptName()}",$_') | 3068 ..write('["${library.getLibraryOrScriptName()}",$_') |
| 3068 ..write('"${uri}",$_') | 3069 ..write('"${uri}",$_') |
| (...skipping 203 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3272 | 3273 |
| 3273 const String HOOKS_API_USAGE = """ | 3274 const String HOOKS_API_USAGE = """ |
| 3274 // The code supports the following hooks: | 3275 // The code supports the following hooks: |
| 3275 // dartPrint(message) - if this function is defined it is called | 3276 // dartPrint(message) - if this function is defined it is called |
| 3276 // instead of the Dart [print] method. | 3277 // instead of the Dart [print] method. |
| 3277 // dartMainRunner(main) - if this function is defined, the Dart [main] | 3278 // dartMainRunner(main) - if this function is defined, the Dart [main] |
| 3278 // method will not be invoked directly. | 3279 // method will not be invoked directly. |
| 3279 // Instead, a closure that will invoke [main] is | 3280 // Instead, a closure that will invoke [main] is |
| 3280 // passed to [dartMainRunner]. | 3281 // passed to [dartMainRunner]. |
| 3281 """; | 3282 """; |
| OLD | NEW |