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 * Names are generated through three stages: | 10 * Names are generated through three stages: |
(...skipping 439 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
450 constantHasher = new ConstantCanonicalHasher(compiler), | 450 constantHasher = new ConstantCanonicalHasher(compiler), |
451 functionTypeNamer = new FunctionTypeNamer(compiler) { | 451 functionTypeNamer = new FunctionTypeNamer(compiler) { |
452 _literalAsyncPrefix = new StringBackedName(asyncPrefix); | 452 _literalAsyncPrefix = new StringBackedName(asyncPrefix); |
453 _literalGetterPrefix = new StringBackedName(getterPrefix); | 453 _literalGetterPrefix = new StringBackedName(getterPrefix); |
454 _literalSetterPrefix = new StringBackedName(setterPrefix); | 454 _literalSetterPrefix = new StringBackedName(setterPrefix); |
455 _literalLazyGetterPrefix = new StringBackedName(lazyGetterPrefix); | 455 _literalLazyGetterPrefix = new StringBackedName(lazyGetterPrefix); |
456 } | 456 } |
457 | 457 |
458 JavaScriptBackend get backend => compiler.backend; | 458 JavaScriptBackend get backend => compiler.backend; |
459 | 459 |
| 460 BackendHelpers get helpers => backend.helpers; |
| 461 |
460 DiagnosticReporter get reporter => compiler.reporter; | 462 DiagnosticReporter get reporter => compiler.reporter; |
461 | 463 |
462 CoreClasses get coreClasses => compiler.coreClasses; | 464 CoreClasses get coreClasses => compiler.coreClasses; |
463 | 465 |
464 String get deferredTypesName => 'deferredTypes'; | 466 String get deferredTypesName => 'deferredTypes'; |
465 String get isolateName => 'Isolate'; | 467 String get isolateName => 'Isolate'; |
466 String get isolatePropertiesName => r'$isolateProperties'; | 468 String get isolatePropertiesName => r'$isolateProperties'; |
467 jsAst.Name get noSuchMethodName => invocationName(Selectors.noSuchMethod_); | 469 jsAst.Name get noSuchMethodName => invocationName(Selectors.noSuchMethod_); |
468 | 470 |
469 /** | 471 /** |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
501 return asName(functionTypeVoidReturnTag); | 503 return asName(functionTypeVoidReturnTag); |
502 case JsGetName.FUNCTION_TYPE_RETURN_TYPE_TAG: | 504 case JsGetName.FUNCTION_TYPE_RETURN_TYPE_TAG: |
503 return asName(functionTypeReturnTypeTag); | 505 return asName(functionTypeReturnTypeTag); |
504 case JsGetName.FUNCTION_TYPE_REQUIRED_PARAMETERS_TAG: | 506 case JsGetName.FUNCTION_TYPE_REQUIRED_PARAMETERS_TAG: |
505 return asName(functionTypeRequiredParametersTag); | 507 return asName(functionTypeRequiredParametersTag); |
506 case JsGetName.FUNCTION_TYPE_OPTIONAL_PARAMETERS_TAG: | 508 case JsGetName.FUNCTION_TYPE_OPTIONAL_PARAMETERS_TAG: |
507 return asName(functionTypeOptionalParametersTag); | 509 return asName(functionTypeOptionalParametersTag); |
508 case JsGetName.FUNCTION_TYPE_NAMED_PARAMETERS_TAG: | 510 case JsGetName.FUNCTION_TYPE_NAMED_PARAMETERS_TAG: |
509 return asName(functionTypeNamedParametersTag); | 511 return asName(functionTypeNamedParametersTag); |
510 case JsGetName.IS_INDEXABLE_FIELD_NAME: | 512 case JsGetName.IS_INDEXABLE_FIELD_NAME: |
511 Element cls = backend.findHelper('JavaScriptIndexingBehavior'); | 513 return operatorIs(helpers.jsIndexingBehaviorInterface); |
512 return operatorIs(cls); | |
513 case JsGetName.NULL_CLASS_TYPE_NAME: | 514 case JsGetName.NULL_CLASS_TYPE_NAME: |
514 return runtimeTypeName(coreClasses.nullClass); | 515 return runtimeTypeName(coreClasses.nullClass); |
515 case JsGetName.OBJECT_CLASS_TYPE_NAME: | 516 case JsGetName.OBJECT_CLASS_TYPE_NAME: |
516 return runtimeTypeName(coreClasses.objectClass); | 517 return runtimeTypeName(coreClasses.objectClass); |
517 case JsGetName.FUNCTION_CLASS_TYPE_NAME: | 518 case JsGetName.FUNCTION_CLASS_TYPE_NAME: |
518 return runtimeTypeName(coreClasses.functionClass); | 519 return runtimeTypeName(coreClasses.functionClass); |
519 default: | 520 default: |
520 reporter.reportErrorMessage( | 521 reporter.reportErrorMessage( |
521 node, | 522 node, |
522 MessageKind.GENERIC, | 523 MessageKind.GENERIC, |
(...skipping 678 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1201 name = disambiguated; | 1202 name = disambiguated; |
1202 } else { | 1203 } else { |
1203 name = element.name; | 1204 name = element.name; |
1204 } | 1205 } |
1205 return name; | 1206 return name; |
1206 } | 1207 } |
1207 | 1208 |
1208 String suffixForGetInterceptor(Iterable<ClassElement> classes) { | 1209 String suffixForGetInterceptor(Iterable<ClassElement> classes) { |
1209 String abbreviate(ClassElement cls) { | 1210 String abbreviate(ClassElement cls) { |
1210 if (cls == coreClasses.objectClass) return "o"; | 1211 if (cls == coreClasses.objectClass) return "o"; |
1211 if (cls == backend.jsStringClass) return "s"; | 1212 if (cls == helpers.jsStringClass) return "s"; |
1212 if (cls == backend.jsArrayClass) return "a"; | 1213 if (cls == helpers.jsArrayClass) return "a"; |
1213 if (cls == backend.jsDoubleClass) return "d"; | 1214 if (cls == helpers.jsDoubleClass) return "d"; |
1214 if (cls == backend.jsIntClass) return "i"; | 1215 if (cls == helpers.jsIntClass) return "i"; |
1215 if (cls == backend.jsNumberClass) return "n"; | 1216 if (cls == helpers.jsNumberClass) return "n"; |
1216 if (cls == backend.jsNullClass) return "u"; | 1217 if (cls == helpers.jsNullClass) return "u"; |
1217 if (cls == backend.jsBoolClass) return "b"; | 1218 if (cls == helpers.jsBoolClass) return "b"; |
1218 if (cls == backend.jsInterceptorClass) return "I"; | 1219 if (cls == helpers.jsInterceptorClass) return "I"; |
1219 return cls.name; | 1220 return cls.name; |
1220 } | 1221 } |
1221 List<String> names = classes | 1222 List<String> names = classes |
1222 .where((cls) => !backend.isNativeOrExtendsNative(cls)) | 1223 .where((cls) => !backend.isNativeOrExtendsNative(cls)) |
1223 .map(abbreviate) | 1224 .map(abbreviate) |
1224 .toList(); | 1225 .toList(); |
1225 // There is one dispatch mechanism for all native classes. | 1226 // There is one dispatch mechanism for all native classes. |
1226 if (classes.any((cls) => backend.isNativeOrExtendsNative(cls))) { | 1227 if (classes.any((cls) => backend.isNativeOrExtendsNative(cls))) { |
1227 names.add("x"); | 1228 names.add("x"); |
1228 } | 1229 } |
1229 // Sort the names of the classes after abbreviating them to ensure | 1230 // Sort the names of the classes after abbreviating them to ensure |
1230 // the suffix is stable and predictable for the suggested names. | 1231 // the suffix is stable and predictable for the suggested names. |
1231 names.sort(); | 1232 names.sort(); |
1232 return names.join(); | 1233 return names.join(); |
1233 } | 1234 } |
1234 | 1235 |
1235 /// Property name used for `getInterceptor` or one of its specializations. | 1236 /// Property name used for `getInterceptor` or one of its specializations. |
1236 jsAst.Name nameForGetInterceptor(Iterable<ClassElement> classes) { | 1237 jsAst.Name nameForGetInterceptor(Iterable<ClassElement> classes) { |
1237 FunctionElement getInterceptor = backend.getInterceptorMethod; | 1238 FunctionElement getInterceptor = helpers.getInterceptorMethod; |
1238 if (classes.contains(backend.jsInterceptorClass)) { | 1239 if (classes.contains(helpers.jsInterceptorClass)) { |
1239 // If the base Interceptor class is in the set of intercepted classes, we | 1240 // If the base Interceptor class is in the set of intercepted classes, we |
1240 // need to go through the generic getInterceptorMethod, since any subclass | 1241 // need to go through the generic getInterceptorMethod, since any subclass |
1241 // of the base Interceptor could match. | 1242 // of the base Interceptor could match. |
1242 // The unspecialized getInterceptor method can also be accessed through | 1243 // The unspecialized getInterceptor method can also be accessed through |
1243 // its element, so we treat this as a user-space global instead of an | 1244 // its element, so we treat this as a user-space global instead of an |
1244 // internal global. | 1245 // internal global. |
1245 return _disambiguateGlobal(getInterceptor); | 1246 return _disambiguateGlobal(getInterceptor); |
1246 } | 1247 } |
1247 String suffix = suffixForGetInterceptor(classes); | 1248 String suffix = suffixForGetInterceptor(classes); |
1248 return _disambiguateInternalGlobal("${getInterceptor.name}\$$suffix"); | 1249 return _disambiguateInternalGlobal("${getInterceptor.name}\$$suffix"); |
1249 } | 1250 } |
1250 | 1251 |
1251 /// Property name used for the one-shot interceptor method for the given | 1252 /// Property name used for the one-shot interceptor method for the given |
1252 /// [selector] and return-type specialization. | 1253 /// [selector] and return-type specialization. |
1253 jsAst.Name nameForGetOneShotInterceptor(Selector selector, | 1254 jsAst.Name nameForGetOneShotInterceptor(Selector selector, |
1254 Iterable<ClassElement> classes) { | 1255 Iterable<ClassElement> classes) { |
1255 // The one-shot name is a global name derived from the invocation name. To | 1256 // The one-shot name is a global name derived from the invocation name. To |
1256 // avoid instability we would like the names to be unique and not clash with | 1257 // avoid instability we would like the names to be unique and not clash with |
1257 // other global names. | 1258 // other global names. |
1258 jsAst.Name root = invocationName(selector); | 1259 jsAst.Name root = invocationName(selector); |
1259 | 1260 |
1260 if (classes.contains(backend.jsInterceptorClass)) { | 1261 if (classes.contains(helpers.jsInterceptorClass)) { |
1261 // If the base Interceptor class is in the set of intercepted classes, | 1262 // If the base Interceptor class is in the set of intercepted classes, |
1262 // this is the most general specialization which uses the generic | 1263 // this is the most general specialization which uses the generic |
1263 // getInterceptor method. | 1264 // getInterceptor method. |
1264 // TODO(sra): Find a way to get the simple name when Object is not in the | 1265 // TODO(sra): Find a way to get the simple name when Object is not in the |
1265 // set of classes for most general variant, e.g. "$lt$n" could be "$lt". | 1266 // set of classes for most general variant, e.g. "$lt$n" could be "$lt". |
1266 return new CompoundName([root, _literalDollar]); | 1267 return new CompoundName([root, _literalDollar]); |
1267 } else { | 1268 } else { |
1268 String suffix = suffixForGetInterceptor(classes); | 1269 String suffix = suffixForGetInterceptor(classes); |
1269 return new CompoundName([root, _literalDollar, | 1270 return new CompoundName([root, _literalDollar, |
1270 new StringBackedName(suffix)]); | 1271 new StringBackedName(suffix)]); |
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1360 !element.isTypedef && | 1361 !element.isTypedef && |
1361 !element.isConstructor && | 1362 !element.isConstructor && |
1362 !element.isFunction && | 1363 !element.isFunction && |
1363 !element.isLibrary; | 1364 !element.isLibrary; |
1364 } | 1365 } |
1365 | 1366 |
1366 /// Returns [staticStateHolder] or one of [reservedGlobalObjectNames]. | 1367 /// Returns [staticStateHolder] or one of [reservedGlobalObjectNames]. |
1367 String globalObjectFor(Element element) { | 1368 String globalObjectFor(Element element) { |
1368 if (_isPropertyOfStaticStateHolder(element)) return staticStateHolder; | 1369 if (_isPropertyOfStaticStateHolder(element)) return staticStateHolder; |
1369 LibraryElement library = element.library; | 1370 LibraryElement library = element.library; |
1370 if (library == backend.interceptorsLibrary) return 'J'; | 1371 if (library == helpers.interceptorsLibrary) return 'J'; |
1371 if (library.isInternalLibrary) return 'H'; | 1372 if (library.isInternalLibrary) return 'H'; |
1372 if (library.isPlatformLibrary) { | 1373 if (library.isPlatformLibrary) { |
1373 if ('${library.canonicalUri}' == 'dart:html') return 'W'; | 1374 if ('${library.canonicalUri}' == 'dart:html') return 'W'; |
1374 return 'P'; | 1375 return 'P'; |
1375 } | 1376 } |
1376 return userGlobalObjects[ | 1377 return userGlobalObjects[ |
1377 library.libraryOrScriptName.hashCode % userGlobalObjects.length]; | 1378 library.libraryOrScriptName.hashCode % userGlobalObjects.length]; |
1378 } | 1379 } |
1379 | 1380 |
1380 jsAst.Name deriveLazyInitializerName(jsAst.Name name) { | 1381 jsAst.Name deriveLazyInitializerName(jsAst.Name name) { |
(...skipping 644 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2025 } | 2026 } |
2026 } | 2027 } |
2027 } | 2028 } |
2028 } | 2029 } |
2029 | 2030 |
2030 enum NamingScope { | 2031 enum NamingScope { |
2031 global, | 2032 global, |
2032 instance, | 2033 instance, |
2033 constant | 2034 constant |
2034 } | 2035 } |
OLD | NEW |