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