Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(770)

Side by Side Diff: pkg/compiler/lib/src/js_backend/namer.dart

Issue 1062913003: Extract CallStructure from Selector. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 5 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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 478 matching lines...) Expand 10 before | Expand all | Expand 10 after
489 * If the [originalName] is not private returns [originalName]. Otherwise 489 * If the [originalName] is not private returns [originalName]. Otherwise
490 * mangles the [originalName] so that each library has its own distinguished 490 * mangles the [originalName] so that each library has its own distinguished
491 * version of the name. 491 * version of the name.
492 * 492 *
493 * Although the name is not guaranteed to be unique within any namespace, 493 * Although the name is not guaranteed to be unique within any namespace,
494 * clashes are very unlikely in practice. Therefore, it can be used in cases 494 * clashes are very unlikely in practice. Therefore, it can be used in cases
495 * where uniqueness is nice but not a strict requirement. 495 * where uniqueness is nice but not a strict requirement.
496 * 496 *
497 * The resulting name is a *proposed name* and is never minified. 497 * The resulting name is a *proposed name* and is never minified.
498 */ 498 */
499 String privateName(LibraryElement library, String originalName) { 499 String privateName(Name originalName) {
500 String text = originalName.text;
501
500 // Public names are easy. 502 // Public names are easy.
501 if (!isPrivateName(originalName)) return originalName; 503 if (!originalName.isPrivate) return text;
504
505 LibraryElement library = originalName.library;
502 506
503 // The first library asking for a short private name wins. 507 // The first library asking for a short private name wins.
504 LibraryElement owner = 508 LibraryElement owner =
505 shortPrivateNameOwners.putIfAbsent(originalName, () => library); 509 shortPrivateNameOwners.putIfAbsent(text, () => library);
506 510
507 if (owner == library) { 511 if (owner == library) {
508 return originalName; 512 return text;
509 } else { 513 } else {
510 // Make sure to return a private name that starts with _ so it 514 // Make sure to return a private name that starts with _ so it
511 // cannot clash with any public names. 515 // cannot clash with any public names.
512 // The name is still not guaranteed to be unique, since both the library 516 // The name is still not guaranteed to be unique, since both the library
513 // name and originalName could contain $ symbols. 517 // name and originalName could contain $ symbols.
514 String libraryName = _disambiguateGlobal(library); 518 String libraryName = _disambiguateGlobal(library);
515 return '_$libraryName\$${originalName}'; 519 return '_$libraryName\$${text}';
516 } 520 }
517 } 521 }
518 522
519 String _proposeNameForConstructorBody(ConstructorBodyElement method) { 523 String _proposeNameForConstructorBody(ConstructorBodyElement method) {
520 String name = Elements.reconstructConstructorNameSourceString(method); 524 String name = Elements.reconstructConstructorNameSourceString(method);
521 // We include the method suffix on constructor bodies. It has no purpose, 525 // We include the method suffix on constructor bodies. It has no purpose,
522 // but this way it produces the same names as previous versions of the 526 // but this way it produces the same names as previous versions of the
523 // Namer class did. 527 // Namer class did.
524 List<String> suffix = callSuffixForSignature(method.functionSignature); 528 List<String> suffix = callSuffixForSignature(method.functionSignature);
525 return '$name\$${suffix.join(r'$')}'; 529 return '$name\$${suffix.join(r'$')}';
(...skipping 25 matching lines...) Expand all
551 // TODO(asgerf): Avoid clashes when named parameters contain $ symbols. 555 // TODO(asgerf): Avoid clashes when named parameters contain $ symbols.
552 return '$callPrefix\$${suffix.join(r'$')}'; 556 return '$callPrefix\$${suffix.join(r'$')}';
553 } 557 }
554 558
555 /// The suffix list for the pattern: 559 /// The suffix list for the pattern:
556 /// 560 ///
557 /// $<N>$namedParam1...$namedParam<M> 561 /// $<N>$namedParam1...$namedParam<M>
558 /// 562 ///
559 /// This is used for the annotated names of `call`, and for the proposed name 563 /// This is used for the annotated names of `call`, and for the proposed name
560 /// for other instance methods. 564 /// for other instance methods.
561 List<String> callSuffixForSelector(Selector selector) { 565 List<String> callSuffixForStructure(CallStructure callStructure) {
562 List<String> suffixes = ['${selector.argumentCount}']; 566 List<String> suffixes = ['${callStructure.argumentCount}'];
563 suffixes.addAll(selector.getOrderedNamedArguments()); 567 suffixes.addAll(callStructure.getOrderedNamedArguments());
564 return suffixes; 568 return suffixes;
565 } 569 }
566 570
567 /// The suffix list for the pattern: 571 /// The suffix list for the pattern:
568 /// 572 ///
569 /// $<N>$namedParam1...$namedParam<M> 573 /// $<N>$namedParam1...$namedParam<M>
570 /// 574 ///
571 /// This is used for the annotated names of `call`, and for the proposed name 575 /// This is used for the annotated names of `call`, and for the proposed name
572 /// for other instance methods. 576 /// for other instance methods.
573 List<String> callSuffixForSignature(FunctionSignature sig) { 577 List<String> callSuffixForSignature(FunctionSignature sig) {
574 List<String> suffixes = ['${sig.parameterCount}']; 578 List<String> suffixes = ['${sig.parameterCount}'];
575 if (sig.optionalParametersAreNamed) { 579 if (sig.optionalParametersAreNamed) {
576 for (FormalElement param in sig.orderedOptionalParameters) { 580 for (FormalElement param in sig.orderedOptionalParameters) {
577 suffixes.add(param.name); 581 suffixes.add(param.name);
578 } 582 }
579 } 583 }
580 return suffixes; 584 return suffixes;
581 } 585 }
582 586
583 /// Annotated name for the member being invoked by [selector]. 587 /// Annotated name for the member being invoked by [selector].
584 String invocationName(Selector selector) { 588 String invocationName(Selector selector) {
585 LibraryElement library = selector.library;
586 switch (selector.kind) { 589 switch (selector.kind) {
587 case SelectorKind.GETTER: 590 case SelectorKind.GETTER:
588 String disambiguatedName = _disambiguateMember(library, selector.name); 591 String disambiguatedName = _disambiguateMember(selector.memberName);
589 return deriveGetterName(disambiguatedName); 592 return deriveGetterName(disambiguatedName);
590 593
591 case SelectorKind.SETTER: 594 case SelectorKind.SETTER:
592 String disambiguatedName = _disambiguateMember(library, selector.name); 595 String disambiguatedName = _disambiguateMember(selector.memberName);
593 return deriveSetterName(disambiguatedName); 596 return deriveSetterName(disambiguatedName);
594 597
595 case SelectorKind.OPERATOR: 598 case SelectorKind.OPERATOR:
596 case SelectorKind.INDEX: 599 case SelectorKind.INDEX:
597 String operatorIdentifier = operatorNameToIdentifier(selector.name); 600 String operatorIdentifier = operatorNameToIdentifier(selector.name);
598 String disambiguatedName = _disambiguateOperator(operatorIdentifier); 601 String disambiguatedName = _disambiguateOperator(operatorIdentifier);
599 return disambiguatedName; // Operators are not annotated. 602 return disambiguatedName; // Operators are not annotated.
600 603
601 case SelectorKind.CALL: 604 case SelectorKind.CALL:
602 List<String> suffix = callSuffixForSelector(selector); 605 List<String> suffix = callSuffixForStructure(selector.callStructure);
603 if (selector.name == Compiler.CALL_OPERATOR_NAME) { 606 if (selector.name == Compiler.CALL_OPERATOR_NAME) {
604 // Derive the annotated name for this variant of 'call'. 607 // Derive the annotated name for this variant of 'call'.
605 return deriveCallMethodName(suffix); 608 return deriveCallMethodName(suffix);
606 } 609 }
607 String disambiguatedName = 610 String disambiguatedName =
608 _disambiguateMember(library, selector.name, suffix); 611 _disambiguateMember(selector.memberName, suffix);
609 return disambiguatedName; // Methods other than call are not annotated. 612 return disambiguatedName; // Methods other than call are not annotated.
610 613
611 default: 614 default:
612 compiler.internalError(compiler.currentElement, 615 compiler.internalError(compiler.currentElement,
613 'Unexpected selector kind: ${selector.kind}'); 616 'Unexpected selector kind: ${selector.kind}');
614 return null; 617 return null;
615 } 618 }
616 } 619 }
617 620
618 /** 621 /**
619 * Returns the internal name used for an invocation mirror of this selector. 622 * Returns the internal name used for an invocation mirror of this selector.
620 */ 623 */
621 String invocationMirrorInternalName(Selector selector) 624 String invocationMirrorInternalName(Selector selector)
622 => invocationName(selector); 625 => invocationName(selector);
623 626
624 /** 627 /**
625 * Returns the disambiguated name for the given field, used for constructing 628 * Returns the disambiguated name for the given field, used for constructing
626 * the getter and setter names. 629 * the getter and setter names.
627 */ 630 */
628 String fieldAccessorName(Element element) { 631 String fieldAccessorName(FieldElement element) {
629 return element.isInstanceMember 632 return element.isInstanceMember
630 ? _disambiguateMember(element.library, element.name) 633 ? _disambiguateMember(element.memberName)
631 : _disambiguateGlobal(element); 634 : _disambiguateGlobal(element);
632 } 635 }
633 636
634 /** 637 /**
635 * Returns name of the JavaScript property used to store a static or instance 638 * Returns name of the JavaScript property used to store a static or instance
636 * field. 639 * field.
637 */ 640 */
638 String fieldPropertyName(Element element) { 641 String fieldPropertyName(FieldElement element) {
639 return element.isInstanceMember 642 return element.isInstanceMember
640 ? instanceFieldPropertyName(element) 643 ? instanceFieldPropertyName(element)
641 : _disambiguateGlobal(element); 644 : _disambiguateGlobal(element);
642 } 645 }
643 646
644 /** 647 /**
645 * Returns name of the JavaScript property used to store the 648 * Returns name of the JavaScript property used to store the
646 * `readTypeVariable` function for the given type variable. 649 * `readTypeVariable` function for the given type variable.
647 */ 650 */
648 String nameForReadTypeVariable(TypeVariableElement element) { 651 String nameForReadTypeVariable(TypeVariableElement element) {
649 return _disambiguateInternalMember(element, () => element.name); 652 return _disambiguateInternalMember(element, () => element.name);
650 } 653 }
651 654
652 /** 655 /**
653 * Returns a JavaScript property name used to store [element] on one 656 * Returns a JavaScript property name used to store [element] on one
654 * of the global objects. 657 * of the global objects.
655 * 658 *
656 * Should be used together with [globalObjectFor], which denotes the object 659 * Should be used together with [globalObjectFor], which denotes the object
657 * on which the returned property name should be used. 660 * on which the returned property name should be used.
658 */ 661 */
659 String globalPropertyName(Element element) { 662 String globalPropertyName(Element element) {
660 return _disambiguateGlobal(element); 663 return _disambiguateGlobal(element);
661 } 664 }
662 665
663 /** 666 /**
664 * Returns the JavaScript property name used to store an instance field. 667 * Returns the JavaScript property name used to store an instance field.
665 */ 668 */
666 String instanceFieldPropertyName(Element element) { 669 String instanceFieldPropertyName(FieldElement element) {
667 ClassElement enclosingClass = element.enclosingClass; 670 ClassElement enclosingClass = element.enclosingClass;
668 671
669 if (element.hasFixedBackendName) { 672 if (element.hasFixedBackendName) {
670 // Certain native fields must be given a specific name. Native names must 673 // Certain native fields must be given a specific name. Native names must
671 // not contain '$'. We rely on this to avoid clashes. 674 // not contain '$'. We rely on this to avoid clashes.
672 assert(enclosingClass.isNative && 675 assert(enclosingClass.isNative &&
673 !element.fixedBackendName.contains(r'$')); 676 !element.fixedBackendName.contains(r'$'));
674 677
675 return element.fixedBackendName; 678 return element.fixedBackendName;
676 } 679 }
(...skipping 19 matching lines...) Expand all
696 if (classWorld.isUsedAsMixin(enclosingClass) || 699 if (classWorld.isUsedAsMixin(enclosingClass) ||
697 _isShadowingSuperField(element) || 700 _isShadowingSuperField(element) ||
698 _isUserClassExtendingNative(enclosingClass)) { 701 _isUserClassExtendingNative(enclosingClass)) {
699 String proposeName() => '${enclosingClass.name}_${element.name}'; 702 String proposeName() => '${enclosingClass.name}_${element.name}';
700 return _disambiguateInternalMember(element, proposeName); 703 return _disambiguateInternalMember(element, proposeName);
701 } 704 }
702 705
703 // No superclass uses the disambiguated name as a property name, so we can 706 // No superclass uses the disambiguated name as a property name, so we can
704 // use it for this field. This generates nicer field names since otherwise 707 // use it for this field. This generates nicer field names since otherwise
705 // the field name would have to be mangled. 708 // the field name would have to be mangled.
706 return _disambiguateMember(element.library, element.name); 709 return _disambiguateMember(element.memberName);
707 } 710 }
708 711
709 bool _isShadowingSuperField(Element element) { 712 bool _isShadowingSuperField(Element element) {
710 return element.enclosingClass.hasFieldShadowedBy(element); 713 return element.enclosingClass.hasFieldShadowedBy(element);
711 } 714 }
712 715
713 /// True if [class_] is a non-native class that inherits from a native class. 716 /// True if [class_] is a non-native class that inherits from a native class.
714 bool _isUserClassExtendingNative(ClassElement class_) { 717 bool _isUserClassExtendingNative(ClassElement class_) {
715 return !class_.isNative && 718 return !class_.isNative &&
716 Elements.isNativeOrExtendsNative(class_.superclass); 719 Elements.isNativeOrExtendsNative(class_.superclass);
717 } 720 }
718 721
719 /// Annotated name for the setter of [element]. 722 /// Annotated name for the setter of [element].
720 String setterForElement(Element element) { 723 String setterForElement(MemberElement element) {
721 // We dynamically create setters from the field-name. The setter name must 724 // We dynamically create setters from the field-name. The setter name must
722 // therefore be derived from the instance field-name. 725 // therefore be derived from the instance field-name.
723 String name = _disambiguateMember(element.library, element.name); 726 String name = _disambiguateMember(element.memberName);
724 return deriveSetterName(name); 727 return deriveSetterName(name);
725 } 728 }
726 729
727 /// Annotated name for the setter of any member with [disambiguatedName]. 730 /// Annotated name for the setter of any member with [disambiguatedName].
728 String deriveSetterName(String disambiguatedName) { 731 String deriveSetterName(String disambiguatedName) {
729 // We dynamically create setters from the field-name. The setter name must 732 // We dynamically create setters from the field-name. The setter name must
730 // therefore be derived from the instance field-name. 733 // therefore be derived from the instance field-name.
731 return '$setterPrefix$disambiguatedName'; 734 return '$setterPrefix$disambiguatedName';
732 } 735 }
733 736
734 /// Annotated name for the setter of any member with [disambiguatedName]. 737 /// Annotated name for the setter of any member with [disambiguatedName].
735 String deriveGetterName(String disambiguatedName) { 738 String deriveGetterName(String disambiguatedName) {
736 // We dynamically create getters from the field-name. The getter name must 739 // We dynamically create getters from the field-name. The getter name must
737 // therefore be derived from the instance field-name. 740 // therefore be derived from the instance field-name.
738 return '$getterPrefix$disambiguatedName'; 741 return '$getterPrefix$disambiguatedName';
739 } 742 }
740 743
741 /// Annotated name for the getter of [element]. 744 /// Annotated name for the getter of [element].
742 String getterForElement(Element element) { 745 String getterForElement(MemberElement element) {
743 // We dynamically create getters from the field-name. The getter name must 746 // We dynamically create getters from the field-name. The getter name must
744 // therefore be derived from the instance field-name. 747 // therefore be derived from the instance field-name.
745 String name = _disambiguateMember(element.library, element.name); 748 String name = _disambiguateMember(element.memberName);
746 return deriveGetterName(name); 749 return deriveGetterName(name);
747 } 750 }
748 751
749 /// Property name for the getter of an instance member with [originalName] 752 /// Property name for the getter of an instance member with [originalName].
750 /// in [library]. 753 String getterForMember(Name originalName) {
751 /// 754 String disambiguatedName = _disambiguateMember(originalName);
752 /// [library] may be `null` if [originalName] is known to be public.
753 String getterForMember(LibraryElement library, String originalName) {
754 String disambiguatedName = _disambiguateMember(library, originalName);
755 return deriveGetterName(disambiguatedName); 755 return deriveGetterName(disambiguatedName);
756 } 756 }
757 757
758 /// Property name for the getter or a public instance member with
759 /// [originalName].
760 String getterForPublicMember(String originalName) {
761 return getterForMember(null, originalName);
762 }
763
764 /// Disambiguated name for a compiler-owned global variable. 758 /// Disambiguated name for a compiler-owned global variable.
765 /// 759 ///
766 /// The resulting name is unique within the global-member namespace. 760 /// The resulting name is unique within the global-member namespace.
767 String _disambiguateInternalGlobal(String name) { 761 String _disambiguateInternalGlobal(String name) {
768 String newName = internalGlobals[name]; 762 String newName = internalGlobals[name];
769 if (newName == null) { 763 if (newName == null) {
770 newName = getFreshName(name, usedGlobalNames, suggestedGlobalNames); 764 newName = getFreshName(name, usedGlobalNames, suggestedGlobalNames);
771 internalGlobals[name] = newName; 765 internalGlobals[name] = newName;
772 } 766 }
773 return newName; 767 return newName;
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
815 /// and setters) and as property name for storing methods and method stubs. 809 /// and setters) and as property name for storing methods and method stubs.
816 /// 810 ///
817 /// [suffixes] denote an extension of [originalName] to distiguish it from 811 /// [suffixes] denote an extension of [originalName] to distiguish it from
818 /// other members with that name. These are used to encode the arity and 812 /// other members with that name. These are used to encode the arity and
819 /// named parameters to a method. Disambiguating the same [originalName] with 813 /// named parameters to a method. Disambiguating the same [originalName] with
820 /// different [suffixes] will yield different disambiguated names. 814 /// different [suffixes] will yield different disambiguated names.
821 /// 815 ///
822 /// The resulting name, and its associated annotated names, are unique 816 /// The resulting name, and its associated annotated names, are unique
823 /// to the ([originalName], [suffixes]) pair within the instance-member 817 /// to the ([originalName], [suffixes]) pair within the instance-member
824 /// namespace. 818 /// namespace.
825 String _disambiguateMember(LibraryElement library, 819 String _disambiguateMember(Name originalName,
826 String originalName,
827 [List<String> suffixes = const []]) { 820 [List<String> suffixes = const []]) {
828 // For private names, a library must be given.
829 assert(isPublicName(originalName) || library != null);
830
831 // Build a string encoding the library name, if the name is private. 821 // Build a string encoding the library name, if the name is private.
832 String libraryKey = isPrivateName(originalName) 822 String libraryKey = originalName.isPrivate
833 ? _disambiguateGlobal(library) 823 ? _disambiguateGlobal(originalName.library)
834 : ''; 824 : '';
835 825
836 // In the unique key, separate the name parts by '@'. 826 // In the unique key, separate the name parts by '@'.
837 // This avoids clashes since the original names cannot contain that symbol. 827 // This avoids clashes since the original names cannot contain that symbol.
838 String key = '$libraryKey@$originalName@${suffixes.join('@')}'; 828 String key = '$libraryKey@${originalName.text}@${suffixes.join('@')}';
839 String newName = userInstanceMembers[key]; 829 String newName = userInstanceMembers[key];
840 if (newName == null) { 830 if (newName == null) {
841 String proposedName = privateName(library, originalName); 831 String proposedName = privateName(originalName);
842 if (!suffixes.isEmpty) { 832 if (!suffixes.isEmpty) {
843 // In the proposed name, separate the name parts by '$', because the 833 // In the proposed name, separate the name parts by '$', because the
844 // proposed name must be a valid identifier, but not necessarily unique. 834 // proposed name must be a valid identifier, but not necessarily unique.
845 proposedName += r'$' + suffixes.join(r'$'); 835 proposedName += r'$' + suffixes.join(r'$');
846 } 836 }
847 newName = getFreshName(proposedName, 837 newName = getFreshName(proposedName,
848 usedInstanceNames, suggestedInstanceNames, 838 usedInstanceNames, suggestedInstanceNames,
849 sanitizeForAnnotations: true); 839 sanitizeForAnnotations: true);
850 userInstanceMembers[key] = newName; 840 userInstanceMembers[key] = newName;
851 } 841 }
(...skipping 916 matching lines...) Expand 10 before | Expand all | Expand 10 after
1768 if (!first) { 1758 if (!first) {
1769 sb.write('_'); 1759 sb.write('_');
1770 } 1760 }
1771 sb.write('_'); 1761 sb.write('_');
1772 visit(parameter); 1762 visit(parameter);
1773 first = true; 1763 first = true;
1774 } 1764 }
1775 } 1765 }
1776 } 1766 }
1777 } 1767 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698