| 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 |