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

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

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

Powered by Google App Engine
This is Rietveld 408576698