| 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 155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 166 if (_jsVariableReserved == null) { | 166 if (_jsVariableReserved == null) { |
| 167 _jsVariableReserved = new Set<String>(); | 167 _jsVariableReserved = new Set<String>(); |
| 168 _jsVariableReserved.addAll(javaScriptKeywords); | 168 _jsVariableReserved.addAll(javaScriptKeywords); |
| 169 _jsVariableReserved.addAll(reservedPropertySymbols); | 169 _jsVariableReserved.addAll(reservedPropertySymbols); |
| 170 _jsVariableReserved.addAll(reservedGlobalSymbols); | 170 _jsVariableReserved.addAll(reservedGlobalSymbols); |
| 171 } | 171 } |
| 172 return _jsVariableReserved; | 172 return _jsVariableReserved; |
| 173 } | 173 } |
| 174 | 174 |
| 175 final String CURRENT_ISOLATE; | 175 final String CURRENT_ISOLATE; |
| 176 String get GLOBAL_OBJECT => CURRENT_ISOLATE; | |
| 177 | 176 |
| 178 final String getterPrefix = r'get$'; | 177 final String getterPrefix = r'get$'; |
| 179 final String setterPrefix = r'set$'; | 178 final String setterPrefix = r'set$'; |
| 180 final String metadataField = '@'; | 179 final String metadataField = '@'; |
| 181 | 180 |
| 182 /** | 181 /** |
| 183 * Map from top-level or static elements to their unique identifiers provided | 182 * Map from top-level or static elements to their unique identifiers provided |
| 184 * by [getName]. | 183 * by [getName]. |
| 185 * | 184 * |
| 186 * Invariant: Keys must be declaration elements. | 185 * Invariant: Keys must be declaration elements. |
| (...skipping 573 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 760 } | 759 } |
| 761 | 760 |
| 762 String isolateStaticClosureAccess(Element element) { | 761 String isolateStaticClosureAccess(Element element) { |
| 763 return "$CURRENT_ISOLATE.${getStaticClosureName(element)}"; | 762 return "$CURRENT_ISOLATE.${getStaticClosureName(element)}"; |
| 764 } | 763 } |
| 765 | 764 |
| 766 String operatorIsPrefix() => r'$is'; | 765 String operatorIsPrefix() => r'$is'; |
| 767 | 766 |
| 768 String operatorAsPrefix() => r'$as'; | 767 String operatorAsPrefix() => r'$as'; |
| 769 | 768 |
| 770 String operatorSignature() => r'$signature'; | |
| 771 | |
| 772 String functionTypeTag() => r'func'; | |
| 773 | |
| 774 String functionTypeVoidReturnTag() => r'void'; | |
| 775 | |
| 776 String functionTypeReturnTypeTag() => r'ret'; | |
| 777 | |
| 778 String functionTypeRequiredParametersTag() => r'args'; | |
| 779 | |
| 780 String functionTypeOptionalParametersTag() => r'opt'; | |
| 781 | |
| 782 String functionTypeNamedParametersTag() => r'named'; | |
| 783 | |
| 784 Map<FunctionType,String> functionTypeNameMap = | |
| 785 new Map<FunctionType,String>(); | |
| 786 FunctionTypeNamer functionTypeNamer = new FunctionTypeNamer(); | |
| 787 | |
| 788 String getFunctionTypeName(FunctionType functionType) { | |
| 789 return functionTypeNameMap.putIfAbsent(functionType, () { | |
| 790 String proposedName = functionTypeNamer.computeName(functionType); | |
| 791 String freshName = getFreshName(proposedName, usedInstanceNames, | |
| 792 suggestedInstanceNames, ensureSafe: true); | |
| 793 return freshName; | |
| 794 }); | |
| 795 } | |
| 796 | |
| 797 String operatorIsType(DartType type) { | |
| 798 if (type.kind == TypeKind.FUNCTION) { | |
| 799 // TODO(erikcorry): Reduce from $isx to ix when we are minifying. | |
| 800 return '${operatorIsPrefix()}_${getFunctionTypeName(type)}'; | |
| 801 } | |
| 802 return operatorIs(type.element); | |
| 803 } | |
| 804 | |
| 805 String operatorIs(Element element) { | 769 String operatorIs(Element element) { |
| 806 // TODO(erikcorry): Reduce from $isx to ix when we are minifying. | 770 // TODO(erikcorry): Reduce from $isx to ix when we are minifying. |
| 807 return '${operatorIsPrefix()}${getRuntimeTypeName(element)}'; | 771 return '${operatorIsPrefix()}${getRuntimeTypeName(element)}'; |
| 808 } | 772 } |
| 809 | 773 |
| 810 /* | 774 /* |
| 811 * Returns a name that does not clash with reserved JS keywords, | 775 * Returns a name that does not clash with reserved JS keywords, |
| 812 * and also ensures it won't clash with other identifiers. | 776 * and also ensures it won't clash with other identifiers. |
| 813 */ | 777 */ |
| 814 String _safeName(String name, Set<String> reserved) { | 778 String _safeName(String name, Set<String> reserved) { |
| 815 if (reserved.contains(name) || name.startsWith(r'$')) { | 779 if (reserved.contains(name) || name.startsWith(r'$')) { |
| 816 name = '\$$name'; | 780 name = '\$$name'; |
| 817 } | 781 } |
| 818 assert(!reserved.contains(name)); | 782 assert(!reserved.contains(name)); |
| 819 return name; | 783 return name; |
| 820 } | 784 } |
| 821 | 785 |
| 822 String substitutionName(Element element) { | 786 String substitutionName(Element element) { |
| 823 return '${operatorAsPrefix()}${getName(element)}'; | 787 return '${operatorAsPrefix()}${getName(element)}'; |
| 824 } | 788 } |
| 825 | 789 |
| 826 String signatureLocation(FunctionType type) { | |
| 827 ClassElement classElement = Types.getClassContext(type); | |
| 828 if (classElement != null) { | |
| 829 return '${isolateAccess(classElement)}'; | |
| 830 } else { | |
| 831 return '${GLOBAL_OBJECT}'; | |
| 832 } | |
| 833 } | |
| 834 | |
| 835 String signatureName(FunctionType type) { | |
| 836 String signature = '${operatorSignature()}_${getFunctionTypeName(type)}'; | |
| 837 return '${signatureLocation(type)}.$signature'; | |
| 838 } | |
| 839 | |
| 840 String safeName(String name) => _safeName(name, jsReserved); | 790 String safeName(String name) => _safeName(name, jsReserved); |
| 841 String safeVariableName(String name) => _safeName(name, jsVariableReserved); | 791 String safeVariableName(String name) => _safeName(name, jsVariableReserved); |
| 842 | 792 |
| 843 SourceString operatorNameToIdentifier(SourceString name) { | 793 SourceString operatorNameToIdentifier(SourceString name) { |
| 844 if (name == null) return null; | 794 if (name == null) return null; |
| 845 String value = name.stringValue; | 795 String value = name.stringValue; |
| 846 if (value == null) { | 796 if (value == null) { |
| 847 return name; | 797 return name; |
| 848 } else if (value == '==') { | 798 } else if (value == '==') { |
| 849 return const SourceString(r'$eq'); | 799 return const SourceString(r'$eq'); |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 884 } else if (value == '-') { | 834 } else if (value == '-') { |
| 885 return const SourceString(r'$sub'); | 835 return const SourceString(r'$sub'); |
| 886 } else if (value == 'unary-') { | 836 } else if (value == 'unary-') { |
| 887 return const SourceString(r'$negate'); | 837 return const SourceString(r'$negate'); |
| 888 } else { | 838 } else { |
| 889 return name; | 839 return name; |
| 890 } | 840 } |
| 891 } | 841 } |
| 892 } | 842 } |
| 893 | 843 |
| 844 |
| 894 /** | 845 /** |
| 895 * Generator of names for [Constant] values. | 846 * Generator of names for [Constant] values. |
| 896 * | 847 * |
| 897 * The names are stable under perturbations of the source. The name is either a | 848 * The names are stable under perturbations of the source. The name is either a |
| 898 * short sequence of words, if this can be found from the constant, or a type | 849 * short sequence of words, if this can be found from the constant, or a type |
| 899 * followed by a hash tag. | 850 * followed by a hash tag. |
| 900 * | 851 * |
| 901 * List_imX // A List, with hash tag. | 852 * List_imX // A List, with hash tag. |
| 902 * C_Sentinel // const Sentinel(), "C_" added to avoid clash | 853 * C_Sentinel // const Sentinel(), "C_" added to avoid clash |
| 903 * // with class name. | 854 * // with class name. |
| (...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1057 String name = backend.rti.getRawTypeRepresentation(type); | 1008 String name = backend.rti.getRawTypeRepresentation(type); |
| 1058 addIdentifier(name); | 1009 addIdentifier(name); |
| 1059 } | 1010 } |
| 1060 | 1011 |
| 1061 visitInterceptor(InterceptorConstant constant) { | 1012 visitInterceptor(InterceptorConstant constant) { |
| 1062 addRoot(constant.dispatchedType.element.name.slowToString()); | 1013 addRoot(constant.dispatchedType.element.name.slowToString()); |
| 1063 add('methods'); | 1014 add('methods'); |
| 1064 } | 1015 } |
| 1065 } | 1016 } |
| 1066 | 1017 |
| 1018 |
| 1067 /** | 1019 /** |
| 1068 * Generates canonical hash values for [Constant]s. | 1020 * Generates canonical hash values for [Constant]s. |
| 1069 * | 1021 * |
| 1070 * Unfortunately, [Constant.hashCode] is not stable under minor perturbations, | 1022 * Unfortunately, [Constant.hashCode] is not stable under minor perturbations, |
| 1071 * so it can't be used for generating names. This hasher keeps consistency | 1023 * so it can't be used for generating names. This hasher keeps consistency |
| 1072 * between runs by basing hash values of the names of elements, rather than | 1024 * between runs by basing hash values of the names of elements, rather than |
| 1073 * their hashCodes. | 1025 * their hashCodes. |
| 1074 */ | 1026 */ |
| 1075 class ConstantCanonicalHasher implements ConstantVisitor<int> { | 1027 class ConstantCanonicalHasher implements ConstantVisitor<int> { |
| 1076 | 1028 |
| (...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1202 hash = hash ^ (hash >> 6); | 1154 hash = hash ^ (hash >> 6); |
| 1203 return hash; | 1155 return hash; |
| 1204 } | 1156 } |
| 1205 | 1157 |
| 1206 static int _finish(int hash) { | 1158 static int _finish(int hash) { |
| 1207 hash = _MASK & (hash + (((_MASK >> 3) & hash) << 3)); | 1159 hash = _MASK & (hash + (((_MASK >> 3) & hash) << 3)); |
| 1208 hash = hash & (hash >> 11); | 1160 hash = hash & (hash >> 11); |
| 1209 return _MASK & (hash + (((_MASK >> 15) & hash) << 15)); | 1161 return _MASK & (hash + (((_MASK >> 15) & hash) << 15)); |
| 1210 } | 1162 } |
| 1211 } | 1163 } |
| 1212 | |
| 1213 class FunctionTypeNamer extends DartTypeVisitor { | |
| 1214 StringBuffer sb; | |
| 1215 | |
| 1216 String computeName(DartType type) { | |
| 1217 sb = new StringBuffer(); | |
| 1218 visit(type); | |
| 1219 return sb.toString(); | |
| 1220 } | |
| 1221 | |
| 1222 visit(DartType type) { | |
| 1223 type.accept(this, null); | |
| 1224 } | |
| 1225 | |
| 1226 visitType(DartType type, _) { | |
| 1227 sb.write(type.name.slowToString()); | |
| 1228 } | |
| 1229 | |
| 1230 visitFunctionType(FunctionType type, _) { | |
| 1231 visit(type.returnType); | |
| 1232 sb.write('_'); | |
| 1233 for (Link<DartType> link = type.parameterTypes; | |
| 1234 !link.isEmpty; | |
| 1235 link = link.tail) { | |
| 1236 sb.write('_'); | |
| 1237 visit(link.head); | |
| 1238 } | |
| 1239 bool first = false; | |
| 1240 for (Link<DartType> link = type.optionalParameterTypes; | |
| 1241 !link.isEmpty; | |
| 1242 link = link.tail) { | |
| 1243 if (!first) { | |
| 1244 sb.write('_'); | |
| 1245 } | |
| 1246 sb.write('_'); | |
| 1247 visit(link.head); | |
| 1248 first = true; | |
| 1249 } | |
| 1250 if (!type.namedParameterTypes.isEmpty) { | |
| 1251 first = false; | |
| 1252 for (Link<DartType> link = type.namedParameterTypes; | |
| 1253 !link.isEmpty; | |
| 1254 link = link.tail) { | |
| 1255 if (!first) { | |
| 1256 sb.write('_'); | |
| 1257 } | |
| 1258 sb.write('_'); | |
| 1259 visit(link.head); | |
| 1260 first = true; | |
| 1261 } | |
| 1262 } | |
| 1263 } | |
| 1264 } | |
| OLD | NEW |