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 |
11 import '../closure.dart'; | 11 import '../closure.dart'; |
12 import '../common.dart'; | 12 import '../common.dart'; |
13 import '../common/names.dart' show Identifiers, Selectors; | 13 import '../common/names.dart' show Identifiers, Selectors; |
14 import '../constants/values.dart'; | 14 import '../constants/values.dart'; |
15 import '../common_elements.dart' show CommonElements; | 15 import '../common_elements.dart' show CommonElements; |
16 import '../diagnostics/invariant.dart' show DEBUG_MODE; | 16 import '../diagnostics/invariant.dart' show DEBUG_MODE; |
17 import '../elements/elements.dart'; | 17 import '../elements/elements.dart'; |
18 import '../elements/entities.dart'; | 18 import '../elements/entities.dart'; |
19 import '../elements/resolution_types.dart'; | 19 import '../elements/resolution_types.dart'; |
20 import '../elements/types.dart'; | 20 import '../elements/types.dart'; |
21 import '../js/js.dart' as jsAst; | 21 import '../js/js.dart' as jsAst; |
22 import '../tree/tree.dart'; | 22 import '../tree/tree.dart'; |
23 import '../universe/call_structure.dart' show CallStructure; | 23 import '../universe/call_structure.dart' show CallStructure; |
24 import '../universe/selector.dart' show Selector, SelectorKind; | 24 import '../universe/selector.dart' show Selector, SelectorKind; |
25 import '../universe/world_builder.dart' show CodegenWorldBuilder; | 25 import '../universe/world_builder.dart' show CodegenWorldBuilder; |
26 import 'package:front_end/src/fasta/scanner/characters.dart'; | 26 import 'package:front_end/src/fasta/scanner/characters.dart'; |
27 import '../util/util.dart'; | 27 import '../util/util.dart'; |
28 import '../world.dart' show ClosedWorld; | 28 import '../world.dart' show ClosedWorld; |
29 import 'backend.dart'; | 29 import 'backend.dart'; |
30 import 'backend_helpers.dart'; | |
31 import 'constant_system_javascript.dart'; | 30 import 'constant_system_javascript.dart'; |
32 import 'native_data.dart'; | 31 import 'native_data.dart'; |
33 | 32 |
34 part 'field_naming_mixin.dart'; | 33 part 'field_naming_mixin.dart'; |
35 part 'frequency_namer.dart'; | 34 part 'frequency_namer.dart'; |
36 part 'minify_namer.dart'; | 35 part 'minify_namer.dart'; |
37 part 'namer_names.dart'; | 36 part 'namer_names.dart'; |
38 | 37 |
39 /** | 38 /** |
40 * Assigns JavaScript identifiers to Dart variables, class-names and members. | 39 * Assigns JavaScript identifiers to Dart variables, class-names and members. |
(...skipping 440 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
481 jsAst.Name _rtiFieldJsName; | 480 jsAst.Name _rtiFieldJsName; |
482 jsAst.Name get rtiFieldJsName => | 481 jsAst.Name get rtiFieldJsName => |
483 _rtiFieldJsName ??= new StringBackedName(rtiName); | 482 _rtiFieldJsName ??= new StringBackedName(rtiName); |
484 | 483 |
485 // Name of property in a class description for the native dispatch metadata. | 484 // Name of property in a class description for the native dispatch metadata. |
486 final String nativeSpecProperty = '%'; | 485 final String nativeSpecProperty = '%'; |
487 | 486 |
488 static final RegExp IDENTIFIER = new RegExp(r'^[A-Za-z_$][A-Za-z0-9_$]*$'); | 487 static final RegExp IDENTIFIER = new RegExp(r'^[A-Za-z_$][A-Za-z0-9_$]*$'); |
489 static final RegExp NON_IDENTIFIER_CHAR = new RegExp(r'[^A-Za-z_0-9$]'); | 488 static final RegExp NON_IDENTIFIER_CHAR = new RegExp(r'[^A-Za-z_0-9$]'); |
490 | 489 |
491 final BackendHelpers _helpers; | |
492 final NativeData _nativeData; | 490 final NativeData _nativeData; |
493 final ClosedWorld _closedWorld; | 491 final ClosedWorld _closedWorld; |
494 final CodegenWorldBuilder _codegenWorldBuilder; | 492 final CodegenWorldBuilder _codegenWorldBuilder; |
495 | 493 |
496 RuntimeTypesEncoder _rtiEncoder; | 494 RuntimeTypesEncoder _rtiEncoder; |
497 RuntimeTypesEncoder get rtiEncoder { | 495 RuntimeTypesEncoder get rtiEncoder { |
498 assert(invariant(NO_LOCATION_SPANNABLE, _rtiEncoder != null, | 496 assert(invariant(NO_LOCATION_SPANNABLE, _rtiEncoder != null, |
499 message: "Namer.rtiEncoder has not been set.")); | 497 message: "Namer.rtiEncoder has not been set.")); |
500 return _rtiEncoder; | 498 return _rtiEncoder; |
501 } | 499 } |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
554 | 552 |
555 final Map<String, String> suggestedGlobalNames = <String, String>{}; | 553 final Map<String, String> suggestedGlobalNames = <String, String>{}; |
556 final Map<String, String> suggestedInstanceNames = <String, String>{}; | 554 final Map<String, String> suggestedInstanceNames = <String, String>{}; |
557 | 555 |
558 /// Used to store unique keys for library names. Keys are not used as names, | 556 /// Used to store unique keys for library names. Keys are not used as names, |
559 /// nor are they visible in the output. The only serve as an internal | 557 /// nor are they visible in the output. The only serve as an internal |
560 /// key into maps. | 558 /// key into maps. |
561 final Map<LibraryElement, String> _libraryKeys = | 559 final Map<LibraryElement, String> _libraryKeys = |
562 new HashMap<LibraryElement, String>(); | 560 new HashMap<LibraryElement, String>(); |
563 | 561 |
564 Namer(this._helpers, this._nativeData, this._closedWorld, | 562 Namer(this._nativeData, this._closedWorld, this._codegenWorldBuilder) { |
565 this._codegenWorldBuilder) { | |
566 _literalAsyncPrefix = new StringBackedName(asyncPrefix); | 563 _literalAsyncPrefix = new StringBackedName(asyncPrefix); |
567 _literalGetterPrefix = new StringBackedName(getterPrefix); | 564 _literalGetterPrefix = new StringBackedName(getterPrefix); |
568 _literalSetterPrefix = new StringBackedName(setterPrefix); | 565 _literalSetterPrefix = new StringBackedName(setterPrefix); |
569 _literalLazyGetterPrefix = new StringBackedName(lazyGetterPrefix); | 566 _literalLazyGetterPrefix = new StringBackedName(lazyGetterPrefix); |
570 } | 567 } |
571 | 568 |
572 CommonElements get _commonElements => _closedWorld.commonElements; | 569 CommonElements get _commonElements => _closedWorld.commonElements; |
573 | 570 |
574 String get deferredTypesName => 'deferredTypes'; | 571 String get deferredTypesName => 'deferredTypes'; |
575 String get isolateName => 'Isolate'; | 572 String get isolateName => 'Isolate'; |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
639 return asName(functionTypeVoidReturnTag); | 636 return asName(functionTypeVoidReturnTag); |
640 case JsGetName.FUNCTION_TYPE_RETURN_TYPE_TAG: | 637 case JsGetName.FUNCTION_TYPE_RETURN_TYPE_TAG: |
641 return asName(functionTypeReturnTypeTag); | 638 return asName(functionTypeReturnTypeTag); |
642 case JsGetName.FUNCTION_TYPE_REQUIRED_PARAMETERS_TAG: | 639 case JsGetName.FUNCTION_TYPE_REQUIRED_PARAMETERS_TAG: |
643 return asName(functionTypeRequiredParametersTag); | 640 return asName(functionTypeRequiredParametersTag); |
644 case JsGetName.FUNCTION_TYPE_OPTIONAL_PARAMETERS_TAG: | 641 case JsGetName.FUNCTION_TYPE_OPTIONAL_PARAMETERS_TAG: |
645 return asName(functionTypeOptionalParametersTag); | 642 return asName(functionTypeOptionalParametersTag); |
646 case JsGetName.FUNCTION_TYPE_NAMED_PARAMETERS_TAG: | 643 case JsGetName.FUNCTION_TYPE_NAMED_PARAMETERS_TAG: |
647 return asName(functionTypeNamedParametersTag); | 644 return asName(functionTypeNamedParametersTag); |
648 case JsGetName.IS_INDEXABLE_FIELD_NAME: | 645 case JsGetName.IS_INDEXABLE_FIELD_NAME: |
649 return operatorIs(_helpers.jsIndexingBehaviorInterface); | 646 return operatorIs(_commonElements.jsIndexingBehaviorInterface); |
650 case JsGetName.NULL_CLASS_TYPE_NAME: | 647 case JsGetName.NULL_CLASS_TYPE_NAME: |
651 ClassElement nullClass = _commonElements.nullClass; | 648 ClassElement nullClass = _commonElements.nullClass; |
652 return runtimeTypeName(nullClass); | 649 return runtimeTypeName(nullClass); |
653 case JsGetName.OBJECT_CLASS_TYPE_NAME: | 650 case JsGetName.OBJECT_CLASS_TYPE_NAME: |
654 ClassElement objectClass = _commonElements.objectClass; | 651 ClassElement objectClass = _commonElements.objectClass; |
655 return runtimeTypeName(objectClass); | 652 return runtimeTypeName(objectClass); |
656 case JsGetName.FUNCTION_CLASS_TYPE_NAME: | 653 case JsGetName.FUNCTION_CLASS_TYPE_NAME: |
657 ClassElement functionClass = _commonElements.functionClass; | 654 ClassElement functionClass = _commonElements.functionClass; |
658 return runtimeTypeName(functionClass); | 655 return runtimeTypeName(functionClass); |
659 default: | 656 default: |
(...skipping 651 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1311 for (int c = 0; libraryLongNames.containsValue(disambiguated); c++) { | 1308 for (int c = 0; libraryLongNames.containsValue(disambiguated); c++) { |
1312 disambiguated = "$name$c"; | 1309 disambiguated = "$name$c"; |
1313 } | 1310 } |
1314 libraryLongNames[library] = disambiguated; | 1311 libraryLongNames[library] = disambiguated; |
1315 return disambiguated; | 1312 return disambiguated; |
1316 } | 1313 } |
1317 | 1314 |
1318 String suffixForGetInterceptor(Iterable<ClassEntity> classes) { | 1315 String suffixForGetInterceptor(Iterable<ClassEntity> classes) { |
1319 String abbreviate(ClassElement cls) { | 1316 String abbreviate(ClassElement cls) { |
1320 if (cls == _commonElements.objectClass) return "o"; | 1317 if (cls == _commonElements.objectClass) return "o"; |
1321 if (cls == _helpers.jsStringClass) return "s"; | 1318 if (cls == _commonElements.jsStringClass) return "s"; |
1322 if (cls == _helpers.jsArrayClass) return "a"; | 1319 if (cls == _commonElements.jsArrayClass) return "a"; |
1323 if (cls == _helpers.jsDoubleClass) return "d"; | 1320 if (cls == _commonElements.jsDoubleClass) return "d"; |
1324 if (cls == _helpers.jsIntClass) return "i"; | 1321 if (cls == _commonElements.jsIntClass) return "i"; |
1325 if (cls == _helpers.jsNumberClass) return "n"; | 1322 if (cls == _commonElements.jsNumberClass) return "n"; |
1326 if (cls == _helpers.jsNullClass) return "u"; | 1323 if (cls == _commonElements.jsNullClass) return "u"; |
1327 if (cls == _helpers.jsBoolClass) return "b"; | 1324 if (cls == _commonElements.jsBoolClass) return "b"; |
1328 if (cls == _helpers.jsInterceptorClass) return "I"; | 1325 if (cls == _commonElements.jsInterceptorClass) return "I"; |
1329 return cls.name; | 1326 return cls.name; |
1330 } | 1327 } |
1331 | 1328 |
1332 List<String> names = classes | 1329 List<String> names = classes |
1333 .where((cls) => !_nativeData.isNativeOrExtendsNative(cls)) | 1330 .where((cls) => !_nativeData.isNativeOrExtendsNative(cls)) |
1334 .map(abbreviate) | 1331 .map(abbreviate) |
1335 .toList(); | 1332 .toList(); |
1336 // There is one dispatch mechanism for all native classes. | 1333 // There is one dispatch mechanism for all native classes. |
1337 if (classes.any((cls) => _nativeData.isNativeOrExtendsNative(cls))) { | 1334 if (classes.any((cls) => _nativeData.isNativeOrExtendsNative(cls))) { |
1338 names.add("x"); | 1335 names.add("x"); |
1339 } | 1336 } |
1340 // Sort the names of the classes after abbreviating them to ensure | 1337 // Sort the names of the classes after abbreviating them to ensure |
1341 // the suffix is stable and predictable for the suggested names. | 1338 // the suffix is stable and predictable for the suggested names. |
1342 names.sort(); | 1339 names.sort(); |
1343 return names.join(); | 1340 return names.join(); |
1344 } | 1341 } |
1345 | 1342 |
1346 /// Property name used for `getInterceptor` or one of its specializations. | 1343 /// Property name used for `getInterceptor` or one of its specializations. |
1347 jsAst.Name nameForGetInterceptor(Iterable<ClassEntity> classes) { | 1344 jsAst.Name nameForGetInterceptor(Iterable<ClassEntity> classes) { |
1348 MethodElement getInterceptor = _helpers.getInterceptorMethod; | 1345 MethodElement getInterceptor = _commonElements.getInterceptorMethod; |
1349 if (classes.contains(_helpers.jsInterceptorClass)) { | 1346 if (classes.contains(_commonElements.jsInterceptorClass)) { |
1350 // If the base Interceptor class is in the set of intercepted classes, we | 1347 // If the base Interceptor class is in the set of intercepted classes, we |
1351 // need to go through the generic getInterceptorMethod, since any subclass | 1348 // need to go through the generic getInterceptorMethod, since any subclass |
1352 // of the base Interceptor could match. | 1349 // of the base Interceptor could match. |
1353 // The unspecialized getInterceptor method can also be accessed through | 1350 // The unspecialized getInterceptor method can also be accessed through |
1354 // its element, so we treat this as a user-space global instead of an | 1351 // its element, so we treat this as a user-space global instead of an |
1355 // internal global. | 1352 // internal global. |
1356 return _disambiguateGlobal(getInterceptor); | 1353 return _disambiguateGlobal(getInterceptor); |
1357 } | 1354 } |
1358 String suffix = suffixForGetInterceptor(classes); | 1355 String suffix = suffixForGetInterceptor(classes); |
1359 return _disambiguateInternalGlobal("${getInterceptor.name}\$$suffix"); | 1356 return _disambiguateInternalGlobal("${getInterceptor.name}\$$suffix"); |
1360 } | 1357 } |
1361 | 1358 |
1362 /// Property name used for the one-shot interceptor method for the given | 1359 /// Property name used for the one-shot interceptor method for the given |
1363 /// [selector] and return-type specialization. | 1360 /// [selector] and return-type specialization. |
1364 jsAst.Name nameForGetOneShotInterceptor( | 1361 jsAst.Name nameForGetOneShotInterceptor( |
1365 Selector selector, Iterable<ClassEntity> classes) { | 1362 Selector selector, Iterable<ClassEntity> classes) { |
1366 // The one-shot name is a global name derived from the invocation name. To | 1363 // The one-shot name is a global name derived from the invocation name. To |
1367 // avoid instability we would like the names to be unique and not clash with | 1364 // avoid instability we would like the names to be unique and not clash with |
1368 // other global names. | 1365 // other global names. |
1369 jsAst.Name root = invocationName(selector); | 1366 jsAst.Name root = invocationName(selector); |
1370 | 1367 |
1371 if (classes.contains(_helpers.jsInterceptorClass)) { | 1368 if (classes.contains(_commonElements.jsInterceptorClass)) { |
1372 // If the base Interceptor class is in the set of intercepted classes, | 1369 // If the base Interceptor class is in the set of intercepted classes, |
1373 // this is the most general specialization which uses the generic | 1370 // this is the most general specialization which uses the generic |
1374 // getInterceptor method. | 1371 // getInterceptor method. |
1375 // TODO(sra): Find a way to get the simple name when Object is not in the | 1372 // TODO(sra): Find a way to get the simple name when Object is not in the |
1376 // set of classes for most general variant, e.g. "$lt$n" could be "$lt". | 1373 // set of classes for most general variant, e.g. "$lt$n" could be "$lt". |
1377 return new CompoundName([root, _literalDollar]); | 1374 return new CompoundName([root, _literalDollar]); |
1378 } else { | 1375 } else { |
1379 String suffix = suffixForGetInterceptor(classes); | 1376 String suffix = suffixForGetInterceptor(classes); |
1380 return new CompoundName( | 1377 return new CompoundName( |
1381 [root, _literalDollar, new StringBackedName(suffix)]); | 1378 [root, _literalDollar, new StringBackedName(suffix)]); |
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1481 globalObjectFor(element); | 1478 globalObjectFor(element); |
1482 | 1479 |
1483 /// Returns [staticStateHolder] or one of [reservedGlobalObjectNames]. | 1480 /// Returns [staticStateHolder] or one of [reservedGlobalObjectNames]. |
1484 String globalObjectFor(Element element) { | 1481 String globalObjectFor(Element element) { |
1485 if (_isPropertyOfStaticStateHolder(element)) return staticStateHolder; | 1482 if (_isPropertyOfStaticStateHolder(element)) return staticStateHolder; |
1486 return globalObjectForLibrary(element.library); | 1483 return globalObjectForLibrary(element.library); |
1487 } | 1484 } |
1488 | 1485 |
1489 /// Returns the [reservedGlobalObjectNames] for [library]. | 1486 /// Returns the [reservedGlobalObjectNames] for [library]. |
1490 String globalObjectForLibrary(LibraryElement library) { | 1487 String globalObjectForLibrary(LibraryElement library) { |
1491 if (library == _helpers.interceptorsLibrary) return 'J'; | 1488 if (library == _commonElements.interceptorsLibrary) return 'J'; |
1492 if (library.isInternalLibrary) return 'H'; | 1489 if (library.isInternalLibrary) return 'H'; |
1493 if (library.isPlatformLibrary) { | 1490 if (library.isPlatformLibrary) { |
1494 if ('${library.canonicalUri}' == 'dart:html') return 'W'; | 1491 if ('${library.canonicalUri}' == 'dart:html') return 'W'; |
1495 return 'P'; | 1492 return 'P'; |
1496 } | 1493 } |
1497 return userGlobalObjects[library.name.hashCode % userGlobalObjects.length]; | 1494 return userGlobalObjects[library.name.hashCode % userGlobalObjects.length]; |
1498 } | 1495 } |
1499 | 1496 |
1500 jsAst.Name deriveLazyInitializerName(jsAst.Name name) { | 1497 jsAst.Name deriveLazyInitializerName(jsAst.Name name) { |
1501 // These are not real dart getters, so do not use GetterName; | 1498 // These are not real dart getters, so do not use GetterName; |
(...skipping 682 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2184 void addSuggestion(String original, String suggestion) { | 2181 void addSuggestion(String original, String suggestion) { |
2185 assert(!_suggestedNames.containsKey(original)); | 2182 assert(!_suggestedNames.containsKey(original)); |
2186 _suggestedNames[original] = suggestion; | 2183 _suggestedNames[original] = suggestion; |
2187 } | 2184 } |
2188 | 2185 |
2189 bool hasSuggestion(String original) => _suggestedNames.containsKey(original); | 2186 bool hasSuggestion(String original) => _suggestedNames.containsKey(original); |
2190 bool isSuggestion(String candidate) { | 2187 bool isSuggestion(String candidate) { |
2191 return _suggestedNames.containsValue(candidate); | 2188 return _suggestedNames.containsValue(candidate); |
2192 } | 2189 } |
2193 } | 2190 } |
OLD | NEW |