| 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 library js_backend.namer; | 5 library js_backend.namer; |
| 6 | 6 |
| 7 import 'dart:collection' show HashMap; | 7 import 'dart:collection' show HashMap; |
| 8 | 8 |
| 9 import 'package:js_runtime/shared/embedded_names.dart' show JsGetName; | 9 import 'package:js_runtime/shared/embedded_names.dart' show JsGetName; |
| 10 | 10 |
| (...skipping 1161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1172 String _sanitizeForNatives(String name) { | 1172 String _sanitizeForNatives(String name) { |
| 1173 if (!name.contains(r'$')) { | 1173 if (!name.contains(r'$')) { |
| 1174 // Prepend $$. The result must not coincide with an annotated name. | 1174 // Prepend $$. The result must not coincide with an annotated name. |
| 1175 name = '\$\$$name'; | 1175 name = '\$\$$name'; |
| 1176 } | 1176 } |
| 1177 return name; | 1177 return name; |
| 1178 } | 1178 } |
| 1179 | 1179 |
| 1180 /** | 1180 /** |
| 1181 * Returns a proposed name for the given top-level or static element. | 1181 * Returns a proposed name for the given top-level or static element. |
| 1182 * The returned id is guaranteed to be a valid JS-id. | 1182 * The returned id is guaranteed to be a valid JavaScript identifier. |
| 1183 */ | 1183 */ |
| 1184 String _proposeNameForGlobal(Element element) { | 1184 String _proposeNameForGlobal(Element element) { |
| 1185 assert(!element.isInstanceMember); | 1185 assert(!element.isInstanceMember); |
| 1186 String name; | |
| 1187 if (element.isGenerativeConstructor) { | 1186 if (element.isGenerativeConstructor) { |
| 1188 name = "${element.enclosingClass.name}\$" | 1187 return '${element.enclosingClass.name}\$${element.name}'; |
| 1189 "${element.name}"; | 1188 } |
| 1190 } else if (element.isFactoryConstructor) { | 1189 if (element.isFactoryConstructor) { |
| 1191 // TODO(johnniwinther): Change factory name encoding as to not include | 1190 // TODO(johnniwinther): Change factory name encoding as to not include |
| 1192 // the class-name twice. | 1191 // the class-name twice. |
| 1193 String className = element.enclosingClass.name; | 1192 String className = element.enclosingClass.name; |
| 1194 name = '${className}_${Elements.reconstructConstructorName(element)}'; | 1193 return '${className}_${Elements.reconstructConstructorName(element)}'; |
| 1195 } else if (Elements.isStaticOrTopLevel(element)) { | 1194 } |
| 1195 if (Elements.isStaticOrTopLevel(element)) { |
| 1196 if (element.isClassMember) { | 1196 if (element.isClassMember) { |
| 1197 ClassElement enclosingClass = element.enclosingClass; | 1197 ClassElement enclosingClass = element.enclosingClass; |
| 1198 name = "${enclosingClass.name}_" | 1198 return '${enclosingClass.name}_${element.name}'; |
| 1199 "${element.name}"; | |
| 1200 } else { | |
| 1201 name = element.name.replaceAll('+', '_'); | |
| 1202 } | 1199 } |
| 1203 } else if (element.isLibrary) { | 1200 return element.name.replaceAll('+', '_'); |
| 1204 LibraryElement library = element; | 1201 } |
| 1205 name = libraryLongNames[library]; | 1202 if (element.isLibrary) { |
| 1206 if (name != null) return name; | 1203 return _proposeNameForLibrary(element); |
| 1207 name = library.libraryOrScriptName; | 1204 } |
| 1208 if (name.contains('.')) { | 1205 return element.name; |
| 1209 // For libraries that have a library tag, we use the last part | 1206 } |
| 1210 // of the fully qualified name as their base name. For all other | 1207 |
| 1211 // libraries, we use the first part of their filename. | 1208 /** |
| 1212 name = library.hasLibraryName | 1209 * Returns a proposed name for the given [LibraryElement]. |
| 1213 ? name.substring(name.lastIndexOf('.') + 1) | 1210 * The returned id is guaranteed to be a valid JavaScript identifier. |
| 1214 : name.substring(0, name.indexOf('.')); | 1211 */ |
| 1212 // TODO(sra): Pre-process libraries to assign [libraryLongNames] in a way that |
| 1213 // is independent of the order of calls to namer. |
| 1214 String _proposeNameForLibrary(LibraryElement library) { |
| 1215 String name = libraryLongNames[library]; |
| 1216 if (name != null) return name; |
| 1217 // Use the 'file' name, e.g. "package:expect/expect.dart" -> "expect" |
| 1218 name = library.canonicalUri.path; |
| 1219 name = name.substring(name.lastIndexOf('/') + 1); |
| 1220 if (name.contains('.')) { |
| 1221 // Drop file extension. |
| 1222 name = name.substring(0, name.lastIndexOf('.')); |
| 1223 } |
| 1224 // The filename based name can contain all kinds of nasty characters. Make |
| 1225 // sure it is an identifier. |
| 1226 if (!IDENTIFIER.hasMatch(name)) { |
| 1227 String replacer(Match match) { |
| 1228 String s = match[0]; |
| 1229 if (s == '.') return '_'; |
| 1230 return s.codeUnitAt(0).toRadixString(16); |
| 1215 } | 1231 } |
| 1216 // The filename based name can contain all kinds of nasty characters. Make | 1232 |
| 1217 // sure it is an identifier. | 1233 name = name.replaceAllMapped(NON_IDENTIFIER_CHAR, replacer); |
| 1218 if (!IDENTIFIER.hasMatch(name)) { | 1234 if (!IDENTIFIER.hasMatch(name)) { |
| 1219 name = name.replaceAllMapped(NON_IDENTIFIER_CHAR, | 1235 // e.g. starts with digit. |
| 1220 (match) => match[0].codeUnitAt(0).toRadixString(16)); | 1236 name = 'lib_$name'; |
| 1221 if (!IDENTIFIER.hasMatch(name)) { | |
| 1222 // e.g. starts with digit. | |
| 1223 name = 'lib_$name'; | |
| 1224 } | |
| 1225 } | 1237 } |
| 1226 // Names constructed based on a libary name will be further disambiguated. | |
| 1227 // However, as names from the same libary should have the same libary | |
| 1228 // name part, we disambiguate the library name here. | |
| 1229 String disambiguated = name; | |
| 1230 for (int c = 0; libraryLongNames.containsValue(disambiguated); c++) { | |
| 1231 disambiguated = "$name$c"; | |
| 1232 } | |
| 1233 libraryLongNames[library] = disambiguated; | |
| 1234 name = disambiguated; | |
| 1235 } else { | |
| 1236 name = element.name; | |
| 1237 } | 1238 } |
| 1238 return name; | 1239 // Names constructed based on a libary name will be further disambiguated. |
| 1240 // However, as names from the same libary should have the same library |
| 1241 // name part, we disambiguate the library name here. |
| 1242 String disambiguated = name; |
| 1243 for (int c = 0; libraryLongNames.containsValue(disambiguated); c++) { |
| 1244 disambiguated = "$name$c"; |
| 1245 } |
| 1246 libraryLongNames[library] = disambiguated; |
| 1247 return disambiguated; |
| 1239 } | 1248 } |
| 1240 | 1249 |
| 1241 String suffixForGetInterceptor(Iterable<ClassElement> classes) { | 1250 String suffixForGetInterceptor(Iterable<ClassElement> classes) { |
| 1242 String abbreviate(ClassElement cls) { | 1251 String abbreviate(ClassElement cls) { |
| 1243 if (cls == coreClasses.objectClass) return "o"; | 1252 if (cls == coreClasses.objectClass) return "o"; |
| 1244 if (cls == helpers.jsStringClass) return "s"; | 1253 if (cls == helpers.jsStringClass) return "s"; |
| 1245 if (cls == helpers.jsArrayClass) return "a"; | 1254 if (cls == helpers.jsArrayClass) return "a"; |
| 1246 if (cls == helpers.jsDoubleClass) return "d"; | 1255 if (cls == helpers.jsDoubleClass) return "d"; |
| 1247 if (cls == helpers.jsIntClass) return "i"; | 1256 if (cls == helpers.jsIntClass) return "i"; |
| 1248 if (cls == helpers.jsNumberClass) return "n"; | 1257 if (cls == helpers.jsNumberClass) return "n"; |
| (...skipping 839 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2088 void addSuggestion(String original, String suggestion) { | 2097 void addSuggestion(String original, String suggestion) { |
| 2089 assert(!_suggestedNames.containsKey(original)); | 2098 assert(!_suggestedNames.containsKey(original)); |
| 2090 _suggestedNames[original] = suggestion; | 2099 _suggestedNames[original] = suggestion; |
| 2091 } | 2100 } |
| 2092 | 2101 |
| 2093 bool hasSuggestion(String original) => _suggestedNames.containsKey(original); | 2102 bool hasSuggestion(String original) => _suggestedNames.containsKey(original); |
| 2094 bool isSuggestion(String candidate) { | 2103 bool isSuggestion(String candidate) { |
| 2095 return _suggestedNames.containsValue(candidate); | 2104 return _suggestedNames.containsValue(candidate); |
| 2096 } | 2105 } |
| 2097 } | 2106 } |
| OLD | NEW |