OLD | NEW |
---|---|
1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2011, 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 * Assigns JavaScript identifiers to Dart variables, class-names and members. | 8 * Assigns JavaScript identifiers to Dart variables, class-names and members. |
9 */ | 9 */ |
10 class Namer implements ClosureNamer { | 10 class Namer implements ClosureNamer { |
(...skipping 705 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
716 } | 716 } |
717 | 717 |
718 String isolateLazyInitializerAccess(Element element) { | 718 String isolateLazyInitializerAccess(Element element) { |
719 return "$CURRENT_ISOLATE.${getLazyInitializerName(element)}"; | 719 return "$CURRENT_ISOLATE.${getLazyInitializerName(element)}"; |
720 } | 720 } |
721 | 721 |
722 String operatorIsPrefix() => r'$is'; | 722 String operatorIsPrefix() => r'$is'; |
723 | 723 |
724 String operatorAsPrefix() => r'$as'; | 724 String operatorAsPrefix() => r'$as'; |
725 | 725 |
726 String operatorSignature() => r'$signature'; | |
727 | |
728 String functionTypeTag() => r'func'; | |
729 | |
730 String functionTypeVoidReturnTag() => r'void'; | |
731 | |
732 String functionTypeReturnTypeTag() => r'ret'; | |
733 | |
734 String functionTypeRequiredParametersTag() => r'args'; | |
735 | |
736 String functionTypeOptionalParametersTag() => r'opt'; | |
737 | |
738 String functionTypeNamedParametersTag() => r'named'; | |
739 | |
740 Map<FunctionType,String> functionTypeNameMap = | |
741 new Map<FunctionType,String>(); | |
742 FunctionTypeNamer functionTypeNamer = new FunctionTypeNamer(); | |
743 | |
744 String getFunctionTypeName(FunctionType functionType) { | |
745 return functionTypeNameMap.putIfAbsent(functionType, () { | |
746 String proposedName = functionTypeNamer.computeName(functionType); | |
747 String freshName = getFreshName(proposedName, usedInstanceNames, | |
748 suggestedInstanceNames, ensureSafe: true); | |
749 return freshName; | |
750 }); | |
751 } | |
752 | |
753 String operatorIsType(DartType type) { | |
754 if (type.kind == TypeKind.FUNCTION) { | |
755 // TODO(erikcorry): Reduce from $isx to ix when we are minifying. | |
756 return '${operatorIsPrefix()}_${getFunctionTypeName(type)}'; | |
757 } | |
758 return operatorIs(type.element); | |
759 } | |
760 | |
726 String operatorIs(Element element) { | 761 String operatorIs(Element element) { |
727 // TODO(erikcorry): Reduce from $isx to ix when we are minifying. | 762 // TODO(erikcorry): Reduce from $isx to ix when we are minifying. |
728 return '${operatorIsPrefix()}${getName(element)}'; | 763 return '${operatorIsPrefix()}${getName(element)}'; |
729 } | 764 } |
730 | 765 |
731 /* | 766 /* |
732 * Returns a name that does not clash with reserved JS keywords, | 767 * Returns a name that does not clash with reserved JS keywords, |
733 * and also ensures it won't clash with other identifiers. | 768 * and also ensures it won't clash with other identifiers. |
734 */ | 769 */ |
735 String _safeName(String name, Set<String> reserved) { | 770 String _safeName(String name, Set<String> reserved) { |
736 if (reserved.contains(name) || name.startsWith(r'$')) { | 771 if (reserved.contains(name) || name.startsWith(r'$')) { |
737 name = '\$$name'; | 772 name = '\$$name'; |
738 } | 773 } |
739 assert(!reserved.contains(name)); | 774 assert(!reserved.contains(name)); |
740 return name; | 775 return name; |
741 } | 776 } |
742 | 777 |
743 String substitutionName(Element element) { | 778 String substitutionName(Element element) { |
744 return '${operatorAsPrefix()}${getName(element)}'; | 779 return '${operatorAsPrefix()}${getName(element)}'; |
745 } | 780 } |
746 | 781 |
782 String signatureLocation(FunctionType type) { | |
783 ClassElement classElement = Types.getClassContext(type); | |
784 if (classElement != null) { | |
785 return '${isolateAccess(classElement)}'; | |
786 } else { | |
787 return '${CURRENT_ISOLATE}'; | |
karlklose
2013/03/22 13:17:46
No {} needed.
Johnni Winther
2013/06/21 12:19:14
I like them, anyway!
| |
788 } | |
789 } | |
790 | |
791 String signatureName(FunctionType type) { | |
792 String signature = '${operatorSignature()}_${getFunctionTypeName(type)}'; | |
793 return '${signatureLocation(type)}.$signature'; | |
794 } | |
795 | |
747 String safeName(String name) => _safeName(name, jsReserved); | 796 String safeName(String name) => _safeName(name, jsReserved); |
748 String safeVariableName(String name) => _safeName(name, jsVariableReserved); | 797 String safeVariableName(String name) => _safeName(name, jsVariableReserved); |
749 | 798 |
750 SourceString operatorNameToIdentifier(SourceString name) { | 799 SourceString operatorNameToIdentifier(SourceString name) { |
751 if (name == null) return null; | 800 if (name == null) return null; |
752 String value = name.stringValue; | 801 String value = name.stringValue; |
753 if (value == null) { | 802 if (value == null) { |
754 return name; | 803 return name; |
755 } else if (value == '==') { | 804 } else if (value == '==') { |
756 return const SourceString(r'$eq'); | 805 return const SourceString(r'$eq'); |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
790 return const SourceString(r'$or'); | 839 return const SourceString(r'$or'); |
791 } else if (value == '-') { | 840 } else if (value == '-') { |
792 return const SourceString(r'$sub'); | 841 return const SourceString(r'$sub'); |
793 } else if (value == 'unary-') { | 842 } else if (value == 'unary-') { |
794 return const SourceString(r'$negate'); | 843 return const SourceString(r'$negate'); |
795 } else { | 844 } else { |
796 return name; | 845 return name; |
797 } | 846 } |
798 } | 847 } |
799 } | 848 } |
849 | |
850 class FunctionTypeNamer extends DartTypeVisitor { | |
851 StringBuffer sb; | |
852 | |
853 String computeName(DartType type) { | |
854 sb = new StringBuffer(); | |
855 visit(type); | |
856 return sb.toString(); | |
857 } | |
858 | |
859 visit(DartType type) { | |
860 type.accept(this, null); | |
861 } | |
862 | |
863 visitType(DartType type, _) { | |
864 sb.write(type.name.slowToString()); | |
865 } | |
866 | |
867 visitFunctionType(FunctionType type, _) { | |
868 visit(type.returnType); | |
869 sb.write('_'); | |
870 for (Link<DartType> link = type.parameterTypes; | |
871 !link.isEmpty; | |
872 link = link.tail) { | |
873 sb.write('_'); | |
874 visit(link.head); | |
875 } | |
876 for (Link<DartType> link = type.optionalParameterTypes; | |
karlklose
2013/03/22 13:17:46
Don't we need a separator between the sets of para
Johnni Winther
2013/06/21 12:19:14
Done.
| |
877 !link.isEmpty; | |
878 link = link.tail) { | |
879 sb.write('_'); | |
880 visit(link.head); | |
881 } | |
882 if (!type.namedParameterTypes.isEmpty) { | |
883 for (Link<DartType> link = type.namedParameterTypes; | |
884 !link.isEmpty; | |
885 link = link.tail) { | |
886 sb.write('_'); | |
887 visit(link.head); | |
888 } | |
889 } | |
890 } | |
891 | |
892 } | |
OLD | NEW |