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 show |
| 19 ClassElement, |
| 20 ConstructorBodyElement, |
| 21 Element, |
| 22 Elements, |
| 23 FieldElement, |
| 24 FormalElement, |
| 25 FunctionElement, |
| 26 FunctionSignature, |
| 27 MemberElement, |
| 28 TypeDeclarationElement, |
| 29 MixinApplicationElement, |
| 30 TypedefElement; |
18 import '../elements/entities.dart'; | 31 import '../elements/entities.dart'; |
19 import '../elements/entity_utils.dart' as utils; | 32 import '../elements/entity_utils.dart' as utils; |
20 import '../elements/jumps.dart'; | 33 import '../elements/jumps.dart'; |
21 import '../elements/names.dart'; | 34 import '../elements/names.dart'; |
22 import '../elements/resolution_types.dart'; | 35 import '../elements/resolution_types.dart'; |
23 import '../elements/types.dart'; | 36 import '../elements/types.dart'; |
24 import '../js/js.dart' as jsAst; | 37 import '../js/js.dart' as jsAst; |
25 import '../tree/tree.dart'; | |
26 import '../universe/call_structure.dart' show CallStructure; | 38 import '../universe/call_structure.dart' show CallStructure; |
27 import '../universe/selector.dart' show Selector, SelectorKind; | 39 import '../universe/selector.dart' show Selector, SelectorKind; |
28 import '../universe/world_builder.dart' show CodegenWorldBuilder; | 40 import '../universe/world_builder.dart' show CodegenWorldBuilder; |
29 import 'package:front_end/src/fasta/scanner/characters.dart'; | 41 import 'package:front_end/src/fasta/scanner/characters.dart'; |
30 import '../util/util.dart'; | 42 import '../util/util.dart'; |
31 import '../world.dart' show ClosedWorld; | 43 import '../world.dart' show ClosedWorld; |
32 import 'backend.dart'; | 44 import 'backend.dart'; |
33 import 'constant_system_javascript.dart'; | 45 import 'constant_system_javascript.dart'; |
34 import 'native_data.dart'; | 46 import 'native_data.dart'; |
35 import 'runtime_types.dart'; | 47 import 'runtime_types.dart'; |
(...skipping 499 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
535 | 547 |
536 /// Used to disambiguate names for constants in [constantName]. | 548 /// Used to disambiguate names for constants in [constantName]. |
537 final NamingScope constantScope = new NamingScope(); | 549 final NamingScope constantScope = new NamingScope(); |
538 | 550 |
539 /// Used to store scopes for instances of [PrivatelyNamedJsEntity] | 551 /// Used to store scopes for instances of [PrivatelyNamedJsEntity] |
540 final Map<Entity, NamingScope> _privateNamingScopes = | 552 final Map<Entity, NamingScope> _privateNamingScopes = |
541 new Map<Entity, NamingScope>(); | 553 new Map<Entity, NamingScope>(); |
542 | 554 |
543 final Map<String, int> popularNameCounters = <String, int>{}; | 555 final Map<String, int> popularNameCounters = <String, int>{}; |
544 | 556 |
545 final Map<LibraryElement, String> libraryLongNames = | 557 final Map<LibraryEntity, String> libraryLongNames = |
546 new HashMap<LibraryElement, String>(); | 558 new HashMap<LibraryEntity, String>(); |
547 | 559 |
548 final Map<ConstantValue, jsAst.Name> constantNames = | 560 final Map<ConstantValue, jsAst.Name> constantNames = |
549 new HashMap<ConstantValue, jsAst.Name>(); | 561 new HashMap<ConstantValue, jsAst.Name>(); |
550 final Map<ConstantValue, String> constantLongNames = | 562 final Map<ConstantValue, String> constantLongNames = |
551 <ConstantValue, String>{}; | 563 <ConstantValue, String>{}; |
552 ConstantCanonicalHasher _constantHasher; | 564 ConstantCanonicalHasher _constantHasher; |
553 | 565 |
554 /// Maps private names to a library that may use that name without prefixing | 566 /// Maps private names to a library that may use that name without prefixing |
555 /// itself. Used for building proposed names. | 567 /// itself. Used for building proposed names. |
556 final Map<String, LibraryElement> shortPrivateNameOwners = | 568 final Map<String, LibraryEntity> shortPrivateNameOwners = |
557 <String, LibraryElement>{}; | 569 <String, LibraryEntity>{}; |
558 | 570 |
559 final Map<String, String> suggestedGlobalNames = <String, String>{}; | 571 final Map<String, String> suggestedGlobalNames = <String, String>{}; |
560 final Map<String, String> suggestedInstanceNames = <String, String>{}; | 572 final Map<String, String> suggestedInstanceNames = <String, String>{}; |
561 | 573 |
562 /// Used to store unique keys for library names. Keys are not used as names, | 574 /// Used to store unique keys for library names. Keys are not used as names, |
563 /// nor are they visible in the output. The only serve as an internal | 575 /// nor are they visible in the output. The only serve as an internal |
564 /// key into maps. | 576 /// key into maps. |
565 final Map<LibraryElement, String> _libraryKeys = | 577 final Map<LibraryEntity, String> _libraryKeys = |
566 new HashMap<LibraryElement, String>(); | 578 new HashMap<LibraryEntity, String>(); |
567 | 579 |
568 Namer(this._closedWorld, this._codegenWorldBuilder) { | 580 Namer(this._closedWorld, this._codegenWorldBuilder) { |
569 _literalAsyncPrefix = new StringBackedName(asyncPrefix); | 581 _literalAsyncPrefix = new StringBackedName(asyncPrefix); |
570 _literalGetterPrefix = new StringBackedName(getterPrefix); | 582 _literalGetterPrefix = new StringBackedName(getterPrefix); |
571 _literalSetterPrefix = new StringBackedName(setterPrefix); | 583 _literalSetterPrefix = new StringBackedName(setterPrefix); |
572 _literalLazyGetterPrefix = new StringBackedName(lazyGetterPrefix); | 584 _literalLazyGetterPrefix = new StringBackedName(lazyGetterPrefix); |
573 } | 585 } |
574 | 586 |
575 CommonElements get _commonElements => _closedWorld.commonElements; | 587 CommonElements get _commonElements => _closedWorld.commonElements; |
576 | 588 |
(...skipping 12 matching lines...) Expand all Loading... |
589 String get closureInvocationSelectorName => Identifiers.call; | 601 String get closureInvocationSelectorName => Identifiers.call; |
590 bool get shouldMinify => false; | 602 bool get shouldMinify => false; |
591 | 603 |
592 NamingScope _getPrivateScopeFor(PrivatelyNamedJSEntity entity) { | 604 NamingScope _getPrivateScopeFor(PrivatelyNamedJSEntity entity) { |
593 return _privateNamingScopes.putIfAbsent( | 605 return _privateNamingScopes.putIfAbsent( |
594 entity.rootOfScope, () => new NamingScope()); | 606 entity.rootOfScope, () => new NamingScope()); |
595 } | 607 } |
596 | 608 |
597 /// Returns the string that is to be used as the result of a call to | 609 /// Returns the string that is to be used as the result of a call to |
598 /// [JS_GET_NAME] at [node] with argument [name]. | 610 /// [JS_GET_NAME] at [node] with argument [name]. |
599 jsAst.Name getNameForJsGetName(Node node, JsGetName name) { | 611 jsAst.Name getNameForJsGetName(Spannable spannable, JsGetName name) { |
600 switch (name) { | 612 switch (name) { |
601 case JsGetName.GETTER_PREFIX: | 613 case JsGetName.GETTER_PREFIX: |
602 return asName(getterPrefix); | 614 return asName(getterPrefix); |
603 case JsGetName.SETTER_PREFIX: | 615 case JsGetName.SETTER_PREFIX: |
604 return asName(setterPrefix); | 616 return asName(setterPrefix); |
605 case JsGetName.CALL_PREFIX: | 617 case JsGetName.CALL_PREFIX: |
606 return asName(callPrefix); | 618 return asName(callPrefix); |
607 case JsGetName.CALL_PREFIX0: | 619 case JsGetName.CALL_PREFIX0: |
608 return asName('${callPrefix}\$0'); | 620 return asName('${callPrefix}\$0'); |
609 case JsGetName.CALL_PREFIX1: | 621 case JsGetName.CALL_PREFIX1: |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
646 return asName(functionTypeReturnTypeTag); | 658 return asName(functionTypeReturnTypeTag); |
647 case JsGetName.FUNCTION_TYPE_REQUIRED_PARAMETERS_TAG: | 659 case JsGetName.FUNCTION_TYPE_REQUIRED_PARAMETERS_TAG: |
648 return asName(functionTypeRequiredParametersTag); | 660 return asName(functionTypeRequiredParametersTag); |
649 case JsGetName.FUNCTION_TYPE_OPTIONAL_PARAMETERS_TAG: | 661 case JsGetName.FUNCTION_TYPE_OPTIONAL_PARAMETERS_TAG: |
650 return asName(functionTypeOptionalParametersTag); | 662 return asName(functionTypeOptionalParametersTag); |
651 case JsGetName.FUNCTION_TYPE_NAMED_PARAMETERS_TAG: | 663 case JsGetName.FUNCTION_TYPE_NAMED_PARAMETERS_TAG: |
652 return asName(functionTypeNamedParametersTag); | 664 return asName(functionTypeNamedParametersTag); |
653 case JsGetName.IS_INDEXABLE_FIELD_NAME: | 665 case JsGetName.IS_INDEXABLE_FIELD_NAME: |
654 return operatorIs(_commonElements.jsIndexingBehaviorInterface); | 666 return operatorIs(_commonElements.jsIndexingBehaviorInterface); |
655 case JsGetName.NULL_CLASS_TYPE_NAME: | 667 case JsGetName.NULL_CLASS_TYPE_NAME: |
656 ClassElement nullClass = _commonElements.nullClass; | 668 return runtimeTypeName(_commonElements.nullClass); |
657 return runtimeTypeName(nullClass); | |
658 case JsGetName.OBJECT_CLASS_TYPE_NAME: | 669 case JsGetName.OBJECT_CLASS_TYPE_NAME: |
659 ClassElement objectClass = _commonElements.objectClass; | 670 return runtimeTypeName(_commonElements.objectClass); |
660 return runtimeTypeName(objectClass); | |
661 case JsGetName.FUNCTION_CLASS_TYPE_NAME: | 671 case JsGetName.FUNCTION_CLASS_TYPE_NAME: |
662 ClassElement functionClass = _commonElements.functionClass; | 672 return runtimeTypeName(_commonElements.functionClass); |
663 return runtimeTypeName(functionClass); | |
664 default: | 673 default: |
665 throw new SpannableAssertionFailure( | 674 throw new SpannableAssertionFailure( |
666 node, 'Error: Namer has no name for "$name".'); | 675 spannable, 'Error: Namer has no name for "$name".'); |
667 } | 676 } |
668 } | 677 } |
669 | 678 |
670 /// Return a reference to the given [name]. | 679 /// Return a reference to the given [name]. |
671 /// | 680 /// |
672 /// This is used to ensure that every use site of a name has a unique node so | 681 /// This is used to ensure that every use site of a name has a unique node so |
673 /// that we can properly attribute source information. | 682 /// that we can properly attribute source information. |
674 jsAst.Name _newReference(jsAst.Name name) { | 683 jsAst.Name _newReference(jsAst.Name name) { |
675 return new _NameReference(name); | 684 return new _NameReference(name); |
676 } | 685 } |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
734 * where uniqueness is nice but not a strict requirement. | 743 * where uniqueness is nice but not a strict requirement. |
735 * | 744 * |
736 * The resulting name is a *proposed name* and is never minified. | 745 * The resulting name is a *proposed name* and is never minified. |
737 */ | 746 */ |
738 String privateName(Name originalName) { | 747 String privateName(Name originalName) { |
739 String text = originalName.text; | 748 String text = originalName.text; |
740 | 749 |
741 // Public names are easy. | 750 // Public names are easy. |
742 if (!originalName.isPrivate) return text; | 751 if (!originalName.isPrivate) return text; |
743 | 752 |
744 LibraryElement library = originalName.library; | 753 LibraryEntity library = originalName.library; |
745 | 754 |
746 // The first library asking for a short private name wins. | 755 // The first library asking for a short private name wins. |
747 LibraryElement owner = | 756 LibraryEntity owner = |
748 shortPrivateNameOwners.putIfAbsent(text, () => library); | 757 shortPrivateNameOwners.putIfAbsent(text, () => library); |
749 | 758 |
750 if (owner == library) { | 759 if (owner == library) { |
751 return text; | 760 return text; |
752 } else { | 761 } else { |
753 // Make sure to return a private name that starts with _ so it | 762 // Make sure to return a private name that starts with _ so it |
754 // cannot clash with any public names. | 763 // cannot clash with any public names. |
755 // The name is still not guaranteed to be unique, since both the library | 764 // The name is still not guaranteed to be unique, since both the library |
756 // name and originalName could contain $ symbols and as the library | 765 // name and originalName could contain $ symbols and as the library |
757 // name itself might clash. | 766 // name itself might clash. |
(...skipping 271 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1029 /// globals, although the callers of must still take care not to accidentally | 1038 /// globals, although the callers of must still take care not to accidentally |
1030 /// pass in the same [name] for two different internal globals. | 1039 /// pass in the same [name] for two different internal globals. |
1031 jsAst.Name internalGlobal(String name) { | 1040 jsAst.Name internalGlobal(String name) { |
1032 assert(!name.contains(r'$')); | 1041 assert(!name.contains(r'$')); |
1033 return _disambiguateInternalGlobal(name); | 1042 return _disambiguateInternalGlobal(name); |
1034 } | 1043 } |
1035 | 1044 |
1036 /// Generates a unique key for [library]. | 1045 /// Generates a unique key for [library]. |
1037 /// | 1046 /// |
1038 /// Keys are meant to be used in maps and should not be visible in the output. | 1047 /// Keys are meant to be used in maps and should not be visible in the output. |
1039 String _generateLibraryKey(LibraryElement library) { | 1048 String _generateLibraryKey(LibraryEntity library) { |
1040 return _libraryKeys.putIfAbsent(library, () { | 1049 return _libraryKeys.putIfAbsent(library, () { |
1041 String keyBase = library.name; | 1050 String keyBase = library.name; |
1042 int counter = 0; | 1051 int counter = 0; |
1043 String key = keyBase; | 1052 String key = keyBase; |
1044 while (_libraryKeys.values.contains(key)) { | 1053 while (_libraryKeys.values.contains(key)) { |
1045 key = "$keyBase${counter++}"; | 1054 key = "$keyBase${counter++}"; |
1046 } | 1055 } |
1047 return key; | 1056 return key; |
1048 }); | 1057 }); |
1049 } | 1058 } |
(...skipping 1189 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2239 void addSuggestion(String original, String suggestion) { | 2248 void addSuggestion(String original, String suggestion) { |
2240 assert(!_suggestedNames.containsKey(original)); | 2249 assert(!_suggestedNames.containsKey(original)); |
2241 _suggestedNames[original] = suggestion; | 2250 _suggestedNames[original] = suggestion; |
2242 } | 2251 } |
2243 | 2252 |
2244 bool hasSuggestion(String original) => _suggestedNames.containsKey(original); | 2253 bool hasSuggestion(String original) => _suggestedNames.containsKey(original); |
2245 bool isSuggestion(String candidate) { | 2254 bool isSuggestion(String candidate) { |
2246 return _suggestedNames.containsValue(candidate); | 2255 return _suggestedNames.containsValue(candidate); |
2247 } | 2256 } |
2248 } | 2257 } |
OLD | NEW |