Chromium Code Reviews| 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 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 130 * typedefs and implicitly through type annotations in checked mode. | 130 * typedefs and implicitly through type annotations in checked mode. |
| 131 */ | 131 */ |
| 132 Set<FunctionType> checkedFunctionTypes; | 132 Set<FunctionType> checkedFunctionTypes; |
| 133 | 133 |
| 134 Map<ClassElement, Set<FunctionType>> checkedGenericFunctionTypes = | 134 Map<ClassElement, Set<FunctionType>> checkedGenericFunctionTypes = |
| 135 new Map<ClassElement, Set<FunctionType>>(); | 135 new Map<ClassElement, Set<FunctionType>>(); |
| 136 | 136 |
| 137 Set<FunctionType> checkedNonGenericFunctionTypes = | 137 Set<FunctionType> checkedNonGenericFunctionTypes = |
| 138 new Set<FunctionType>(); | 138 new Set<FunctionType>(); |
| 139 | 139 |
| 140 /** | |
| 141 * For classes and libraries, record code for static/top-level members. | |
| 142 * Later, this code is emitted when the class or library is emitted. | |
|
ngeoffray
2013/07/17 07:35:57
Would there be a way to just produce them when we
ahe
2013/07/17 07:55:27
Yes. I hope to clean this up.
However, there are,
ngeoffray
2013/07/17 08:08:42
I agree it's not trivial.
| |
| 143 * See [bufferForElement]. | |
| 144 */ | |
| 145 final Map<Element, List<CodeBuffer>> elementBuffers = | |
| 146 new Map<Element, List<CodeBuffer>>(); | |
| 147 | |
| 140 void registerDynamicFunctionTypeCheck(FunctionType functionType) { | 148 void registerDynamicFunctionTypeCheck(FunctionType functionType) { |
| 141 ClassElement classElement = Types.getClassContext(functionType); | 149 ClassElement classElement = Types.getClassContext(functionType); |
| 142 if (classElement != null) { | 150 if (classElement != null) { |
| 143 checkedGenericFunctionTypes.putIfAbsent(classElement, | 151 checkedGenericFunctionTypes.putIfAbsent(classElement, |
| 144 () => new Set<FunctionType>()).add(functionType); | 152 () => new Set<FunctionType>()).add(functionType); |
| 145 } else { | 153 } else { |
| 146 checkedNonGenericFunctionTypes.add(functionType); | 154 checkedNonGenericFunctionTypes.add(functionType); |
| 147 } | 155 } |
| 148 } | 156 } |
| 149 | 157 |
| (...skipping 1627 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1777 var metadata = buildMetadataFunction(classElement); | 1785 var metadata = buildMetadataFunction(classElement); |
| 1778 if (metadata != null) { | 1786 if (metadata != null) { |
| 1779 builder.addProperty("@", metadata); | 1787 builder.addProperty("@", metadata); |
| 1780 } | 1788 } |
| 1781 emitClassGettersSetters(classElement, builder); | 1789 emitClassGettersSetters(classElement, builder); |
| 1782 if (!classElement.isMixinApplication) { | 1790 if (!classElement.isMixinApplication) { |
| 1783 emitInstanceMembers(classElement, builder); | 1791 emitInstanceMembers(classElement, builder); |
| 1784 } | 1792 } |
| 1785 emitIsTests(classElement, builder); | 1793 emitIsTests(classElement, builder); |
| 1786 | 1794 |
| 1795 List<CodeBuffer> classBuffers = elementBuffers[classElement]; | |
| 1796 CodeBuffer statics = new CodeBuffer(); | |
| 1797 bool hasStatics = false; | |
| 1798 if (classBuffers != null) { | |
| 1799 statics.write('{$n'); | |
| 1800 elementBuffers.remove(classElement); | |
| 1801 for (CodeBuffer classBuffer in classBuffers) { | |
| 1802 // TODO(ahe): What about deferred? | |
| 1803 if (classBuffer != null) { | |
| 1804 hasStatics = true; | |
| 1805 statics.addBuffer(classBuffer); | |
| 1806 } | |
| 1807 } | |
| 1808 statics.write('}$n'); | |
| 1809 } | |
| 1810 if (hasStatics) { | |
| 1811 builder.addProperty('static', new jsAst.Blob(statics)); | |
| 1812 } | |
| 1813 | |
| 1787 // TODO(ahe): This method (generateClass) should return a jsAst.Expression. | 1814 // TODO(ahe): This method (generateClass) should return a jsAst.Expression. |
| 1788 if (!buffer.isEmpty) { | 1815 if (!buffer.isEmpty) { |
| 1789 buffer.write(',$n$n'); | 1816 buffer.write(',$n$n'); |
| 1790 } | 1817 } |
| 1791 buffer.write('$className:$_'); | 1818 buffer.write('$className:$_'); |
| 1792 buffer.write(jsAst.prettyPrint(builder.toObjectInitializer(), compiler)); | 1819 buffer.write(jsAst.prettyPrint(builder.toObjectInitializer(), compiler)); |
| 1793 if (backend.retainName(classElement.name)) { | 1820 if (backend.retainName(classElement.name)) { |
| 1794 buffer.write(',$n$n"+${classElement.name.slowToString()}": 0'); | 1821 buffer.write(',$n$n"+${classElement.name.slowToString()}": 0'); |
| 1795 } | 1822 } |
| 1796 } | 1823 } |
| (...skipping 1585 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3382 mainBuffer.add('(function(${namer.CURRENT_ISOLATE})$_{$n'); | 3409 mainBuffer.add('(function(${namer.CURRENT_ISOLATE})$_{$n'); |
| 3383 } | 3410 } |
| 3384 | 3411 |
| 3385 mainBuffer.add('function ${namer.isolateName}()$_{}\n'); | 3412 mainBuffer.add('function ${namer.isolateName}()$_{}\n'); |
| 3386 mainBuffer.add('init()$N$n'); | 3413 mainBuffer.add('init()$N$n'); |
| 3387 // Shorten the code by using [namer.CURRENT_ISOLATE] as temporary. | 3414 // Shorten the code by using [namer.CURRENT_ISOLATE] as temporary. |
| 3388 isolateProperties = namer.CURRENT_ISOLATE; | 3415 isolateProperties = namer.CURRENT_ISOLATE; |
| 3389 mainBuffer.add( | 3416 mainBuffer.add( |
| 3390 '$isolateProperties$_=$_$isolatePropertiesName$N'); | 3417 '$isolateProperties$_=$_$isolatePropertiesName$N'); |
| 3391 | 3418 |
| 3419 emitStaticFunctions(mainBuffer); | |
| 3420 | |
| 3392 if (!regularClasses.isEmpty || | 3421 if (!regularClasses.isEmpty || |
| 3393 !deferredClasses.isEmpty || | 3422 !deferredClasses.isEmpty || |
| 3394 !nativeClasses.isEmpty || | 3423 !nativeClasses.isEmpty || |
| 3395 !compiler.codegenWorld.staticFunctionsNeedingGetter.isEmpty) { | 3424 !compiler.codegenWorld.staticFunctionsNeedingGetter.isEmpty) { |
| 3396 // Shorten the code by using "$$" as temporary. | 3425 // Shorten the code by using "$$" as temporary. |
| 3397 classesCollector = r"$$"; | 3426 classesCollector = r"$$"; |
| 3398 mainBuffer.add('var $classesCollector$_=$_{}$N$n'); | 3427 mainBuffer.add('var $classesCollector$_=$_{}$N$n'); |
| 3399 } | 3428 } |
| 3400 | 3429 |
| 3401 // As a side-effect, emitting classes will produce "bound closures" in | 3430 // As a side-effect, emitting classes will produce "bound closures" in |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3436 for (jsAst.Node node in boundClosures) { | 3465 for (jsAst.Node node in boundClosures) { |
| 3437 // TODO(ahe): Some of these can be deferred. | 3466 // TODO(ahe): Some of these can be deferred. |
| 3438 mainBuffer.add(jsAst.prettyPrint(node, compiler)); | 3467 mainBuffer.add(jsAst.prettyPrint(node, compiler)); |
| 3439 mainBuffer.add("$N$n"); | 3468 mainBuffer.add("$N$n"); |
| 3440 } | 3469 } |
| 3441 | 3470 |
| 3442 // After this assignment we will produce invalid JavaScript code if we use | 3471 // After this assignment we will produce invalid JavaScript code if we use |
| 3443 // the classesCollector variable. | 3472 // the classesCollector variable. |
| 3444 classesCollector = 'classesCollector should not be used from now on'; | 3473 classesCollector = 'classesCollector should not be used from now on'; |
| 3445 | 3474 |
| 3446 emitStaticFunctions(mainBuffer); | 3475 if (!elementBuffers.isEmpty) { |
| 3447 | |
| 3448 if (!libraryBuffers.isEmpty) { | |
| 3449 var oldClassesCollector = classesCollector; | 3476 var oldClassesCollector = classesCollector; |
| 3450 classesCollector = r"$$"; | 3477 classesCollector = r"$$"; |
| 3451 if (compiler.enableMinification) { | 3478 if (compiler.enableMinification) { |
| 3452 mainBuffer.write(';'); | 3479 mainBuffer.write(';'); |
| 3453 } | 3480 } |
| 3454 if (!mangledFieldNames.isEmpty) { | 3481 if (!mangledFieldNames.isEmpty) { |
| 3455 var keys = mangledFieldNames.keys.toList(); | 3482 var keys = mangledFieldNames.keys.toList(); |
| 3456 keys.sort(); | 3483 keys.sort(); |
| 3457 var properties = []; | 3484 var properties = []; |
| 3458 for (String key in keys) { | 3485 for (String key in keys) { |
| 3459 var value = js.string('${mangledFieldNames[key]}'); | 3486 var value = js.string('${mangledFieldNames[key]}'); |
| 3460 properties.add(new jsAst.Property(js.string(key), value)); | 3487 properties.add(new jsAst.Property(js.string(key), value)); |
| 3461 } | 3488 } |
| 3462 var map = new jsAst.ObjectInitializer(properties); | 3489 var map = new jsAst.ObjectInitializer(properties); |
| 3463 mainBuffer.write( | 3490 mainBuffer.write( |
| 3464 jsAst.prettyPrint( | 3491 jsAst.prettyPrint( |
| 3465 js('init.mangledNames = #', map).toStatement(), compiler)); | 3492 js('init.mangledNames = #', map).toStatement(), compiler)); |
| 3466 if (compiler.enableMinification) { | 3493 if (compiler.enableMinification) { |
| 3467 mainBuffer.write(';'); | 3494 mainBuffer.write(';'); |
| 3468 } | 3495 } |
| 3469 } | 3496 } |
| 3470 mainBuffer | 3497 mainBuffer |
| 3471 ..write(getReflectionDataParser()) | 3498 ..write(getReflectionDataParser()) |
| 3472 ..write('([$n'); | 3499 ..write('([$n'); |
| 3473 | 3500 |
| 3474 var sortedLibraries = Elements.sortedByPosition(libraryBuffers.keys); | 3501 var sortedElements = Elements.sortedByPosition(elementBuffers.keys); |
|
karlklose
2013/07/17 08:01:40
Type this variable (and also b in l. 3505)?
ahe
2013/07/17 08:31:24
Done.
| |
| 3475 for (LibraryElement library in sortedLibraries) { | 3502 bool hasPendingStatics = false; |
| 3476 List<CodeBuffer> buffers = libraryBuffers[library]; | 3503 for (Element element in sortedElements) { |
| 3504 if (!element.isLibrary()) { | |
| 3505 for (var b in elementBuffers[element]) { | |
|
ngeoffray
2013/07/17 07:35:57
Add a TODO to remove this once you implement it fo
ahe
2013/07/17 07:55:27
I'm not sure this code would go away. Consider it
ngeoffray
2013/07/17 08:08:42
OK. So after reading the code again, I realize I m
ahe
2013/07/17 08:31:24
If feel that would be easier to accomplish once I
| |
| 3506 if (b != null) { | |
| 3507 hasPendingStatics = true; | |
| 3508 compiler.reportInfo( | |
| 3509 element, MessageKind.GENERIC, {'text': 'Pending statics.'}); | |
| 3510 print(b.getText()); | |
| 3511 } | |
| 3512 } | |
| 3513 continue; | |
| 3514 } | |
| 3515 LibraryElement library = element; | |
| 3516 List<CodeBuffer> buffers = elementBuffers[library]; | |
| 3477 var buffer = buffers[0]; | 3517 var buffer = buffers[0]; |
| 3478 var uri = library.canonicalUri; | 3518 var uri = library.canonicalUri; |
| 3479 if (uri.scheme == 'file' && compiler.sourceMapUri != null) { | 3519 if (uri.scheme == 'file' && compiler.sourceMapUri != null) { |
| 3480 // TODO(ahe): It is a hack to use compiler.sourceMapUri | 3520 // TODO(ahe): It is a hack to use compiler.sourceMapUri |
| 3481 // here. It should be relative to the main JavaScript | 3521 // here. It should be relative to the main JavaScript |
| 3482 // output file. | 3522 // output file. |
| 3483 uri = relativize( | 3523 uri = relativize( |
| 3484 compiler.sourceMapUri, library.canonicalUri, false); | 3524 compiler.sourceMapUri, library.canonicalUri, false); |
| 3485 } | 3525 } |
| 3486 if (buffer != null) { | 3526 if (buffer != null) { |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 3498 buffer = buffers[1]; | 3538 buffer = buffers[1]; |
| 3499 if (buffer != null) { | 3539 if (buffer != null) { |
| 3500 deferredLibraries | 3540 deferredLibraries |
| 3501 ..write('["${library.getLibraryOrScriptName()}",$_') | 3541 ..write('["${library.getLibraryOrScriptName()}",$_') |
| 3502 ..write('"${uri}",$_') | 3542 ..write('"${uri}",$_') |
| 3503 ..write('[],$_') | 3543 ..write('[],$_') |
| 3504 ..write('{$n') | 3544 ..write('{$n') |
| 3505 ..addBuffer(buffer) | 3545 ..addBuffer(buffer) |
| 3506 ..write('}],$n'); | 3546 ..write('}],$n'); |
| 3507 } | 3547 } |
| 3508 libraryBuffers[library] = const []; | 3548 elementBuffers[library] = const []; |
| 3549 } | |
| 3550 if (hasPendingStatics) { | |
| 3551 compiler.internalError('Pending statics (see above).'); | |
|
ngeoffray
2013/07/17 07:35:57
Is that an internal error, or a not yet implemente
ahe
2013/07/17 07:55:27
It is an internal error.
If a static is "pending"
| |
| 3509 } | 3552 } |
| 3510 mainBuffer.write('])$N'); | 3553 mainBuffer.write('])$N'); |
| 3511 | 3554 |
| 3512 emitFinishClassesInvocationIfNecessary(mainBuffer); | 3555 emitFinishClassesInvocationIfNecessary(mainBuffer); |
| 3513 classesCollector = oldClassesCollector; | 3556 classesCollector = oldClassesCollector; |
| 3514 } | 3557 } |
| 3515 | 3558 |
| 3516 emitStaticFunctionGetters(mainBuffer); | 3559 emitStaticFunctionGetters(mainBuffer); |
| 3517 | 3560 |
| 3518 emitRuntimeTypeSupport(mainBuffer); | 3561 emitRuntimeTypeSupport(mainBuffer); |
| (...skipping 29 matching lines...) Expand all Loading... | |
| 3548 } | 3591 } |
| 3549 compiler.assembledCode = mainBuffer.getText(); | 3592 compiler.assembledCode = mainBuffer.getText(); |
| 3550 outputSourceMap(mainBuffer, compiler.assembledCode, ''); | 3593 outputSourceMap(mainBuffer, compiler.assembledCode, ''); |
| 3551 | 3594 |
| 3552 emitDeferredCode(); | 3595 emitDeferredCode(); |
| 3553 | 3596 |
| 3554 }); | 3597 }); |
| 3555 return compiler.assembledCode; | 3598 return compiler.assembledCode; |
| 3556 } | 3599 } |
| 3557 | 3600 |
| 3558 final Map<LibraryElement, List<CodeBuffer>> libraryBuffers = | |
| 3559 new Map<LibraryElement, List<CodeBuffer>>(); | |
| 3560 | |
| 3561 CodeBuffer bufferForElement(Element element, CodeBuffer eagerBuffer) { | 3601 CodeBuffer bufferForElement(Element element, CodeBuffer eagerBuffer) { |
| 3562 LibraryElement library = element.getLibrary(); | 3602 Element owner = element.getLibrary(); |
| 3563 List<CodeBuffer> buffers = libraryBuffers.putIfAbsent( | 3603 if (!element.isTopLevel() && !element.isNative()) { |
| 3564 library, () => <CodeBuffer>[null, null]); | 3604 // For static (not top level) elements, record their code in a buffer |
| 3605 // specific to the class. For now, not supported for native classes and | |
| 3606 // native elements. | |
| 3607 ClassElement cls = | |
| 3608 element.getEnclosingClassOrCompilationUnit().declaration; | |
| 3609 if (compiler.codegenWorld.instantiatedClasses.contains(cls) | |
| 3610 && !cls.isNative()) { | |
| 3611 owner = cls; | |
| 3612 } | |
| 3613 } | |
| 3614 if (owner == null) { | |
|
ngeoffray
2013/07/17 07:35:57
This looks too defensive.
ahe
2013/07/17 07:55:27
At first sight, yes. But notice that if we don't c
| |
| 3615 throw 'Bad owner of $element'; | |
|
karlklose
2013/07/17 08:01:40
Could you call internalError instead?
ahe
2013/07/17 08:31:24
Done.
| |
| 3616 } | |
| 3617 List<CodeBuffer> buffers = elementBuffers.putIfAbsent( | |
| 3618 owner, () => <CodeBuffer>[null, null]); | |
| 3565 bool deferred = isDeferred(element); | 3619 bool deferred = isDeferred(element); |
| 3566 int index = deferred ? 1 : 0; | 3620 int index = deferred ? 1 : 0; |
| 3567 CodeBuffer buffer = buffers[index]; | 3621 CodeBuffer buffer = buffers[index]; |
| 3568 if (buffer == null) { | 3622 if (buffer == null) { |
| 3569 buffer = buffers[index] = new CodeBuffer(); | 3623 buffer = buffers[index] = new CodeBuffer(); |
| 3570 } | 3624 } |
| 3571 return buffer; | 3625 return buffer; |
| 3572 } | 3626 } |
| 3573 | 3627 |
| 3574 /** | 3628 /** |
| (...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3675 | 3729 |
| 3676 // TODO(ahe): Remove this when deferred loading is fully implemented. | 3730 // TODO(ahe): Remove this when deferred loading is fully implemented. |
| 3677 void warnNotImplemented(Element element, String message) { | 3731 void warnNotImplemented(Element element, String message) { |
| 3678 compiler.reportMessage(compiler.spanFromSpannable(element), | 3732 compiler.reportMessage(compiler.spanFromSpannable(element), |
| 3679 MessageKind.GENERIC.error({'text': message}), | 3733 MessageKind.GENERIC.error({'text': message}), |
| 3680 api.Diagnostic.WARNING); | 3734 api.Diagnostic.WARNING); |
| 3681 } | 3735 } |
| 3682 | 3736 |
| 3683 // TODO(ahe): This code should be integrated in finishClasses. | 3737 // TODO(ahe): This code should be integrated in finishClasses. |
| 3684 String getReflectionDataParser() { | 3738 String getReflectionDataParser() { |
| 3739 String metadataField = '"${namer.metadataField}"'; | |
| 3685 return ''' | 3740 return ''' |
| 3686 (function (reflectionData) { | 3741 (function (reflectionData) { |
| 3687 if (!init.libraries) init.libraries = []; | 3742 if (!init.libraries) init.libraries = []; |
| 3688 if (!init.mangledNames) init.mangledNames = {}; | 3743 if (!init.mangledNames) init.mangledNames = {}; |
| 3689 if (!init.mangledGlobalNames) init.mangledGlobalNames = {}; | 3744 if (!init.mangledGlobalNames) init.mangledGlobalNames = {}; |
| 3745 if (!init.statics) init.statics = {}; | |
| 3690 init.getterPrefix = "${namer.getterPrefix}"; | 3746 init.getterPrefix = "${namer.getterPrefix}"; |
| 3691 init.setterPrefix = "${namer.setterPrefix}"; | 3747 init.setterPrefix = "${namer.setterPrefix}"; |
| 3692 var libraries = init.libraries; | 3748 var libraries = init.libraries; |
| 3693 var mangledNames = init.mangledNames; | 3749 var mangledNames = init.mangledNames; |
| 3694 var mangledGlobalNames = init.mangledGlobalNames; | 3750 var mangledGlobalNames = init.mangledGlobalNames; |
| 3695 var hasOwnProperty = Object.prototype.hasOwnProperty; | 3751 var hasOwnProperty = Object.prototype.hasOwnProperty; |
| 3696 var length = reflectionData.length; | 3752 var length = reflectionData.length; |
| 3697 for (var i = 0; i < length; i++) { | 3753 for (var i = 0; i < length; i++) { |
| 3698 var data = reflectionData[i]; | 3754 var data = reflectionData[i]; |
| 3699 var name = data[0]; | 3755 var name = data[0]; |
| 3700 var uri = data[1]; | 3756 var uri = data[1]; |
| 3701 var metadata = data[2]; | 3757 var metadata = data[2]; |
| 3702 var descriptor = data[3]; | 3758 var descriptor = data[3]; |
| 3703 var classes = []; | 3759 var classes = []; |
| 3704 var functions = []; | 3760 var functions = []; |
| 3705 for (var property in descriptor) { | 3761 function processStatics(descriptor) { |
| 3706 if (!hasOwnProperty.call(descriptor, property)) continue; | 3762 for (var property in descriptor) { |
| 3707 var element = descriptor[property]; | 3763 if (!hasOwnProperty.call(descriptor, property)) continue; |
| 3708 var firstChar = property.substring(0, 1); | 3764 var element = descriptor[property]; |
| 3709 var previousProperty; | 3765 var firstChar = property.substring(0, 1); |
| 3710 if (firstChar == "+") { | 3766 var previousProperty; |
| 3711 mangledGlobalNames[previousProperty] = property.substring(1); | 3767 if (firstChar === "+") { |
| 3712 } else if (firstChar == "@") { | 3768 mangledGlobalNames[previousProperty] = property.substring(1); |
| 3713 property = property.substring(1); | 3769 } else if (firstChar === "@") { |
| 3714 ${namer.CURRENT_ISOLATE}[property]["${namer.metadataField}"] = element; | 3770 property = property.substring(1); |
| 3715 } else if (typeof element === "function") { | 3771 ${namer.CURRENT_ISOLATE}[property][$metadataField] = element; |
| 3716 ${namer.CURRENT_ISOLATE}[previousProperty = property] = element; | 3772 } else if (typeof element === "function") { |
| 3717 functions.push(property); | 3773 ${namer.CURRENT_ISOLATE}[previousProperty = property] = element; |
| 3718 } else { | 3774 functions.push(property); |
| 3719 previousProperty = property; | 3775 } else { |
| 3720 var newDesc = {}; | 3776 previousProperty = property; |
| 3721 var previousProp; | 3777 var newDesc = {}; |
| 3722 for (var prop in element) { | 3778 var previousProp; |
| 3723 if (!hasOwnProperty.call(element, prop)) continue; | 3779 for (var prop in element) { |
| 3724 firstChar = prop.substring(0, 1); | 3780 if (!hasOwnProperty.call(element, prop)) continue; |
| 3725 if (firstChar == "+") { | 3781 firstChar = prop.substring(0, 1); |
| 3726 mangledNames[previousProp] = prop.substring(1); | 3782 if (prop === "static") { |
| 3727 } else if (firstChar == "@" && prop != "@") { | 3783 processStatics(init.statics[property] = element[prop]); |
| 3728 newDesc[prop.substring(1)]["${namer.metadataField}"] =''' | 3784 } else if (firstChar === "+") { |
| 3729 '''element[prop]; | 3785 mangledNames[previousProp] = prop.substring(1); |
| 3730 } else { | 3786 } else if (firstChar === "@" && prop !== "@") { |
| 3731 newDesc[previousProp = prop] = element[prop]; | 3787 newDesc[prop.substring(1)][$metadataField] = element[prop]; |
| 3788 } else { | |
| 3789 newDesc[previousProp = prop] = element[prop]; | |
| 3790 } | |
| 3732 } | 3791 } |
| 3792 $classesCollector[property] = newDesc; | |
| 3793 classes.push(property); | |
| 3733 } | 3794 } |
| 3734 $classesCollector[property] = newDesc; | |
| 3735 classes.push(property); | |
| 3736 } | 3795 } |
| 3737 } | 3796 } |
| 3797 processStatics(descriptor); | |
| 3738 libraries.push([name, uri, classes, functions, metadata]); | 3798 libraries.push([name, uri, classes, functions, metadata]); |
| 3739 } | 3799 } |
| 3740 })'''; | 3800 })'''; |
| 3741 } | 3801 } |
| 3742 } | 3802 } |
| 3743 | 3803 |
| 3744 const String GENERATED_BY = """ | 3804 const String GENERATED_BY = """ |
| 3745 // Generated by dart2js, the Dart to JavaScript compiler. | 3805 // Generated by dart2js, the Dart to JavaScript compiler. |
| 3746 """; | 3806 """; |
| 3747 | 3807 |
| 3748 const String HOOKS_API_USAGE = """ | 3808 const String HOOKS_API_USAGE = """ |
| 3749 // The code supports the following hooks: | 3809 // The code supports the following hooks: |
| 3750 // dartPrint(message) - if this function is defined it is called | 3810 // dartPrint(message) - if this function is defined it is called |
| 3751 // instead of the Dart [print] method. | 3811 // instead of the Dart [print] method. |
| 3752 // dartMainRunner(main) - if this function is defined, the Dart [main] | 3812 // dartMainRunner(main) - if this function is defined, the Dart [main] |
| 3753 // method will not be invoked directly. | 3813 // method will not be invoked directly. |
| 3754 // Instead, a closure that will invoke [main] is | 3814 // Instead, a closure that will invoke [main] is |
| 3755 // passed to [dartMainRunner]. | 3815 // passed to [dartMainRunner]. |
| 3756 """; | 3816 """; |
| OLD | NEW |