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 /** | 5 /** |
| 6 * A function element that represents a closure call. The signature is copied | 6 * A function element that represents a closure call. The signature is copied |
| 7 * from the given element. | 7 * from the given element. |
| 8 */ | 8 */ |
| 9 class ClosureInvocationElement extends FunctionElement { | 9 class ClosureInvocationElement extends FunctionElement { |
| 10 ClosureInvocationElement(SourceString name, | 10 ClosureInvocationElement(SourceString name, |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 84 => '${namer.ISOLATE}.\$finishIsolateConstructor'; | 84 => '${namer.ISOLATE}.\$finishIsolateConstructor'; |
| 85 String get pendingClassesName | 85 String get pendingClassesName |
| 86 => '${namer.ISOLATE}.\$pendingClasses'; | 86 => '${namer.ISOLATE}.\$pendingClasses'; |
| 87 String get isolatePropertiesName | 87 String get isolatePropertiesName |
| 88 => '${namer.ISOLATE}.${namer.ISOLATE_PROPERTIES}'; | 88 => '${namer.ISOLATE}.${namer.ISOLATE_PROPERTIES}'; |
| 89 String get supportsProtoName | 89 String get supportsProtoName |
| 90 => 'supportsProto'; | 90 => 'supportsProto'; |
| 91 String get lazyInitializerName | 91 String get lazyInitializerName |
| 92 => '${namer.ISOLATE}.\$lazy'; | 92 => '${namer.ISOLATE}.\$lazy'; |
| 93 | 93 |
| 94 final String GETTER_SUFFIX = "?"; | 94 // Property name suffixes. If the accessors are renaming then the format |
| 95 final String SETTER_SUFFIX = "!"; | 95 // is <accessorName>:<fieldName><suffix>. We use the suffix to know whether |
| 96 final String GETTER_SETTER_SUFFIX = "="; | 96 // to look for the ':' separator in order to avoid doing the indexOf operation |
| 97 // on every single property (they are quite rare). None of these characters | |
| 98 // are legal in an identifier and they are related by bit patterns. | |
| 99 // setter < 0x3c | |
| 100 // both = 0x3d | |
| 101 // getter > 0x3e | |
| 102 // renaming setter | 0x7c | |
| 103 // renaming both } 0x7d | |
| 104 // renaming getter ~ 0x7e | |
| 105 const SUFFIX_MASK = 0x3f; | |
| 106 const FIRST_SUFFIX_CODE = 0x3c; | |
| 107 const SETTER_CODE = 0x3c; | |
| 108 const GETTER_SETTER_CODE = 0x3d; | |
| 109 const GETTER_CODE = 0x3e; | |
| 110 const RENAMING_FLAG = 0x40; | |
| 111 String needsGetter(String variable) => '($variable & 3) > 0'; | |
|
floitsch
2012/10/25 12:58:38
needsGetterCode or something to indicate that this
erikcorry
2012/12/06 09:38:07
Done.
| |
| 112 String needsSetter(String variable) => '($variable & 2) == 0'; | |
| 113 String isRenaming(String variable) => '($variable & $RENAMING_FLAG) != 0'; | |
| 97 | 114 |
| 98 String get generateGetterSetterFunction { | 115 String get generateGetterSetterFunction { |
| 99 return """ | 116 return """ |
| 100 function(field, prototype) { | 117 function(field, prototype) { |
| 101 var len = field.length; | 118 var len = field.length; |
| 102 var lastChar = field[len - 1]; | 119 var lastCharCode = field.charCodeAt(len - 1); |
| 103 var needsGetter = lastChar == '$GETTER_SUFFIX' || lastChar == '$GETTER_SETTE R_SUFFIX'; | 120 var needsAccessor = (lastCharCode & $SUFFIX_MASK) >= $FIRST_SUFFIX_CODE; |
| 104 var needsSetter = lastChar == '$SETTER_SUFFIX' || lastChar == '$GETTER_SETTE R_SUFFIX'; | 121 if (needsAccessor) { |
| 105 if (needsGetter || needsSetter) field = field.substring(0, len - 1); | 122 var needsGetter = ${needsGetter('lastCharCode')}; |
| 106 if (needsGetter) { | 123 var needsSetter = ${needsSetter('lastCharCode')}; |
| 107 var getterString = "return this." + field + ";"; | 124 var renaming = ${isRenaming('lastCharCode')}; |
| 108 """ | 125 var accessorName = field = field.substring(0, len - 1); |
|
floitsch
2012/10/25 08:42:40
remove "field =".
erikcorry
2012/10/25 09:09:28
Then it won't work any more!?
floitsch
2012/10/25 12:58:38
never mind. wasn't thinking.
Please put in two lin
| |
| 109 /* The supportsProtoCheck below depends on the getter/setter convention. | 126 if (renaming) { |
| 110 When changing here, update the protoCheck too. */ | 127 var divider = field.indexOf(":"); |
| 111 """ | 128 accessorName = field.substring(0, divider); |
| 112 prototype["get\$" + field] = new Function(getterString); | 129 field = field.substring(divider + 1); |
| 113 } | 130 } |
| 114 if (needsSetter) { | 131 if (needsGetter) { |
| 115 var setterString = "this." + field + " = v;"; | 132 var getterString = "return this." + field + ";"; |
| 116 prototype["set\$" + field] = new Function("v", setterString); | 133 prototype["get\$" + accessorName] = new Function(getterString); |
| 134 } | |
| 135 if (needsSetter) { | |
| 136 var setterString = "this." + field + " = v;"; | |
| 137 prototype["set\$" + accessorName] = new Function("v", setterString); | |
| 138 } | |
| 117 } | 139 } |
| 118 return field; | 140 return field; |
| 119 }"""; | 141 }"""; |
| 120 } | 142 } |
| 121 | 143 |
| 122 String get defineClassFunction { | 144 String get defineClassFunction { |
| 123 // First the class name, then the super class name, followed by the fields | 145 // First the class name, then the super class name, followed by the fields |
| 124 // (in an array) and the members (inside an Object literal). | 146 // (in an array) and the members (inside an Object literal). |
| 125 // The caller can also pass in the constructor as a function if needed. | 147 // The caller can also pass in the constructor as a function if needed. |
| 126 // | 148 // |
| (...skipping 349 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 476 // | 498 // |
| 477 // We need to generate a stub for (5) because the order of the | 499 // We need to generate a stub for (5) because the order of the |
| 478 // stub arguments and the real method may be different. | 500 // stub arguments and the real method may be different. |
| 479 | 501 |
| 480 // Keep a cache of which stubs have already been generated, to | 502 // Keep a cache of which stubs have already been generated, to |
| 481 // avoid duplicates. Note that even if selectors are | 503 // avoid duplicates. Note that even if selectors are |
| 482 // canonicalized, we would still need this cache: a typed selector | 504 // canonicalized, we would still need this cache: a typed selector |
| 483 // on A and a typed selector on B could yield the same stub. | 505 // on A and a typed selector on B could yield the same stub. |
| 484 Set<String> generatedStubNames = new Set<String>(); | 506 Set<String> generatedStubNames = new Set<String>(); |
| 485 if (compiler.enabledFunctionApply | 507 if (compiler.enabledFunctionApply |
| 486 && member.name == Namer.CLOSURE_INVOCATION_NAME) { | 508 && member.name == namer.CLOSURE_INVOCATION_NAME) { |
| 487 // If [Function.apply] is called, we pessimistically compile all | 509 // If [Function.apply] is called, we pessimistically compile all |
| 488 // possible stubs for this closure. | 510 // possible stubs for this closure. |
| 489 // TODO(5074): This functionality only supports the new | 511 // TODO(5074): This functionality only supports the new |
| 490 // parameter specification, and this comment should be removed | 512 // parameter specification, and this comment should be removed |
| 491 // once the old specification is not supported. | 513 // once the old specification is not supported. |
| 492 FunctionSignature signature = member.computeSignature(compiler); | 514 FunctionSignature signature = member.computeSignature(compiler); |
| 493 Set<Selector> selectors = signature.optionalParametersAreNamed | 515 Set<Selector> selectors = signature.optionalParametersAreNamed |
| 494 ? computeNamedSelectors(signature, member) | 516 ? computeNamedSelectors(signature, member) |
| 495 : computeOptionalSelectors(signature, member); | 517 : computeOptionalSelectors(signature, member); |
| 496 for (Selector selector in selectors) { | 518 for (Selector selector in selectors) { |
| (...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 673 } | 695 } |
| 674 | 696 |
| 675 /** | 697 /** |
| 676 * Documentation wanted -- johnniwinther | 698 * Documentation wanted -- johnniwinther |
| 677 * | 699 * |
| 678 * Invariant: [classElement] must be a declaration element. | 700 * Invariant: [classElement] must be a declaration element. |
| 679 */ | 701 */ |
| 680 void visitClassFields(ClassElement classElement, | 702 void visitClassFields(ClassElement classElement, |
| 681 void addField(Element member, | 703 void addField(Element member, |
| 682 String name, | 704 String name, |
| 705 String accessorName, | |
| 683 bool needsGetter, | 706 bool needsGetter, |
| 684 bool needsSetter, | 707 bool needsSetter, |
| 685 bool needsCheckedSetter)) { | 708 bool needsCheckedSetter)) { |
| 686 assert(invariant(classElement, classElement.isDeclaration)); | 709 assert(invariant(classElement, classElement.isDeclaration)); |
| 687 // If the class is never instantiated we still need to set it up for | 710 // If the class is never instantiated we still need to set it up for |
| 688 // inheritance purposes, but we can simplify its JavaScript constructor. | 711 // inheritance purposes, but we can simplify its JavaScript constructor. |
| 689 bool isInstantiated = | 712 bool isInstantiated = |
| 690 compiler.codegenWorld.instantiatedClasses.contains(classElement); | 713 compiler.codegenWorld.instantiatedClasses.contains(classElement); |
| 691 | 714 |
| 692 void visitField(ClassElement enclosingClass, Element member) { | 715 void visitField(ClassElement enclosingClass, Element member) { |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 708 if (identical(enclosingClass, classElement)) { | 731 if (identical(enclosingClass, classElement)) { |
| 709 needsGetter = instanceFieldNeedsGetter(member); | 732 needsGetter = instanceFieldNeedsGetter(member); |
| 710 needsSetter = instanceFieldNeedsSetter(member); | 733 needsSetter = instanceFieldNeedsSetter(member); |
| 711 } else { | 734 } else { |
| 712 isShadowed = classElement.isShadowedByField(member); | 735 isShadowed = classElement.isShadowedByField(member); |
| 713 } | 736 } |
| 714 | 737 |
| 715 if ((isInstantiated && !enclosingClass.isNative()) | 738 if ((isInstantiated && !enclosingClass.isNative()) |
| 716 || needsGetter | 739 || needsGetter |
| 717 || needsSetter) { | 740 || needsSetter) { |
| 718 String fieldName = isShadowed | 741 String accessorName = isShadowed |
| 719 ? namer.shadowedFieldName(member) | 742 ? namer.shadowedFieldName(member) |
| 720 : namer.getName(member); | 743 : namer.getName(member); |
| 744 String fieldName = enclosingClass.isNative() ? | |
| 745 member.name.slowToString() : accessorName; | |
| 721 bool needsCheckedSetter = false; | 746 bool needsCheckedSetter = false; |
| 722 if (needsSetter && compiler.enableTypeAssertions | 747 if (needsSetter && compiler.enableTypeAssertions |
| 723 && canGenerateCheckedSetter(member)) { | 748 && canGenerateCheckedSetter(member)) { |
| 724 needsCheckedSetter = true; | 749 needsCheckedSetter = true; |
| 725 needsSetter = false; | 750 needsSetter = false; |
| 726 } | 751 } |
| 727 // Getters and setters with suffixes will be generated dynamically. | 752 // Getters and setters with suffixes will be generated dynamically. |
| 728 addField(member, | 753 addField(member, |
| 729 fieldName, | 754 fieldName, |
| 755 accessorName, | |
| 730 needsGetter, | 756 needsGetter, |
| 731 needsSetter, | 757 needsSetter, |
| 732 needsCheckedSetter); | 758 needsCheckedSetter); |
| 733 } | 759 } |
| 734 } | 760 } |
| 735 | 761 |
| 736 // If a class is not instantiated then we add the field just so we can | 762 // If a class is not instantiated then we add the field just so we can |
| 737 // generate the field getter/setter dynamically. Since this is only | 763 // generate the field getter/setter dynamically. Since this is only |
| 738 // allowed on fields that are in [classElement] we don't need to visit | 764 // allowed on fields that are in [classElement] we don't need to visit |
| 739 // superclasses for non-instantiated classes. | 765 // superclasses for non-instantiated classes. |
| 740 classElement.implementation.forEachInstanceField( | 766 classElement.implementation.forEachInstanceField( |
| 741 visitField, | 767 visitField, |
| 742 includeBackendMembers: true, | 768 includeBackendMembers: true, |
| 743 includeSuperMembers: isInstantiated && !classElement.isNative()); | 769 includeSuperMembers: isInstantiated && !classElement.isNative()); |
| 744 } | 770 } |
| 745 | 771 |
| 746 void generateGetter(Element member, String fieldName, CodeBuffer buffer) { | 772 void generateGetter(Element member, String fieldName, String accessorName, |
| 747 String getterName = namer.getterName(member.getLibrary(), member.name); | 773 CodeBuffer buffer) { |
| 774 String getterName = | |
| 775 namer.getterName(member.getLibrary(), new SourceString(accessorName)); | |
| 748 buffer.add("$getterName: function() { return this.$fieldName; }"); | 776 buffer.add("$getterName: function() { return this.$fieldName; }"); |
| 749 } | 777 } |
| 750 | 778 |
| 751 void generateSetter(Element member, String fieldName, CodeBuffer buffer) { | 779 void generateSetter(Element member, String fieldName, String accessorName, |
| 752 String setterName = namer.setterName(member.getLibrary(), member.name); | 780 CodeBuffer buffer) { |
| 781 String setterName = | |
| 782 namer.setterName(member.getLibrary(), new SourceString(accessorName)); | |
| 753 buffer.add("$setterName: function(v) { this.$fieldName = v; }"); | 783 buffer.add("$setterName: function(v) { this.$fieldName = v; }"); |
| 754 } | 784 } |
| 755 | 785 |
| 756 bool canGenerateCheckedSetter(Element member) { | 786 bool canGenerateCheckedSetter(Element member) { |
| 757 DartType type = member.computeType(compiler); | 787 DartType type = member.computeType(compiler); |
| 758 if (type.element.isTypeVariable() | 788 if (type.element.isTypeVariable() |
| 759 || type.element == compiler.dynamicClass | 789 || type.element == compiler.dynamicClass |
| 760 || type.element == compiler.objectClass) { | 790 || type.element == compiler.objectClass) { |
| 761 // TODO(ngeoffray): Support type checks on type parameters. | 791 // TODO(ngeoffray): Support type checks on type parameters. |
| 762 return false; | 792 return false; |
| 763 } | 793 } |
| 764 return true; | 794 return true; |
| 765 } | 795 } |
| 766 | 796 |
| 767 void generateCheckedSetter(Element member, | 797 void generateCheckedSetter(Element member, |
| 768 String fieldName, | 798 String fieldName, |
| 799 String accessorName, | |
| 769 CodeBuffer buffer) { | 800 CodeBuffer buffer) { |
| 770 assert(canGenerateCheckedSetter(member)); | 801 assert(canGenerateCheckedSetter(member)); |
| 771 DartType type = member.computeType(compiler); | 802 DartType type = member.computeType(compiler); |
| 772 SourceString helper = compiler.backend.getCheckedModeHelper(type); | 803 SourceString helper = compiler.backend.getCheckedModeHelper(type); |
| 773 FunctionElement helperElement = compiler.findHelper(helper); | 804 FunctionElement helperElement = compiler.findHelper(helper); |
| 774 String helperName = namer.isolateAccess(helperElement); | 805 String helperName = namer.isolateAccess(helperElement); |
| 775 String additionalArgument = ''; | 806 String additionalArgument = ''; |
| 776 if (helperElement.computeSignature(compiler).parameterCount != 1) { | 807 if (helperElement.computeSignature(compiler).parameterCount != 1) { |
| 777 additionalArgument = ", '${namer.operatorIs(type.element)}'"; | 808 additionalArgument = ", '${namer.operatorIs(type.element)}'"; |
| 778 } | 809 } |
| 779 String setterName = namer.setterName(member.getLibrary(), member.name); | 810 String setterName = |
| 811 namer.setterName(member.getLibrary(), new SourceString(accessorName)); | |
| 780 buffer.add("$setterName: function(v) { " | 812 buffer.add("$setterName: function(v) { " |
| 781 "this.$fieldName = $helperName(v$additionalArgument); }"); | 813 "this.$fieldName = $helperName(v$additionalArgument); }"); |
| 782 } | 814 } |
| 783 | 815 |
| 784 void emitClassConstructor(ClassElement classElement, CodeBuffer buffer) { | 816 void emitClassConstructor(ClassElement classElement, CodeBuffer buffer) { |
| 785 /* Do nothing. */ | 817 /* Do nothing. */ |
| 786 } | 818 } |
| 787 | 819 |
| 788 void emitClassFields(ClassElement classElement, CodeBuffer buffer) { | 820 void emitClassFields(ClassElement classElement, CodeBuffer buffer) { |
| 789 buffer.add('"": ['); | 821 buffer.add('"": ['); |
| 790 bool isFirstField = true; | 822 bool isFirstField = true; |
| 791 visitClassFields(classElement, (Element member, | 823 visitClassFields(classElement, (Element member, |
| 792 String name, | 824 String name, |
| 825 String accessorName, | |
| 793 bool needsGetter, | 826 bool needsGetter, |
| 794 bool needsSetter, | 827 bool needsSetter, |
| 795 bool needsCheckedSetter) { | 828 bool needsCheckedSetter) { |
| 796 if (isFirstField) { | 829 if (isFirstField) { |
| 797 isFirstField = false; | 830 isFirstField = false; |
| 798 } else { | 831 } else { |
| 799 buffer.add(", "); | 832 buffer.add(", "); |
| 800 } | 833 } |
| 801 buffer.add('"$name'); | 834 buffer.add('"$accessorName'); |
| 835 int flag = 0; | |
| 836 if (name != accessorName) { | |
| 837 buffer.add(':$name'); | |
| 838 assert(needsGetter || needsSetter); | |
| 839 flag = RENAMING_FLAG; | |
| 840 } | |
| 802 if (needsGetter && needsSetter) { | 841 if (needsGetter && needsSetter) { |
| 803 buffer.add(GETTER_SETTER_SUFFIX); | 842 buffer.addCharCode(GETTER_SETTER_CODE + flag); |
|
floitsch
2012/10/25 12:58:38
I would prefer "|" to indicate that this is a bit-
erikcorry
2012/12/06 09:38:07
Done.
| |
| 804 } else if (needsGetter) { | 843 } else if (needsGetter) { |
| 805 buffer.add(GETTER_SUFFIX); | 844 buffer.addCharCode(GETTER_CODE + flag); |
| 806 } else if (needsSetter) { | 845 } else if (needsSetter) { |
| 807 buffer.add(SETTER_SUFFIX); | 846 buffer.addCharCode(SETTER_CODE + flag); |
| 808 } | 847 } |
| 809 buffer.add('"'); | 848 buffer.add('"'); |
| 810 }); | 849 }); |
| 811 buffer.add(']'); | 850 buffer.add(']'); |
| 812 } | 851 } |
| 813 | 852 |
| 814 /** Each getter/setter must be prefixed with a ",\n ". */ | 853 /** Each getter/setter must be prefixed with a ",\n ". */ |
| 815 void emitClassGettersSetters(ClassElement classElement, CodeBuffer buffer, | 854 void emitClassGettersSetters(ClassElement classElement, CodeBuffer buffer, |
| 816 {bool omitLeadingComma: false}) { | 855 {bool omitLeadingComma: false}) { |
| 817 visitClassFields(classElement, (Element member, | 856 visitClassFields(classElement, (Element member, |
| 818 String name, | 857 String name, |
| 858 String accessorName, | |
| 819 bool needsGetter, | 859 bool needsGetter, |
| 820 bool needsSetter, | 860 bool needsSetter, |
| 821 bool needsCheckedSetter) { | 861 bool needsCheckedSetter) { |
| 822 if (needsCheckedSetter) { | 862 if (needsCheckedSetter) { |
| 823 assert(!needsSetter); | 863 assert(!needsSetter); |
| 824 if (!omitLeadingComma) { | 864 if (!omitLeadingComma) { |
| 825 buffer.add(",\n "); | 865 buffer.add(",\n "); |
| 826 } else { | 866 } else { |
| 827 omitLeadingComma = false; | 867 omitLeadingComma = false; |
| 828 } | 868 } |
| 829 generateCheckedSetter(member, name, buffer); | 869 generateCheckedSetter(member, name, accessorName, buffer); |
| 830 } | 870 } |
| 831 }); | 871 }); |
| 832 } | 872 } |
| 833 | 873 |
| 834 /** | 874 /** |
| 835 * Documentation wanted -- johnniwinther | 875 * Documentation wanted -- johnniwinther |
| 836 * | 876 * |
| 837 * Invariant: [classElement] must be a declaration element. | 877 * Invariant: [classElement] must be a declaration element. |
| 838 */ | 878 */ |
| 839 void generateClass(ClassElement classElement, CodeBuffer buffer) { | 879 void generateClass(ClassElement classElement, CodeBuffer buffer) { |
| (...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1006 | 1046 |
| 1007 void emitStaticFunctionGetters(CodeBuffer buffer) { | 1047 void emitStaticFunctionGetters(CodeBuffer buffer) { |
| 1008 Set<FunctionElement> functionsNeedingGetter = | 1048 Set<FunctionElement> functionsNeedingGetter = |
| 1009 compiler.codegenWorld.staticFunctionsNeedingGetter; | 1049 compiler.codegenWorld.staticFunctionsNeedingGetter; |
| 1010 for (FunctionElement element in functionsNeedingGetter) { | 1050 for (FunctionElement element in functionsNeedingGetter) { |
| 1011 // The static function does not have the correct name. Since | 1051 // The static function does not have the correct name. Since |
| 1012 // [addParameterStubs] use the name to create its stubs we simply | 1052 // [addParameterStubs] use the name to create its stubs we simply |
| 1013 // create a fake element with the correct name. | 1053 // create a fake element with the correct name. |
| 1014 // Note: the callElement will not have any enclosingElement. | 1054 // Note: the callElement will not have any enclosingElement. |
| 1015 FunctionElement callElement = | 1055 FunctionElement callElement = |
| 1016 new ClosureInvocationElement(Namer.CLOSURE_INVOCATION_NAME, element); | 1056 new ClosureInvocationElement(namer.CLOSURE_INVOCATION_NAME, element); |
| 1017 String staticName = namer.getName(element); | 1057 String staticName = namer.getName(element); |
| 1018 String invocationName = namer.instanceMethodName(callElement); | 1058 String invocationName = namer.instanceMethodName(callElement); |
| 1019 String fieldAccess = '$isolateProperties.$staticName'; | 1059 String fieldAccess = '$isolateProperties.$staticName'; |
| 1020 buffer.add("$fieldAccess.$invocationName = $fieldAccess;\n"); | 1060 buffer.add("$fieldAccess.$invocationName = $fieldAccess;\n"); |
| 1021 addParameterStubs(callElement, (String name, CodeBuffer value) { | 1061 addParameterStubs(callElement, (String name, CodeBuffer value) { |
| 1022 buffer.add('$fieldAccess.$name = $value;\n'); | 1062 buffer.add('$fieldAccess.$name = $value;\n'); |
| 1023 }); | 1063 }); |
| 1024 // If a static function is used as a closure we need to add its name | 1064 // If a static function is used as a closure we need to add its name |
| 1025 // in case it is used in spawnFunction. | 1065 // in case it is used in spawnFunction. |
| 1026 String fieldName = namer.STATIC_CLOSURE_NAME_NAME; | 1066 String fieldName = namer.STATIC_CLOSURE_NAME_NAME; |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1083 needsClosureClass = true; | 1123 needsClosureClass = true; |
| 1084 | 1124 |
| 1085 // Define the constructor with a name so that Object.toString can | 1125 // Define the constructor with a name so that Object.toString can |
| 1086 // find the class name of the closure class. | 1126 // find the class name of the closure class. |
| 1087 emitBoundClosureClassHeader(mangledName, superName, boundClosureBuffer); | 1127 emitBoundClosureClassHeader(mangledName, superName, boundClosureBuffer); |
| 1088 // Now add the methods on the closure class. The instance method does not | 1128 // Now add the methods on the closure class. The instance method does not |
| 1089 // have the correct name. Since [addParameterStubs] use the name to create | 1129 // have the correct name. Since [addParameterStubs] use the name to create |
| 1090 // its stubs we simply create a fake element with the correct name. | 1130 // its stubs we simply create a fake element with the correct name. |
| 1091 // Note: the callElement will not have any enclosingElement. | 1131 // Note: the callElement will not have any enclosingElement. |
| 1092 FunctionElement callElement = | 1132 FunctionElement callElement = |
| 1093 new ClosureInvocationElement(Namer.CLOSURE_INVOCATION_NAME, member); | 1133 new ClosureInvocationElement(namer.CLOSURE_INVOCATION_NAME, member); |
| 1094 | 1134 |
| 1095 String invocationName = namer.instanceMethodName(callElement); | 1135 String invocationName = namer.instanceMethodName(callElement); |
| 1096 List<String> arguments = new List<String>(parameterCount); | 1136 List<String> arguments = new List<String>(parameterCount); |
| 1097 for (int i = 0; i < parameterCount; i++) { | 1137 for (int i = 0; i < parameterCount; i++) { |
| 1098 arguments[i] = "p$i"; | 1138 arguments[i] = "p$i"; |
| 1099 } | 1139 } |
| 1100 String joinedArgs = Strings.join(arguments, ", "); | 1140 String joinedArgs = Strings.join(arguments, ", "); |
| 1101 boundClosureBuffer.add( | 1141 boundClosureBuffer.add( |
| 1102 "$invocationName: function($joinedArgs) {"); | 1142 "$invocationName: function($joinedArgs) {"); |
| 1103 boundClosureBuffer.add(" return this.self[this.target]($joinedArgs);"); | 1143 boundClosureBuffer.add(" return this.self[this.target]($joinedArgs);"); |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1139 getter = "this.${namer.getterName(member.getLibrary(), member.name)}()"; | 1179 getter = "this.${namer.getterName(member.getLibrary(), member.name)}()"; |
| 1140 } else { | 1180 } else { |
| 1141 String name = namer.instanceFieldName(memberLibrary, member.name); | 1181 String name = namer.instanceFieldName(memberLibrary, member.name); |
| 1142 getter = "this.$name"; | 1182 getter = "this.$name"; |
| 1143 } | 1183 } |
| 1144 for (Selector selector in selectors) { | 1184 for (Selector selector in selectors) { |
| 1145 if (selector.applies(member, compiler)) { | 1185 if (selector.applies(member, compiler)) { |
| 1146 String invocationName = | 1186 String invocationName = |
| 1147 namer.instanceMethodInvocationName(memberLibrary, member.name, | 1187 namer.instanceMethodInvocationName(memberLibrary, member.name, |
| 1148 selector); | 1188 selector); |
| 1149 SourceString callName = Namer.CLOSURE_INVOCATION_NAME; | 1189 SourceString callName = namer.CLOSURE_INVOCATION_NAME; |
| 1150 String closureCallName = | 1190 String closureCallName = |
| 1151 namer.instanceMethodInvocationName(memberLibrary, callName, | 1191 namer.instanceMethodInvocationName(memberLibrary, callName, |
| 1152 selector); | 1192 selector); |
| 1153 List<String> arguments = <String>[]; | 1193 List<String> arguments = <String>[]; |
| 1154 for (int i = 0; i < selector.argumentCount; i++) { | 1194 for (int i = 0; i < selector.argumentCount; i++) { |
| 1155 arguments.add("arg$i"); | 1195 arguments.add("arg$i"); |
| 1156 } | 1196 } |
| 1157 String joined = Strings.join(arguments, ", "); | 1197 String joined = Strings.join(arguments, ", "); |
| 1158 CodeBuffer getterBuffer = new CodeBuffer(); | 1198 CodeBuffer getterBuffer = new CodeBuffer(); |
| 1159 getterBuffer.add( | 1199 getterBuffer.add( |
| (...skipping 416 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1576 const String HOOKS_API_USAGE = """ | 1616 const String HOOKS_API_USAGE = """ |
| 1577 // Generated by dart2js, the Dart to JavaScript compiler. | 1617 // Generated by dart2js, the Dart to JavaScript compiler. |
| 1578 // The code supports the following hooks: | 1618 // The code supports the following hooks: |
| 1579 // dartPrint(message) - if this function is defined it is called | 1619 // dartPrint(message) - if this function is defined it is called |
| 1580 // instead of the Dart [print] method. | 1620 // instead of the Dart [print] method. |
| 1581 // dartMainRunner(main) - if this function is defined, the Dart [main] | 1621 // dartMainRunner(main) - if this function is defined, the Dart [main] |
| 1582 // method will not be invoked directly. | 1622 // method will not be invoked directly. |
| 1583 // Instead, a closure that will invoke [main] is | 1623 // Instead, a closure that will invoke [main] is |
| 1584 // passed to [dartMainRunner]. | 1624 // passed to [dartMainRunner]. |
| 1585 """; | 1625 """; |
| OLD | NEW |