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

Side by Side Diff: reflectable/lib/src/transformer_implementation.dart

Issue 1391543003: Creates `reflectors`, as a meta-meta feature that enables dynamic selection of a "mirror system". (Closed) Base URL: https://github.com/dart-lang/reflectable.git@master
Patch Set: Review response. Created 5 years, 2 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
OLDNEW
1 // (c) 2015, the Dart Team. All rights reserved. Use of this 1 // (c) 2015, the Dart Team. All rights reserved. Use of this
2 // source code is governed by a BSD-style license that can be found in 2 // source code is governed by a BSD-style license that can be found in
3 // the LICENSE file. 3 // the LICENSE file.
4 4
5 library reflectable.src.transformer_implementation; 5 library reflectable.src.transformer_implementation;
6 6
7 import 'dart:async'; 7 import 'dart:async';
8 import 'dart:convert'; 8 import 'dart:convert';
9 import 'dart:io'; 9 import 'dart:io';
10 import 'package:analyzer/src/generated/ast.dart'; 10 import 'package:analyzer/src/generated/ast.dart';
(...skipping 507 matching lines...) Expand 10 before | Expand all | Expand 10 after
518 String _constConstructionCode(_ImportCollector importCollector) { 518 String _constConstructionCode(_ImportCollector importCollector) {
519 String prefix = importCollector._getPrefix(_reflector.library); 519 String prefix = importCollector._getPrefix(_reflector.library);
520 return "const $prefix.${_reflector.name}()"; 520 return "const $prefix.${_reflector.name}()";
521 } 521 }
522 522
523 /// Generate the code which will create a `ReflectorData` instance 523 /// Generate the code which will create a `ReflectorData` instance
524 /// containing the mirrors and other reflection data which is needed for 524 /// containing the mirrors and other reflection data which is needed for
525 /// `_reflector` to behave correctly. 525 /// `_reflector` to behave correctly.
526 String _generateCode( 526 String _generateCode(
527 _ImportCollector importCollector, TransformLogger logger) { 527 _ImportCollector importCollector, TransformLogger logger) {
528 Enumerator<ExecutableElement> members = new Enumerator<ExecutableElement>(); 528 // Library related collections.
529 Enumerator<_LibraryDomain> libraries = new Enumerator<_LibraryDomain>();
530 Map<LibraryElement, _LibraryDomain> libraryMap =
531 <LibraryElement, _LibraryDomain>{};
532 Enumerator<TopLevelVariableElement> topLevelVariables =
533 new Enumerator<TopLevelVariableElement>();
534
535 // Class related collections.
529 Enumerator<FieldElement> fields = new Enumerator<FieldElement>(); 536 Enumerator<FieldElement> fields = new Enumerator<FieldElement>();
530 Enumerator<ParameterElement> parameters = 537 Enumerator<ParameterElement> parameters =
531 new Enumerator<ParameterElement>(); 538 new Enumerator<ParameterElement>();
532 Enumerator<LibraryElement> libraries = new Enumerator<LibraryElement>();
533 Set<String> instanceGetterNames = new Set<String>(); 539 Set<String> instanceGetterNames = new Set<String>();
534 Set<String> instanceSetterNames = new Set<String>(); 540 Set<String> instanceSetterNames = new Set<String>();
535 541
542 // Library and class related collections.
543 Enumerator<ExecutableElement> members = new Enumerator<ExecutableElement>();
544
536 // Fill in [libraries], [members], [fields], [parameters], 545 // Fill in [libraries], [members], [fields], [parameters],
537 // [instanceGetterNames], and [instanceSetterNames]. 546 // [instanceGetterNames], and [instanceSetterNames].
538 for (LibraryElement library in _libraries) { 547 for (LibraryElement library in _libraries) {
539 libraries.add(library); 548 _LibraryDomain libraryDomain = _createLibraryDomain(library, this);
549 libraries.add(libraryDomain);
550 libraryMap[library] = libraryDomain;
551 libraryDomain._declarations.forEach(members.add);
552 libraryDomain._declaredParameters.forEach(parameters.add);
553 libraryDomain._declaredVariables.forEach(topLevelVariables.add);
540 } 554 }
541 for (_ClassDomain classDomain in classes.domains) { 555 for (_ClassDomain classDomain in classes.domains) {
542 // Gather the behavioral interface into [members]. Note that 556 // Gather the behavioral interface into [members]. Note that
543 // this includes implicitly generated getters and setters, but 557 // this includes implicitly generated getters and setters, but
544 // omits fields. Also note that this does not match the 558 // omits fields. Also note that this does not match the
545 // semantics of the `declarations` method in a [ClassMirror]. 559 // semantics of the `declarations` method in a [ClassMirror].
546 classDomain._declarations.forEach(members.add); 560 classDomain._declarations.forEach(members.add);
547 561
548 // Add the behavioral interface from this class (redundantly, for 562 // Add the behavioral interface from this class (redundantly, for
549 // non-static members) and all superclasses (which matters) to 563 // non-static members) and all superclasses (which matters) to
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
581 instanceGetterNames.add(instanceMember.name); 595 instanceGetterNames.add(instanceMember.name);
582 } else { 596 } else {
583 // `instanceMember` is a ConstructorElement. 597 // `instanceMember` is a ConstructorElement.
584 // Even though a generative constructor has a false 598 // Even though a generative constructor has a false
585 // `isStatic`, we do not wish to include them among 599 // `isStatic`, we do not wish to include them among
586 // instanceGetterNames, so we do nothing here. 600 // instanceGetterNames, so we do nothing here.
587 } 601 }
588 }); 602 });
589 } 603 }
590 604
605 // Find the offsets of fields and of methods and functions in members.
606 int fieldsOffset = topLevelVariables.length;
607 int methodsOffset = fieldsOffset + fields.length;
608
591 // Generate code for creation of class mirrors. 609 // Generate code for creation of class mirrors.
592 String classMirrorsCode = _formatAsList( 610 String classMirrorsCode = _formatAsList(
593 "m.ClassMirror", 611 "m.ClassMirror",
594 _capabilities._impliesTypes 612 _capabilities._impliesTypes
595 ? classes.domains.map((_ClassDomain classDomain) => 613 ? classes.domains.map((_ClassDomain classDomain) =>
596 _classMirrorCode(classDomain, fields, members, libraries, 614 _classMirrorCode(
597 importCollector, logger)) 615 classDomain,
616 fields,
617 fieldsOffset,
618 methodsOffset,
619 members,
620 libraries,
621 libraryMap,
622 importCollector,
623 logger))
598 : <String>[]); 624 : <String>[]);
599 625
600 // Generate code for creation of getter and setter closures. 626 // Generate code for creation of getter and setter closures.
601 String gettersCode = _formatAsMap(instanceGetterNames.map(_gettingClosure)); 627 String gettersCode = _formatAsMap(instanceGetterNames.map(_gettingClosure));
602 String settersCode = _formatAsMap(instanceSetterNames.map(_settingClosure)); 628 String settersCode = _formatAsMap(instanceSetterNames.map(_settingClosure));
603 629
604 bool reflectedTypeRequested = _capabilities._impliesReflectedType; 630 bool reflectedTypeRequested = _capabilities._impliesReflectedType;
605 631
606 // Generate code for creation of member mirrors. 632 // Generate code for creation of member mirrors.
607 Iterable<String> methodsList = 633 Iterable<String> methodsList =
(...skipping 15 matching lines...) Expand all
623 _formatAsList("Type", classes.map((ClassElement classElement) { 649 _formatAsList("Type", classes.map((ClassElement classElement) {
624 return _typeCodeOfClass(classElement, importCollector); 650 return _typeCodeOfClass(classElement, importCollector);
625 })); 651 }));
626 652
627 // Generate code for creation of library mirrors. 653 // Generate code for creation of library mirrors.
628 String librariesCode; 654 String librariesCode;
629 if (!_capabilities.supportsLibraries) { 655 if (!_capabilities.supportsLibraries) {
630 librariesCode = "null"; 656 librariesCode = "null";
631 } else { 657 } else {
632 librariesCode = _formatAsList("m.LibraryMirror", 658 librariesCode = _formatAsList("m.LibraryMirror",
633 libraries.items.map((LibraryElement library) { 659 libraries.items.map((_LibraryDomain library) {
634 return _libraryMirrorCode(library, importCollector, logger); 660 return _libraryMirrorCode(library, members, topLevelVariables,
661 fields.length, importCollector, logger);
635 })); 662 }));
636 } 663 }
637 664
638 // Generate code for creation of parameter mirrors. 665 // Generate code for creation of parameter mirrors.
639 Iterable<String> parametersList = 666 Iterable<String> parametersList =
640 parameters.items.map((ParameterElement element) { 667 parameters.items.map((ParameterElement element) {
641 return _parameterMirrorCode(element, fields, members, importCollector, 668 return _parameterMirrorCode(element, fields, members, importCollector,
642 logger, reflectedTypeRequested); 669 logger, reflectedTypeRequested);
643 }); 670 });
644 String parameterMirrorsCode = 671 String parameterMirrorsCode =
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
679 int _computeReturnTypeIndex(ExecutableElement element, int descriptor) { 706 int _computeReturnTypeIndex(ExecutableElement element, int descriptor) {
680 if (!_capabilities._impliesTypes) return constants.NO_CAPABILITY_INDEX; 707 if (!_capabilities._impliesTypes) return constants.NO_CAPABILITY_INDEX;
681 int result = _computeTypeIndexBase( 708 int result = _computeTypeIndexBase(
682 element.returnType.element, 709 element.returnType.element,
683 descriptor & constants.voidReturnTypeAttribute != 0, 710 descriptor & constants.voidReturnTypeAttribute != 0,
684 descriptor & constants.dynamicReturnTypeAttribute != 0, 711 descriptor & constants.dynamicReturnTypeAttribute != 0,
685 descriptor & constants.classReturnTypeAttribute != 0); 712 descriptor & constants.classReturnTypeAttribute != 0);
686 return result; 713 return result;
687 } 714 }
688 715
689 Iterable<PropertyAccessorElement> _gettersOfLibrary(LibraryElement library) { 716 Iterable<ExecutableElement> _gettersOfLibrary(_LibraryDomain library) sync* {
690 return library.units.map((CompilationUnitElement part) { 717 yield* library._accessors
691 Iterable<Element> getters = <Iterable<Element>>[ 718 .where((PropertyAccessorElement accessor) => accessor.isGetter);
692 part.accessors 719 yield* library._declaredFunctions;
693 .where((PropertyAccessorElement accessor) => accessor.isGetter),
694 part.functions,
695 part.topLevelVariables
696 ].expand((Iterable<Element> elements) => elements);
697 return getters.where((Element getter) =>
698 _capabilities.supportsTopLevelInvoke(getter.name, getter.metadata));
699 }).expand((Iterable<Element> x) => x);
700 } 720 }
701 721
702 Iterable<PropertyAccessorElement> _settersOfLibrary(LibraryElement library) { 722 Iterable<PropertyAccessorElement> _settersOfLibrary(_LibraryDomain library) {
703 return library.units.map((CompilationUnitElement part) { 723 return library._accessors
704 Iterable setters = <Iterable<Element>>[ 724 .where((PropertyAccessorElement accessor) => accessor.isSetter);
705 part.accessors
706 .where((PropertyAccessorElement accessor) => accessor.isSetter),
707 part.topLevelVariables
708 .where((TopLevelVariableElement variable) => !variable.isFinal)
709 ].expand((Iterable<Element> elements) => elements);
710 return setters.where((Element setter) =>
711 _capabilities.supportsTopLevelInvoke(setter.name, setter.metadata));
712 }).expand((Iterable<Element> x) => x);
713 } 725 }
714 726
715 String _classMirrorCode( 727 String _classMirrorCode(
716 _ClassDomain classDomain, 728 _ClassDomain classDomain,
717 Enumerator<FieldElement> fields, 729 Enumerator<FieldElement> fields,
730 int fieldsOffset,
731 int methodsOffset,
718 Enumerator<ExecutableElement> members, 732 Enumerator<ExecutableElement> members,
719 Enumerator<LibraryElement> libraries, 733 Enumerator<_LibraryDomain> libraries,
734 Map<LibraryElement, _LibraryDomain> libraryMap,
720 _ImportCollector importCollector, 735 _ImportCollector importCollector,
721 TransformLogger logger) { 736 TransformLogger logger) {
737 int descriptor = _classDescriptor(classDomain._classElement);
738
722 // Fields go first in [memberMirrors], so they will get the 739 // Fields go first in [memberMirrors], so they will get the
723 // same index as in [fields]. 740 // same index as in [fields].
724 Iterable<int> fieldsIndices = 741 Iterable<int> fieldsIndices =
725 classDomain._declaredFields.map((FieldElement element) { 742 classDomain._declaredFields.map((FieldElement element) {
726 return fields.indexOf(element); 743 return fields.indexOf(element) + fieldsOffset;
727 }); 744 });
728 745
729 // All the elements in the behavioral interface go after the 746 // All the elements in the behavioral interface go after the
730 // fields in [memberMirrors], so they must get an offset of 747 // fields in [memberMirrors], so they must get an offset of
731 // `fields.length` on the index. 748 // `fields.length` on the index.
732 Iterable<int> methodsIndices = classDomain._declarations 749 Iterable<int> methodsIndices = classDomain._declarations
733 .where(_executableIsntImplicitGetterOrSetter) 750 .where(_executableIsntImplicitGetterOrSetter)
734 .map((ExecutableElement element) { 751 .map((ExecutableElement element) {
735 // TODO(eernst) implement: The "magic" default constructor in `Object` 752 // TODO(eernst) implement: The "magic" default constructor in `Object`
736 // (the one that ultimately allocates the memory for _every_ new 753 // (the one that ultimately allocates the memory for _every_ new
737 // object) has no index, which creates the need to catch a `null` 754 // object) has no index, which creates the need to catch a `null`
738 // here. Search for "magic" to find other occurrences of the same 755 // here. Search for "magic" to find other occurrences of the same
739 // issue. For now, we use the index [constants.NO_CAPABILITY_INDEX] 756 // issue. For now, we use the index [constants.NO_CAPABILITY_INDEX]
740 // for this declaration, because it is not yet supported. 757 // for this declaration, because it is not yet supported.
741 // Need to find the correct solution, though! 758 // Need to find the correct solution, though!
742 int index = members.indexOf(element); 759 int index = members.indexOf(element);
743 return index == null 760 return index == null
744 ? constants.NO_CAPABILITY_INDEX 761 ? constants.NO_CAPABILITY_INDEX
745 : index + fields.length; 762 : index + methodsOffset;
746 }); 763 });
747 764
748 String declarationsCode = "<int>[${constants 765 String declarationsCode = _capabilities._impliesDeclarations
749 .NO_CAPABILITY_INDEX}]"; 766 ? _formatAsList(
750 if (_capabilities._impliesDeclarations) { 767 "int",
751 List<int> declarationsIndices = <int>[] 768 () sync* {
752 ..addAll(fieldsIndices) 769 yield* fieldsIndices;
753 ..addAll(methodsIndices); 770 yield* methodsIndices;
754 declarationsCode = _formatAsList("int", declarationsIndices); 771 }())
755 } 772 : "<int>[${constants.NO_CAPABILITY_INDEX}]";
756 773
757 // All instance members belong to the behavioral interface, so they 774 // All instance members belong to the behavioral interface, so they
758 // also get an offset of `fields.length`. 775 // also get an offset of `fields.length`.
759 String instanceMembersCode = _formatAsList("int", 776 String instanceMembersCode = _formatAsList("int",
760 classDomain._instanceMembers.map((ExecutableElement element) { 777 classDomain._instanceMembers.map((ExecutableElement element) {
761 // TODO(eernst) implement: The "magic" default constructor has 778 // TODO(eernst) implement: The "magic" default constructor has
762 // index: NO_CAPABILITY_INDEX; adjust this when support for it has 779 // index: NO_CAPABILITY_INDEX; adjust this when support for it has
763 // been implemented. 780 // been implemented.
764 int index = members.indexOf(element); 781 int index = members.indexOf(element);
765 return index == null 782 return index == null
766 ? constants.NO_CAPABILITY_INDEX 783 ? constants.NO_CAPABILITY_INDEX
767 : index + fields.length; 784 : index + methodsOffset;
768 })); 785 }));
769 786
770 // All static members belong to the behavioral interface, so they 787 // All static members belong to the behavioral interface, so they
771 // also get an offset of `fields.length`. 788 // also get an offset of `fields.length`.
772 String staticMembersCode = _formatAsList("int", 789 String staticMembersCode = _formatAsList("int",
773 classDomain._staticMembers.map((ExecutableElement element) { 790 classDomain._staticMembers.map((ExecutableElement element) {
774 int index = members.indexOf(element); 791 int index = members.indexOf(element);
775 return index == null 792 return index == null
776 ? constants.NO_CAPABILITY_INDEX 793 ? constants.NO_CAPABILITY_INDEX
777 : index + fields.length; 794 : index + methodsOffset;
778 })); 795 }));
779 796
780 ClassElement classElement = classDomain._classElement; 797 ClassElement classElement = classDomain._classElement;
781 ClassElement superclass = classes.superclassOf(classElement); 798 ClassElement superclass = classes.superclassOf(classElement);
782 // [Object]'s superclass is reported as `null`: it does not exist and 799 // [Object]'s superclass is reported as `null`: it does not exist and
783 // hence we cannot decide whether it's supported or unsupported; by 800 // hence we cannot decide whether it's supported or unsupported; by
784 // convention we make it supported and report it in the same way as 801 // convention we make it supported and report it in the same way as
785 // 'dart:mirrors'. Other superclasses use `NO_CAPABILITY_INDEX` to 802 // 'dart:mirrors'. Other superclasses use `NO_CAPABILITY_INDEX` to
786 // indicate missing support. 803 // indicate missing support.
787 String superclassIndex = (classElement is! MixinApplication && 804 String superclassIndex = (classElement is! MixinApplication &&
(...skipping 13 matching lines...) Expand all
801 return 'r"${constructor.name}": $code'; 818 return 'r"${constructor.name}": $code';
802 })); 819 }));
803 } 820 }
804 821
805 String staticGettersCode = "{}"; 822 String staticGettersCode = "{}";
806 String staticSettersCode = "{}"; 823 String staticSettersCode = "{}";
807 if (classElement is! MixinApplication) { 824 if (classElement is! MixinApplication) {
808 staticGettersCode = _formatAsMap([ 825 staticGettersCode = _formatAsMap([
809 classDomain._declaredMethods 826 classDomain._declaredMethods
810 .where((ExecutableElement element) => element.isStatic), 827 .where((ExecutableElement element) => element.isStatic),
811 classDomain._declaredAndImplicitAccessors.where( 828 classDomain._accessors.where((PropertyAccessorElement element) =>
812 (PropertyAccessorElement element) => 829 element.isStatic && element.isGetter)
813 element.isStatic && element.isGetter)
814 ].expand((x) => x).map((ExecutableElement element) => 830 ].expand((x) => x).map((ExecutableElement element) =>
815 _staticGettingClosure(importCollector, classElement, element.name))); 831 _staticGettingClosure(importCollector, classElement, element.name)));
816 staticSettersCode = _formatAsMap(classDomain._declaredAndImplicitAccessors 832 staticSettersCode = _formatAsMap(classDomain._accessors
817 .where((PropertyAccessorElement element) => 833 .where((PropertyAccessorElement element) =>
818 element.isStatic && element.isSetter) 834 element.isStatic && element.isSetter)
819 .map((PropertyAccessorElement element) => _staticSettingClosure( 835 .map((PropertyAccessorElement element) => _staticSettingClosure(
820 importCollector, classElement, element.name))); 836 importCollector, classElement, element.name)));
821 } 837 }
822 838
823 int mixinIndex; 839 int mixinIndex;
824 if (classElement.isMixinApplication) { 840 if (classElement.isMixinApplication) {
825 // Named mixin application (using the syntax `class B = A with M;`). 841 // Named mixin application (using the syntax `class B = A with M;`).
826 mixinIndex = classes.indexOf(classElement.mixins.last.element); 842 mixinIndex = classes.indexOf(classElement.mixins.last.element);
827 } else { 843 } else {
828 mixinIndex = (classElement is MixinApplication) 844 mixinIndex = (classElement is MixinApplication)
829 ? classes.indexOf(classElement.mixin) 845 ? classes.indexOf(classElement.mixin)
830 : classes.indexOf(classElement); 846 : classes.indexOf(classElement);
831 } 847 }
832 if (mixinIndex == null) mixinIndex = constants.NO_CAPABILITY_INDEX; 848 if (mixinIndex == null) mixinIndex = constants.NO_CAPABILITY_INDEX;
833 849
834 int ownerIndex = _capabilities.supportsLibraries 850 int ownerIndex = _capabilities.supportsLibraries
835 ? libraries.indexOf(classElement.library) 851 ? libraries.indexOf(libraryMap[classElement.library])
836 : constants.NO_CAPABILITY_INDEX; 852 : constants.NO_CAPABILITY_INDEX;
837 853
838 String superinterfaceIndices = _formatAsList( 854 String superinterfaceIndices = _formatAsList(
839 'int', 855 'int',
840 classElement.interfaces 856 classElement.interfaces
841 .map((InterfaceType type) => type.element) 857 .map((InterfaceType type) => type.element)
842 .where(classes.contains) 858 .where(classes.contains)
843 .map(classes.indexOf)); 859 .map(classes.indexOf));
844 860
845 String classMetadataCode; 861 String classMetadataCode;
846 if (_capabilities._supportsMetadata) { 862 if (_capabilities._supportsMetadata) {
847 classMetadataCode = _extractMetadataCode(classElement, _resolver, 863 classMetadataCode = _extractMetadataCode(classElement, _resolver,
848 importCollector, logger, _generatedLibraryId); 864 importCollector, logger, _generatedLibraryId);
849 } else { 865 } else {
850 classMetadataCode = "null"; 866 classMetadataCode = "null";
851 } 867 }
852 868
853 int classIndex = classes.indexOf(classElement); 869 int classIndex = classes.indexOf(classElement);
854 870
855 String result = 'new r.ClassMirrorImpl(r"${classDomain._simpleName}", ' 871 String result = 'new r.ClassMirrorImpl(r"${classDomain._simpleName}", '
856 'r"${_qualifiedName(classElement)}", $classIndex, ' 872 'r"${_qualifiedName(classElement)}", $descriptor, $classIndex, '
857 '${_constConstructionCode(importCollector)}, ' 873 '${_constConstructionCode(importCollector)}, '
858 '$declarationsCode, $instanceMembersCode, $staticMembersCode, ' 874 '$declarationsCode, $instanceMembersCode, $staticMembersCode, '
859 '$superclassIndex, $staticGettersCode, $staticSettersCode, ' 875 '$superclassIndex, $staticGettersCode, $staticSettersCode, '
860 '$constructorsCode, $ownerIndex, $mixinIndex, ' 876 '$constructorsCode, $ownerIndex, $mixinIndex, '
861 '$superinterfaceIndices, $classMetadataCode)'; 877 '$superinterfaceIndices, $classMetadataCode)';
862 return result; 878 return result;
863 } 879 }
864 880
865 String _methodMirrorCode( 881 String _methodMirrorCode(
866 ExecutableElement element, 882 ExecutableElement element,
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
943 '${dartType.element}")'; 959 '${dartType.element}")';
944 } 960 }
945 return _typeCodeOfClass(dartType.element, importCollector); 961 return _typeCodeOfClass(dartType.element, importCollector);
946 } 962 }
947 963
948 String _typeCodeOfClass( 964 String _typeCodeOfClass(
949 ClassElement classElement, _ImportCollector importCollector) { 965 ClassElement classElement, _ImportCollector importCollector) {
950 if (classElement is MixinApplication && classElement.declaredName == null) { 966 if (classElement is MixinApplication && classElement.declaredName == null) {
951 return 'new r.FakeType(r"${_qualifiedName(classElement)}")'; 967 return 'new r.FakeType(r"${_qualifiedName(classElement)}")';
952 } 968 }
953 if (classElement is! MixinApplication && classElement.type.isDynamic) { 969 if (classElement.type.isDynamic) return "dynamic";
954 return "dynamic";
955 }
956 String prefix = importCollector._getPrefix(classElement.library); 970 String prefix = importCollector._getPrefix(classElement.library);
957 return "$prefix.${classElement.name}"; 971 return "$prefix.${classElement.name}";
958 } 972 }
959 973
960 String _libraryMirrorCode(LibraryElement library, 974 String _libraryMirrorCode(
961 _ImportCollector importCollector, TransformLogger logger) { 975 _LibraryDomain libraryDomain,
976 Enumerator<ExecutableElement> members,
977 Enumerator<TopLevelVariableElement> variables,
978 int fieldsLength,
979 _ImportCollector importCollector,
980 TransformLogger logger) {
981 LibraryElement library = libraryDomain._libraryElement;
982
962 String gettersCode = _formatAsMap( 983 String gettersCode = _formatAsMap(
963 _gettersOfLibrary(library).map((PropertyAccessorElement getter) { 984 _gettersOfLibrary(libraryDomain).map((PropertyAccessorElement getter) {
964 return _topLevelGettingClosure(importCollector, library, getter.name); 985 return _topLevelGettingClosure(importCollector, library, getter.name);
965 })); 986 }));
987
966 String settersCode = _formatAsMap( 988 String settersCode = _formatAsMap(
967 _settersOfLibrary(library).map((PropertyAccessorElement setter) { 989 _settersOfLibrary(libraryDomain).map((PropertyAccessorElement setter) {
968 return topLevelSettingClosure(importCollector, library, setter.name); 990 return topLevelSettingClosure(importCollector, library, setter.name);
969 })); 991 }));
970 992
993 // Fields go first in [memberMirrors], so they will get the
994 // same index as in [fields].
995 Iterable<int> variableIndices =
996 libraryDomain._declaredVariables.map((TopLevelVariableElement element) {
997 return variables.indexOf(element);
998 });
999
1000 // All the elements in the behavioral interface go after the
1001 // fields in [memberMirrors], so they must get an offset of
1002 // `fields.length` on the index.
1003 Iterable<int> methodsIndices = libraryDomain._declarations
1004 .where(_executableIsntImplicitGetterOrSetter)
1005 .map((ExecutableElement element) {
1006 int index = members.indexOf(element);
1007 return index + fieldsLength;
1008 });
1009
1010 String declarationsCode = "<int>[${constants.NO_CAPABILITY_INDEX}]";
1011 if (_capabilities._impliesDeclarations) {
1012 List<int> declarationsIndices = <int>[]
1013 ..addAll(variableIndices)
1014 ..addAll(methodsIndices);
1015 declarationsCode = _formatAsList("int", declarationsIndices);
1016 }
1017
971 // TODO(sigurdm) clarify: Find out how to get good uri's in a 1018 // TODO(sigurdm) clarify: Find out how to get good uri's in a
972 // transformer. 1019 // transformer.
973 // TODO(sigurdm) implement: Check for `uriCapability`. 1020 // TODO(sigurdm) implement: Check for `uriCapability`.
974 String uriCode = "null"; 1021 String uriCode = "null";
975 1022
976 String metadataCode; 1023 String metadataCode;
977 if (_capabilities._supportsMetadata) { 1024 if (_capabilities._supportsMetadata) {
978 metadataCode = _extractMetadataCode( 1025 metadataCode = _extractMetadataCode(
979 library, _resolver, importCollector, logger, _generatedLibraryId); 1026 library, _resolver, importCollector, logger, _generatedLibraryId);
980 } else { 1027 } else {
981 metadataCode = "null"; 1028 metadataCode = "null";
982 } 1029 }
983 1030
984 return 'new r.LibraryMirrorImpl(r"${library.name}", $uriCode, ' 1031 return 'new r.LibraryMirrorImpl(r"${library.name}", $uriCode, '
985 '$gettersCode, $settersCode, $metadataCode)'; 1032 '${_constConstructionCode(importCollector)}, '
1033 '$declarationsCode, $gettersCode, $settersCode, $metadataCode)';
986 } 1034 }
987 1035
988 String _parameterMirrorCode( 1036 String _parameterMirrorCode(
989 ParameterElement element, 1037 ParameterElement element,
990 Enumerator<FieldElement> fields, 1038 Enumerator<FieldElement> fields,
991 Enumerator<ExecutableElement> members, 1039 Enumerator<ExecutableElement> members,
992 _ImportCollector importCollector, 1040 _ImportCollector importCollector,
993 TransformLogger logger, 1041 TransformLogger logger,
994 bool reflectedTypeRequested) { 1042 bool reflectedTypeRequested) {
995 int descriptor = _parameterDescriptor(element); 1043 int descriptor = _parameterDescriptor(element);
(...skipping 302 matching lines...) Expand 10 before | Expand all | Expand 10 after
1298 closure = "(dynamic instance) => () => ~instance"; 1346 closure = "(dynamic instance) => () => ~instance";
1299 } else { 1347 } else {
1300 closure = "(dynamic instance) => (x) => instance ${getterName} x"; 1348 closure = "(dynamic instance) => (x) => instance ${getterName} x";
1301 } 1349 }
1302 return 'r"${getterName}": $closure'; 1350 return 'r"${getterName}": $closure';
1303 } 1351 }
1304 1352
1305 // Auxiliary function used by `_generateCode`. 1353 // Auxiliary function used by `_generateCode`.
1306 String _settingClosure(String setterName) { 1354 String _settingClosure(String setterName) {
1307 assert(setterName.substring(setterName.length - 1) == "="); 1355 assert(setterName.substring(setterName.length - 1) == "=");
1308 // The [setterName] includes the "=", remove it.
1309 String name = setterName.substring(0, setterName.length - 1); 1356 String name = setterName.substring(0, setterName.length - 1);
1310 1357 return 'r"$setterName": (dynamic instance, value) => instance.$name = value';
1311 return 'r"$setterName": (dynamic instance, value) => '
1312 'instance.$name = value';
1313 } 1358 }
1314 1359
1315 // Auxiliary function used by `_generateCode`. 1360 // Auxiliary function used by `_generateCode`.
1316 String _staticGettingClosure(_ImportCollector importCollector, 1361 String _staticGettingClosure(_ImportCollector importCollector,
1317 ClassElement classElement, String getterName) { 1362 ClassElement classElement, String getterName) {
1318 String className = classElement.name; 1363 String className = classElement.name;
1319 String prefix = importCollector._getPrefix(classElement.library); 1364 String prefix = importCollector._getPrefix(classElement.library);
1320 // Operators cannot be static. 1365 // Operators cannot be static.
1321 return 'r"${getterName}": () => $prefix.$className.$getterName'; 1366 return 'r"${getterName}": () => $prefix.$className.$getterName';
1322 } 1367 }
(...skipping 20 matching lines...) Expand all
1343 // Auxiliary function used by `_generateCode`. 1388 // Auxiliary function used by `_generateCode`.
1344 String topLevelSettingClosure(_ImportCollector importCollector, 1389 String topLevelSettingClosure(_ImportCollector importCollector,
1345 LibraryElement library, String setterName) { 1390 LibraryElement library, String setterName) {
1346 assert(setterName.substring(setterName.length - 1) == "="); 1391 assert(setterName.substring(setterName.length - 1) == "=");
1347 // The [setterName] includes the "=", remove it. 1392 // The [setterName] includes the "=", remove it.
1348 String name = setterName.substring(0, setterName.length - 1); 1393 String name = setterName.substring(0, setterName.length - 1);
1349 String prefix = importCollector._getPrefix(library); 1394 String prefix = importCollector._getPrefix(library);
1350 return 'r"$setterName": (value) => $prefix.$name = value'; 1395 return 'r"$setterName": (value) => $prefix.$name = value';
1351 } 1396 }
1352 1397
1398 /// Information about reflectability for a given library.
1399 class _LibraryDomain {
1400 /// Element describing the target library.
1401 final LibraryElement _libraryElement;
1402
1403 /// Fields declared by [_libraryElement] and included for reflection support,
1404 /// according to the reflector described by the [_reflectorDomain];
1405 /// obtained by filtering `_libraryElement.fields`.
1406 final Iterable<TopLevelVariableElement> _declaredVariables;
1407
1408 /// Methods which are declared by [_libraryElement] and included for
1409 /// reflection support, according to the reflector described by
1410 /// [_reflectorDomain]; obtained by filtering `_libraryElement.functions`.
1411 final Iterable<FunctionElement> _declaredFunctions;
1412
1413 /// Formal parameters declared by one of the [_declaredFunctions].
1414 final Iterable<ParameterElement> _declaredParameters;
1415
1416 /// Getters and setters possessed by [_libraryElement] and included for
1417 /// reflection support, according to the reflector described by
1418 /// [_reflectorDomain]; obtained by filtering `_libraryElement.accessors`.
1419 /// Note that it includes declared as well as synthetic accessors, implicitly
1420 /// created as getters/setters for fields.
1421 final Iterable<PropertyAccessorElement> _accessors;
1422
1423 /// The reflector domain that holds [this] object as one of its
1424 /// library domains.
1425 final _ReflectorDomain _reflectorDomain;
1426
1427 _LibraryDomain(
1428 this._libraryElement,
1429 this._declaredVariables,
1430 this._declaredFunctions,
1431 this._declaredParameters,
1432 this._accessors,
1433 this._reflectorDomain);
1434
1435 String get _simpleName {
1436 return _libraryElement.name;
1437 }
1438
1439 /// Returns the declared methods, accessors and constructors in
1440 /// [_classElement]. Note that this includes synthetic getters and
1441 /// setters, and omits fields; in other words, it provides the
1442 /// behavioral point of view on the class. Also note that this is not
1443 /// the same semantics as that of `declarations` in [ClassMirror].
1444 Iterable<ExecutableElement> get _declarations sync* {
1445 yield* _declaredFunctions;
1446 yield* _accessors;
1447 }
1448
1449 String toString() {
1450 return "LibraryDomain($_libraryElement)";
1451 }
1452
1453 bool operator ==(Object other) {
1454 if (other is _LibraryDomain) {
1455 return _libraryElement == other._libraryElement &&
1456 _reflectorDomain == other._reflectorDomain;
1457 } else {
1458 return false;
1459 }
1460 }
1461
1462 int get hashCode => _libraryElement.hashCode ^ _reflectorDomain.hashCode;
1463 }
1464
1353 /// Information about reflectability for a given class. 1465 /// Information about reflectability for a given class.
1354 class _ClassDomain { 1466 class _ClassDomain {
1355 /// Element describing the target class. 1467 /// Element describing the target class.
1356 final ClassElement _classElement; 1468 final ClassElement _classElement;
1357 1469
1358 /// Fields declared by [classElement] and included for reflection support, 1470 /// Fields declared by [_classElement] and included for reflection support,
1359 /// according to the reflector described by the [reflectorDomain]; 1471 /// according to the reflector described by the [_reflectorDomain];
1360 /// obtained by filtering `classElement.fields`. 1472 /// obtained by filtering `_classElement.fields`.
1361 final Iterable<FieldElement> _declaredFields; 1473 final Iterable<FieldElement> _declaredFields;
1362 1474
1363 /// Methods which are declared by [classElement] and included for 1475 /// Methods which are declared by [_classElement] and included for
1364 /// reflection support, according to the reflector described by 1476 /// reflection support, according to the reflector described by
1365 /// [reflectorDomain]; obtained by filtering `classElement.methods`. 1477 /// [reflectorDomain]; obtained by filtering `_classElement.methods`.
1366 final Iterable<MethodElement> _declaredMethods; 1478 final Iterable<MethodElement> _declaredMethods;
1367 1479
1368 /// Formal parameters declared by one of the [_declaredMethods]. 1480 /// Formal parameters declared by one of the [_declaredMethods].
1369 final Iterable<ParameterElement> _declaredParameters; 1481 final Iterable<ParameterElement> _declaredParameters;
1370 1482
1371 /// Getters and setters possessed by [classElement] and included for 1483 /// Getters and setters possessed by [_classElement] and included for
1372 /// reflection support, according to the reflector described by 1484 /// reflection support, according to the reflector described by
1373 /// [reflectorDomain]; obtained by filtering `classElement.accessors`. 1485 /// [reflectorDomain]; obtained by filtering `_classElement.accessors`.
1374 /// Note that it includes declared as well as synthetic accessors, 1486 /// Note that it includes declared as well as synthetic accessors,
1375 /// implicitly created as getters/setters for fields. 1487 /// implicitly created as getters/setters for fields.
1376 final Iterable<PropertyAccessorElement> _declaredAndImplicitAccessors; 1488 final Iterable<PropertyAccessorElement> _accessors;
1377 1489
1378 /// Constructors declared by [classElement] and included for reflection 1490 /// Constructors declared by [_classElement] and included for reflection
1379 /// support, according to the reflector described by [reflectorDomain]; 1491 /// support, according to the reflector described by [_reflectorDomain];
1380 /// obtained by filtering `classElement.constructors`. 1492 /// obtained by filtering `_classElement.constructors`.
1381 final Iterable<ConstructorElement> _constructors; 1493 final Iterable<ConstructorElement> _constructors;
1382 1494
1383 /// The reflector domain that holds [this] object as one of its 1495 /// The reflector domain that holds [this] object as one of its
1384 /// class domains. 1496 /// class domains.
1385 final _ReflectorDomain _reflectorDomain; 1497 final _ReflectorDomain _reflectorDomain;
1386 1498
1387 _ClassDomain( 1499 _ClassDomain(
1388 this._classElement, 1500 this._classElement,
1389 this._declaredFields, 1501 this._declaredFields,
1390 this._declaredMethods, 1502 this._declaredMethods,
1391 this._declaredParameters, 1503 this._declaredParameters,
1392 this._declaredAndImplicitAccessors, 1504 this._accessors,
1393 this._constructors, 1505 this._constructors,
1394 this._reflectorDomain); 1506 this._reflectorDomain);
1395 1507
1396 String get _simpleName { 1508 String get _simpleName {
1397 // TODO(eernst) clarify: Decide whether this should be simplified 1509 // TODO(eernst) clarify: Decide whether this should be simplified
1398 // by adding a method implementation to `MixinApplication`. 1510 // by adding a method implementation to `MixinApplication`.
1399 if (_classElement.isMixinApplication) { 1511 if (_classElement.isMixinApplication) {
1400 // This is the case `class B = A with M;`. 1512 // This is the case `class B = A with M;`.
1401 return _classElement.name; 1513 return _classElement.name;
1402 } else if (_classElement is MixinApplication) { 1514 } else if (_classElement is MixinApplication) {
(...skipping 19 matching lines...) Expand all
1422 } 1534 }
1423 } 1535 }
1424 1536
1425 /// Returns the declared methods, accessors and constructors in 1537 /// Returns the declared methods, accessors and constructors in
1426 /// [_classElement]. Note that this includes synthetic getters and 1538 /// [_classElement]. Note that this includes synthetic getters and
1427 /// setters, and omits fields; in other words, it provides the 1539 /// setters, and omits fields; in other words, it provides the
1428 /// behavioral point of view on the class. Also note that this is not 1540 /// behavioral point of view on the class. Also note that this is not
1429 /// the same semantics as that of `declarations` in [ClassMirror]. 1541 /// the same semantics as that of `declarations` in [ClassMirror].
1430 Iterable<ExecutableElement> get _declarations { 1542 Iterable<ExecutableElement> get _declarations {
1431 // TODO(sigurdm) feature: Include type variables (if we keep them). 1543 // TODO(sigurdm) feature: Include type variables (if we keep them).
1432 return [_declaredMethods, _declaredAndImplicitAccessors, _constructors] 1544 return [_declaredMethods, _accessors, _constructors].expand((x) => x);
1433 .expand((x) => x);
1434 } 1545 }
1435 1546
1436 /// Finds all instance members by going through the class hierarchy. 1547 /// Finds all instance members by going through the class hierarchy.
1437 Iterable<ExecutableElement> get _instanceMembers { 1548 Iterable<ExecutableElement> get _instanceMembers {
1438 Map<String, ExecutableElement> helper(ClassElement classElement) { 1549 Map<String, ExecutableElement> helper(ClassElement classElement) {
1439 if (_reflectorDomain._instanceMemberCache[classElement] != null) { 1550 if (_reflectorDomain._instanceMemberCache[classElement] != null) {
1440 return _reflectorDomain._instanceMemberCache[classElement]; 1551 return _reflectorDomain._instanceMemberCache[classElement];
1441 } 1552 }
1442 Map<String, ExecutableElement> result = 1553 Map<String, ExecutableElement> result =
1443 new Map<String, ExecutableElement>(); 1554 new Map<String, ExecutableElement>();
(...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after
1634 // Handle API based capabilities. 1745 // Handle API based capabilities.
1635 if ((capability is ec.TopLevelInvokeCapability) && 1746 if ((capability is ec.TopLevelInvokeCapability) &&
1636 _supportsName(capability, methodName)) { 1747 _supportsName(capability, methodName)) {
1637 return true; 1748 return true;
1638 } 1749 }
1639 if ((capability is ec.TopLevelInvokeMetaCapability) && 1750 if ((capability is ec.TopLevelInvokeMetaCapability) &&
1640 _supportsMeta(capability, metadata)) { 1751 _supportsMeta(capability, metadata)) {
1641 return true; 1752 return true;
1642 } 1753 }
1643 // Quantifying capabilities do not influence the availability 1754 // Quantifying capabilities do not influence the availability
1644 // of reflection support for top level invocation. 1755 // of reflection support for top-level invocation.
1645 } 1756 }
1646 1757
1647 // All options exhausted, give up. 1758 // All options exhausted, give up.
1648 return false; 1759 return false;
1649 } 1760 }
1650 1761
1651 bool _supportsStaticInvoke(List<ec.ReflectCapability> capabilities, 1762 bool _supportsStaticInvoke(List<ec.ReflectCapability> capabilities,
1652 String methodName, Iterable<DartObject> metadata) { 1763 String methodName, Iterable<DartObject> metadata) {
1653 for (ec.ReflectCapability capability in capabilities) { 1764 for (ec.ReflectCapability capability in capabilities) {
1654 // Handle API based capabilities. 1765 // Handle API based capabilities.
(...skipping 280 matching lines...) Expand 10 before | Expand all | Expand 10 after
1935 // types (types whose name does not end in `..Impl`) declare the getter 2046 // types (types whose name does not end in `..Impl`) declare the getter
1936 // `evaluationResult`. Another possible choice of type would be 2047 // `evaluationResult`. Another possible choice of type would be
1937 // [VariableElementImpl], but with that one we would have to test 2048 // [VariableElementImpl], but with that one we would have to test
1938 // `isConst` as well. 2049 // `isConst` as well.
1939 if (variable is ConstTopLevelVariableElementImpl) { 2050 if (variable is ConstTopLevelVariableElementImpl) {
1940 EvaluationResultImpl result = variable.evaluationResult; 2051 EvaluationResultImpl result = variable.evaluationResult;
1941 if (result.value == null) return null; // Errors during evaluation. 2052 if (result.value == null) return null; // Errors during evaluation.
1942 bool isOk = checkInheritance(result.value.type, focusClass.type); 2053 bool isOk = checkInheritance(result.value.type, focusClass.type);
1943 return isOk ? result.value.type.element : null; 2054 return isOk ? result.value.type.element : null;
1944 } else { 2055 } else {
1945 // Not a const top level variable, not relevant. 2056 // Not a const top-level variable, not relevant.
1946 return null; 2057 return null;
1947 } 2058 }
1948 } 2059 }
1949 // Otherwise [element] is some other construct which is not supported. 2060 // Otherwise [element] is some other construct which is not supported.
1950 // 2061 //
1951 // TODO(eernst) clarify: We need to consider whether there could be some 2062 // TODO(eernst) clarify: We need to consider whether there could be some
1952 // other syntactic constructs that are incorrectly assumed by programmers 2063 // other syntactic constructs that are incorrectly assumed by programmers
1953 // to be usable with Reflectable. Currently, such constructs will silently 2064 // to be usable with Reflectable. Currently, such constructs will silently
1954 // have no effect; it might be better to emit a diagnostic message (a 2065 // have no effect; it might be better to emit a diagnostic message (a
1955 // hint?) in order to notify the programmer that "it does not work". 2066 // hint?) in order to notify the programmer that "it does not work".
(...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after
2126 } else { 2237 } else {
2127 _ReflectorDomain domain = getReflectorDomain(reflector); 2238 _ReflectorDomain domain = getReflectorDomain(reflector);
2128 if (!domain._classes.contains(type)) { 2239 if (!domain._classes.contains(type)) {
2129 if (type.isMixinApplication) { 2240 if (type.isMixinApplication) {
2130 // Iterate over all mixins in most-general-first order (so with 2241 // Iterate over all mixins in most-general-first order (so with
2131 // `class C extends B with M1, M2..` we visit `M1` then `M2`. 2242 // `class C extends B with M1, M2..` we visit `M1` then `M2`.
2132 ClassElement superclass = type.supertype.element; 2243 ClassElement superclass = type.supertype.element;
2133 for (InterfaceType mixin in type.mixins) { 2244 for (InterfaceType mixin in type.mixins) {
2134 ClassElement mixinElement = mixin.element; 2245 ClassElement mixinElement = mixin.element;
2135 ClassElement subClass = mixin == type.mixins.last ? type : null; 2246 ClassElement subClass = mixin == type.mixins.last ? type : null;
2136 String name = subClass == null ? null : type.name; 2247 String name = subClass == null
2248 ? null
2249 : (type.isMixinApplication ? type.name : null);
2137 MixinApplication mixinApplication = new MixinApplication( 2250 MixinApplication mixinApplication = new MixinApplication(
2138 name, superclass, mixinElement, type.library, subClass); 2251 name, superclass, mixinElement, type.library, subClass);
2139 domain._classes.add(mixinApplication); 2252 domain._classes.add(mixinApplication);
2140 superclass = mixinApplication; 2253 superclass = mixinApplication;
2141 } 2254 }
2142 } else { 2255 } else {
2143 domain._classes.add(type); 2256 domain._classes.add(type);
2144 } 2257 }
2145 addLibrary(type.library, reflector); 2258 addLibrary(type.library, reflector);
2146 // We need to ensure that the [importCollector] has indeed added 2259 // We need to ensure that the [importCollector] has indeed added
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
2214 addLibrary(library, reflector); 2327 addLibrary(library, reflector);
2215 } 2328 }
2216 2329
2217 for (CompilationUnitElement unit in library.units) { 2330 for (CompilationUnitElement unit in library.units) {
2218 for (ClassElement type in unit.types) { 2331 for (ClassElement type in unit.types) {
2219 for (ClassElement reflector 2332 for (ClassElement reflector
2220 in getReflectors(_qualifiedName(type), type.metadata)) { 2333 in getReflectors(_qualifiedName(type), type.metadata)) {
2221 addClassDomain(type, reflector); 2334 addClassDomain(type, reflector);
2222 } 2335 }
2223 } 2336 }
2337 for (FunctionElement function in unit.functions) {
2338 for (ClassElement reflector in getReflectors(
2339 _qualifiedFunctionName(function), function.metadata)) {
2340 // We just add the library here, the function itself will be
2341 // supported using `invoke` and `declarations` of that library
2342 // mirror.
2343 addLibrary(library, reflector);
2344 }
2345 }
2224 } 2346 }
2225 } 2347 }
2226 2348
2227 return new ReflectionWorld(_resolver, dataId, domains.values.toList(), 2349 return new ReflectionWorld(_resolver, dataId, domains.values.toList(),
2228 reflectableLibrary, entryPoint, importCollector); 2350 reflectableLibrary, entryPoint, importCollector);
2229 } 2351 }
2230 2352
2231 /// Returns the [ReflectCapability] denoted by the given [initializer]. 2353 /// Returns the [ReflectCapability] denoted by the given [initializer].
2232 ec.ReflectCapability _capabilityOfExpression(LibraryElement capabilityLibrary, 2354 ec.ReflectCapability _capabilityOfExpression(LibraryElement capabilityLibrary,
2233 Expression expression, LibraryElement containingLibrary) { 2355 Expression expression, LibraryElement containingLibrary) {
(...skipping 347 matching lines...) Expand 10 before | Expand all | Expand 10 after
2581 bool _accessorIsntImplicitGetterOrSetter(PropertyAccessorElement accessor) { 2703 bool _accessorIsntImplicitGetterOrSetter(PropertyAccessorElement accessor) {
2582 return !accessor.isSynthetic || (!accessor.isGetter && !accessor.isSetter); 2704 return !accessor.isSynthetic || (!accessor.isGetter && !accessor.isSetter);
2583 } 2705 }
2584 2706
2585 bool _executableIsntImplicitGetterOrSetter(ExecutableElement executable) { 2707 bool _executableIsntImplicitGetterOrSetter(ExecutableElement executable) {
2586 return executable is! PropertyAccessorElement || 2708 return executable is! PropertyAccessorElement ||
2587 _accessorIsntImplicitGetterOrSetter(executable); 2709 _accessorIsntImplicitGetterOrSetter(executable);
2588 } 2710 }
2589 2711
2590 /// Returns an integer encoding of the kind and attributes of the given 2712 /// Returns an integer encoding of the kind and attributes of the given
2713 /// class.
2714 int _classDescriptor(ClassElement element) {
2715 int result = constants.clazz;
2716 if (element.isPrivate) result |= constants.privateAttribute;
2717 if (element.isSynthetic) result |= constants.syntheticAttribute;
2718 if (element.isAbstract) result |= constants.abstractAttribute;
2719 if (element.isEnum) result |= constants.enumAttribute;
2720 return result;
2721 }
2722
2723 /// Returns an integer encoding of the kind and attributes of the given
2591 /// field. 2724 /// field.
2592 int _fieldDescriptor(FieldElement element) { 2725 int _fieldDescriptor(FieldElement element) {
2593 int result = constants.field; 2726 int result = constants.field;
2594 if (element.isPrivate) result |= constants.privateAttribute; 2727 if (element.isPrivate) result |= constants.privateAttribute;
2595 if (element.isSynthetic) result |= constants.syntheticAttribute; 2728 if (element.isSynthetic) result |= constants.syntheticAttribute;
2596 if (element.isConst) { 2729 if (element.isConst) {
2597 result |= constants.constAttribute; 2730 result |= constants.constAttribute;
2598 // We will get `false` from `element.isFinal` in this case, but with 2731 // We will get `false` from `element.isFinal` in this case, but with
2599 // a mirror from 'dart:mirrors' it is considered to be "implicitly 2732 // a mirror from 'dart:mirrors' it is considered to be "implicitly
2600 // final", so we follow that and ignore `element.isFinal`. 2733 // final", so we follow that and ignore `element.isFinal`.
(...skipping 332 matching lines...) Expand 10 before | Expand all | Expand 10 after
2933 metadataParts.add("const $prefix.$constructor($arguments)"); 3066 metadataParts.add("const $prefix.$constructor($arguments)");
2934 } else { 3067 } else {
2935 // A field reference. 3068 // A field reference.
2936 metadataParts.add("$prefix.${annotationNode.name}"); 3069 metadataParts.add("$prefix.${annotationNode.name}");
2937 } 3070 }
2938 } 3071 }
2939 3072
2940 return _formatAsList("Object", metadataParts); 3073 return _formatAsList("Object", metadataParts);
2941 } 3074 }
2942 3075
3076 /// Returns the top level variables declared in the given [libraryElement],
3077 /// filtering them such that the returned ones are those that are supported
3078 /// by [capabilities].
3079 Iterable<TopLevelVariableElement> _extractDeclaredVariables(
3080 LibraryElement libraryElement, _Capabilities capabilities) sync* {
3081 for (CompilationUnitElement unit in libraryElement.units) {
3082 for (TopLevelVariableElement variable in unit.topLevelVariables) {
3083 if (variable.isPrivate || variable.isSynthetic) continue;
3084 // TODO(eernst) clarify: Do we want to subsume variables under invoke?
3085 if (capabilities.supportsTopLevelInvoke(
3086 variable.name, variable.metadata)) {
3087 yield variable;
3088 }
3089 }
3090 }
3091 }
3092
3093 /// Returns the top level functions declared in the given [libraryElement],
3094 /// filtering them such that the returned ones are those that are supported
3095 /// by [capabilities].
3096 Iterable<FunctionElement> _extractDeclaredFunctions(
3097 LibraryElement libraryElement, _Capabilities capabilities) sync* {
3098 for (CompilationUnitElement unit in libraryElement.units) {
3099 for (FunctionElement function in unit.functions) {
3100 if (function.isPrivate) continue;
3101 if (capabilities.supportsTopLevelInvoke(
3102 function.name, function.metadata)) {
3103 yield function;
3104 }
3105 }
3106 }
3107 }
3108
3109 /// Returns the parameters declared in the given [declaredFunctions] as well
3110 /// as the setters from the given [accessors].
3111 Iterable<ParameterElement> _extractDeclaredFunctionParameters(
3112 Iterable<FunctionElement> declaredFunctions,
3113 Iterable<ExecutableElement> accessors) {
3114 List<ParameterElement> result = <ParameterElement>[];
3115 for (FunctionElement declaredFunction in declaredFunctions) {
3116 result.addAll(declaredFunction.parameters);
3117 }
3118 for (ExecutableElement accessor in accessors) {
3119 if (accessor is PropertyAccessorElement && accessor.isSetter) {
3120 result.addAll(accessor.parameters);
3121 }
3122 }
3123 return result;
3124 }
3125
3126 /// Returns the declared fields in the given [classElement], filtered such
3127 /// that the returned ones are the ones that are supported by [capabilities].
2943 Iterable<FieldElement> _extractDeclaredFields( 3128 Iterable<FieldElement> _extractDeclaredFields(
2944 ClassElement classElement, _Capabilities capabilities) { 3129 ClassElement classElement, _Capabilities capabilities) {
2945 return classElement.fields.where((FieldElement field) { 3130 return classElement.fields.where((FieldElement field) {
2946 if (field.isPrivate) return false; 3131 if (field.isPrivate) return false;
2947 Function capabilityChecker = field.isStatic 3132 Function capabilityChecker = field.isStatic
2948 ? capabilities.supportsStaticInvoke 3133 ? capabilities.supportsStaticInvoke
2949 : capabilities.supportsInstanceInvoke; 3134 : capabilities.supportsInstanceInvoke;
2950 return !field.isSynthetic && capabilityChecker(field.name, field.metadata); 3135 return !field.isSynthetic && capabilityChecker(field.name, field.metadata);
2951 }); 3136 });
2952 } 3137 }
2953 3138
3139 /// Returns the declared methods in the given [classElement], filtered such
3140 /// that the returned ones are the ones that are supported by [capabilities].
2954 Iterable<MethodElement> _extractDeclaredMethods( 3141 Iterable<MethodElement> _extractDeclaredMethods(
2955 ClassElement classElement, _Capabilities capabilities) { 3142 ClassElement classElement, _Capabilities capabilities) {
2956 return classElement.methods.where((MethodElement method) { 3143 return classElement.methods.where((MethodElement method) {
2957 if (method.isPrivate) return false; 3144 if (method.isPrivate) return false;
2958 Function capabilityChecker = method.isStatic 3145 Function capabilityChecker = method.isStatic
2959 ? capabilities.supportsStaticInvoke 3146 ? capabilities.supportsStaticInvoke
2960 : capabilities.supportsInstanceInvoke; 3147 : capabilities.supportsInstanceInvoke;
2961 return capabilityChecker(method.name, method.metadata); 3148 return capabilityChecker(method.name, method.metadata);
2962 }); 3149 });
2963 } 3150 }
2964 3151
3152 /// Returns the declared parameters in the given [declaredMethods] and
3153 /// [declaredConstructors], as well as the ones from the setters in
3154 /// [accessors].
2965 Iterable<ParameterElement> _extractDeclaredParameters( 3155 Iterable<ParameterElement> _extractDeclaredParameters(
2966 Iterable<MethodElement> declaredMethods, 3156 Iterable<MethodElement> declaredMethods,
2967 Iterable<ConstructorElement> declaredConstructors, 3157 Iterable<ConstructorElement> declaredConstructors,
2968 Iterable<PropertyAccessorElement> accessors) { 3158 Iterable<PropertyAccessorElement> accessors) {
2969 List<ParameterElement> result = <ParameterElement>[]; 3159 List<ParameterElement> result = <ParameterElement>[];
2970 for (MethodElement declaredMethod in declaredMethods) { 3160 for (MethodElement declaredMethod in declaredMethods) {
2971 result.addAll(declaredMethod.parameters); 3161 result.addAll(declaredMethod.parameters);
2972 } 3162 }
2973 for (ConstructorElement declaredConstructor in declaredConstructors) { 3163 for (ConstructorElement declaredConstructor in declaredConstructors) {
2974 result.addAll(declaredConstructor.parameters); 3164 result.addAll(declaredConstructor.parameters);
2975 } 3165 }
2976 for (PropertyAccessorElement accessor in accessors) { 3166 for (PropertyAccessorElement accessor in accessors) {
2977 if (accessor.isSetter) { 3167 if (accessor.isSetter) {
2978 result.addAll(accessor.parameters); 3168 result.addAll(accessor.parameters);
2979 } 3169 }
2980 } 3170 }
2981 return result; 3171 return result;
2982 } 3172 }
2983 3173
3174 /// Returns the accessors from the given [libraryElement], filtured such that
3175 /// the returned ones are the ones that are supported by [capabilities].
3176 Iterable<ExecutableElement> _extractLibraryAccessors(
3177 LibraryElement libraryElement, _Capabilities capabilities) sync* {
3178 for (CompilationUnitElement unit in libraryElement.units) {
3179 for (PropertyAccessorElement accessor in unit.accessors) {
3180 if (accessor.isPrivate) continue;
3181 if (capabilities.supportsTopLevelInvoke(
3182 accessor.name, accessor.metadata)) {
3183 yield accessor;
3184 }
3185 }
3186 }
3187 }
3188
2984 /// Returns the [PropertyAccessorElement]s which are the accessors 3189 /// Returns the [PropertyAccessorElement]s which are the accessors
2985 /// of the given [classElement], including both the declared ones 3190 /// of the given [classElement], including both the declared ones
2986 /// and the implicitly generated ones corresponding to fields. This 3191 /// and the implicitly generated ones corresponding to fields. This
2987 /// is the set of accessors that corresponds to the behavioral interface 3192 /// is the set of accessors that corresponds to the behavioral interface
2988 /// of the corresponding instances, as opposed to the source code oriented 3193 /// of the corresponding instances, as opposed to the source code oriented
2989 /// interface, e.g., `declarations`. But the latter can be computed from 3194 /// interface, e.g., `declarations`. But the latter can be computed from
2990 /// here, by filtering out the accessors whose `isSynthetic` is true 3195 /// here, by filtering out the accessors whose `isSynthetic` is true
2991 /// and adding the fields. 3196 /// and adding the fields.
2992 Iterable<PropertyAccessorElement> _declaredAndImplicitAccessors( 3197 Iterable<PropertyAccessorElement> _extractAccessors(
2993 ClassElement classElement, _Capabilities capabilities) { 3198 ClassElement classElement, _Capabilities capabilities) {
2994 return classElement.accessors.where((PropertyAccessorElement accessor) { 3199 return classElement.accessors.where((PropertyAccessorElement accessor) {
2995 if (accessor.isPrivate) return false; 3200 if (accessor.isPrivate) return false;
2996 Function capabilityChecker = accessor.isStatic 3201 Function capabilityChecker = accessor.isStatic
2997 ? capabilities.supportsStaticInvoke 3202 ? capabilities.supportsStaticInvoke
2998 : capabilities.supportsInstanceInvoke; 3203 : capabilities.supportsInstanceInvoke;
2999 return capabilityChecker(accessor.name, accessor.metadata); 3204 return capabilityChecker(accessor.name, accessor.metadata);
3000 }); 3205 });
3001 } 3206 }
3002 3207
3003 Iterable<ConstructorElement> _declaredConstructors( 3208 /// Returns the declared constructors from [classElement], filtered such that
3209 /// the returned ones are the ones that are supported by [capabilities].
3210 Iterable<ConstructorElement> _extractDeclaredConstructors(
3004 ClassElement classElement, _Capabilities capabilities) { 3211 ClassElement classElement, _Capabilities capabilities) {
3005 return classElement.constructors.where((ConstructorElement constructor) { 3212 return classElement.constructors.where((ConstructorElement constructor) {
3006 if (constructor.isPrivate) return false; 3213 if (constructor.isPrivate) return false;
3007 return capabilities.supportsNewInstance( 3214 return capabilities.supportsNewInstance(
3008 constructor.name, constructor.metadata); 3215 constructor.name, constructor.metadata);
3009 }); 3216 });
3010 } 3217 }
3011 3218
3219 _LibraryDomain _createLibraryDomain(
3220 LibraryElement library, _ReflectorDomain domain) {
3221 List<TopLevelVariableElement> declaredVariablesOfLibrary =
3222 _extractDeclaredVariables(library, domain._capabilities).toList();
3223 List<FunctionElement> declaredFunctionsOfLibrary =
3224 _extractDeclaredFunctions(library, domain._capabilities).toList();
3225 List<PropertyAccessorElement> accessorsOfLibrary =
3226 _extractLibraryAccessors(library, domain._capabilities);
3227 List<ParameterElement> declaredParametersOfLibrary =
3228 _extractDeclaredFunctionParameters(
3229 declaredFunctionsOfLibrary, accessorsOfLibrary);
3230 return new _LibraryDomain(
3231 library,
3232 declaredVariablesOfLibrary,
3233 declaredFunctionsOfLibrary,
3234 declaredParametersOfLibrary,
3235 accessorsOfLibrary,
3236 domain);
3237 }
3238
3012 _ClassDomain _createClassDomain(ClassElement type, _ReflectorDomain domain) { 3239 _ClassDomain _createClassDomain(ClassElement type, _ReflectorDomain domain) {
3013 if (type is MixinApplication) { 3240 if (type is MixinApplication) {
3014 List<FieldElement> declaredFieldsOfClass = 3241 List<FieldElement> declaredFieldsOfClass =
3015 _extractDeclaredFields(type.mixin, domain._capabilities) 3242 _extractDeclaredFields(type.mixin, domain._capabilities)
3016 .where((FieldElement e) => !e.isStatic) 3243 .where((FieldElement e) => !e.isStatic)
3017 .toList(); 3244 .toList();
3018 List<MethodElement> declaredMethodsOfClass = 3245 List<MethodElement> declaredMethodsOfClass =
3019 _extractDeclaredMethods(type.mixin, domain._capabilities) 3246 _extractDeclaredMethods(type.mixin, domain._capabilities)
3020 .where((MethodElement e) => !e.isStatic) 3247 .where((MethodElement e) => !e.isStatic)
3021 .toList(); 3248 .toList();
3022 List<PropertyAccessorElement> declaredAndImplicitAccessorsOfClass = 3249 List<PropertyAccessorElement> declaredAndImplicitAccessorsOfClass =
3023 _declaredAndImplicitAccessors(type.mixin, domain._capabilities) 3250 _extractAccessors(type.mixin, domain._capabilities).toList();
3024 .toList();
3025 List<ConstructorElement> declaredConstructorsOfClass = 3251 List<ConstructorElement> declaredConstructorsOfClass =
3026 new List<ConstructorElement>(); 3252 new List<ConstructorElement>();
3027 List<ParameterElement> declaredParametersOfClass = 3253 List<ParameterElement> declaredParametersOfClass =
3028 _extractDeclaredParameters(declaredMethodsOfClass, 3254 _extractDeclaredParameters(declaredMethodsOfClass,
3029 declaredConstructorsOfClass, declaredAndImplicitAccessorsOfClass); 3255 declaredConstructorsOfClass, declaredAndImplicitAccessorsOfClass);
3030 3256
3031 return new _ClassDomain( 3257 return new _ClassDomain(
3032 type, 3258 type,
3033 declaredFieldsOfClass, 3259 declaredFieldsOfClass,
3034 declaredMethodsOfClass, 3260 declaredMethodsOfClass,
3035 declaredParametersOfClass, 3261 declaredParametersOfClass,
3036 declaredAndImplicitAccessorsOfClass, 3262 declaredAndImplicitAccessorsOfClass,
3037 declaredConstructorsOfClass, 3263 declaredConstructorsOfClass,
3038 domain); 3264 domain);
3039 } 3265 }
3040 3266
3041 List<FieldElement> declaredFieldsOfClass = 3267 List<FieldElement> declaredFieldsOfClass =
3042 _extractDeclaredFields(type, domain._capabilities).toList(); 3268 _extractDeclaredFields(type, domain._capabilities).toList();
3043 List<MethodElement> declaredMethodsOfClass = 3269 List<MethodElement> declaredMethodsOfClass =
3044 _extractDeclaredMethods(type, domain._capabilities).toList(); 3270 _extractDeclaredMethods(type, domain._capabilities).toList();
3045 List<PropertyAccessorElement> declaredAndImplicitAccessorsOfClass = 3271 List<PropertyAccessorElement> declaredAndImplicitAccessorsOfClass =
3046 _declaredAndImplicitAccessors(type, domain._capabilities).toList(); 3272 _extractAccessors(type, domain._capabilities).toList();
3047 List<ConstructorElement> declaredConstructorsOfClass = 3273 List<ConstructorElement> declaredConstructorsOfClass =
3048 _declaredConstructors(type, domain._capabilities).toList(); 3274 _extractDeclaredConstructors(type, domain._capabilities).toList();
3049 List<ParameterElement> declaredParametersOfClass = _extractDeclaredParameters( 3275 List<ParameterElement> declaredParametersOfClass = _extractDeclaredParameters(
3050 declaredMethodsOfClass, 3276 declaredMethodsOfClass,
3051 declaredConstructorsOfClass, 3277 declaredConstructorsOfClass,
3052 declaredAndImplicitAccessorsOfClass); 3278 declaredAndImplicitAccessorsOfClass);
3053 return new _ClassDomain( 3279 return new _ClassDomain(
3054 type, 3280 type,
3055 declaredFieldsOfClass, 3281 declaredFieldsOfClass,
3056 declaredMethodsOfClass, 3282 declaredMethodsOfClass,
3057 declaredParametersOfClass, 3283 declaredParametersOfClass,
3058 declaredAndImplicitAccessorsOfClass, 3284 declaredAndImplicitAccessorsOfClass,
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
3109 String get name { 3335 String get name {
3110 if (declaredName != null) return declaredName; 3336 if (declaredName != null) return declaredName;
3111 if (superclass is MixinApplication) { 3337 if (superclass is MixinApplication) {
3112 return "${superclass.name}, ${_qualifiedName(mixin)}"; 3338 return "${superclass.name}, ${_qualifiedName(mixin)}";
3113 } else { 3339 } else {
3114 return "${_qualifiedName(superclass)} with ${_qualifiedName(mixin)}"; 3340 return "${_qualifiedName(superclass)} with ${_qualifiedName(mixin)}";
3115 } 3341 }
3116 } 3342 }
3117 3343
3118 @override 3344 @override
3345 String get displayName => name;
3346
3347 @override
3119 List<InterfaceType> get interfaces => <InterfaceType>[]; 3348 List<InterfaceType> get interfaces => <InterfaceType>[];
3120 3349
3121 @override 3350 @override
3122 List<ElementAnnotation> get metadata => <ElementAnnotation>[]; 3351 List<ElementAnnotation> get metadata => <ElementAnnotation>[];
3123 3352
3124 @override 3353 @override
3125 bool get isSynthetic => declaredName != null; 3354 bool get isSynthetic => declaredName == null;
3126 3355
3127 // Note that the `InterfaceTypeImpl` may well call methods on this 3356 // Note that the `InterfaceTypeImpl` may well call methods on this
3128 // `MixinApplication` whose body is `_unImplemented()`, but it still provides 3357 // `MixinApplication` whose body is `_unImplemented()`, but it still provides
3129 // a slightly better service than leaving this method `_unImplemented()`: 3358 // a slightly better service than leaving this method `_unImplemented()`:
3130 // We are allowed to take one more step, which may be enough. 3359 // We are allowed to take one more step, which may be enough.
3131 @override 3360 @override
3132 InterfaceType get type => new InterfaceTypeImpl(this); 3361 InterfaceType get type => new InterfaceTypeImpl(this);
3133 3362
3134 @override 3363 @override
3135 InterfaceType get supertype { 3364 InterfaceType get supertype {
(...skipping 12 matching lines...) Expand all
3148 } 3377 }
3149 3378
3150 /// Returns true iff this class was declared using the syntax 3379 /// Returns true iff this class was declared using the syntax
3151 /// `class B = A with M;`, i.e., if it is an explicitly named mixin 3380 /// `class B = A with M;`, i.e., if it is an explicitly named mixin
3152 /// application. We do not create instances of this class in that 3381 /// application. We do not create instances of this class in that
3153 /// case. 3382 /// case.
3154 @override 3383 @override
3155 bool get isMixinApplication => declaredName != null; 3384 bool get isMixinApplication => declaredName != null;
3156 3385
3157 @override 3386 @override
3387 bool get isAbstract => !isMixinApplication || mixin.isAbstract;
3388
3389 @override
3390 bool get isEnum => false;
3391
3392 @override
3158 NamedCompilationUnitMember computeNode() => 3393 NamedCompilationUnitMember computeNode() =>
3159 declaredName != null ? subclass.computeNode() : null; 3394 declaredName != null ? subclass.computeNode() : null;
3160 3395
3161 @override 3396 @override
3162 bool operator ==(Object object) { 3397 bool operator ==(Object object) {
3163 return object is MixinApplication && 3398 return object is MixinApplication &&
3164 superclass == object.superclass && 3399 superclass == object.superclass &&
3165 mixin == object.mixin && 3400 mixin == object.mixin &&
3166 library == object.library && 3401 library == object.library &&
3167 subclass == object.subclass; 3402 subclass == object.subclass;
(...skipping 21 matching lines...) Expand all
3189 @override 3424 @override
3190 bool get hasNonFinalField => _unImplemented(); 3425 bool get hasNonFinalField => _unImplemented();
3191 3426
3192 @override 3427 @override
3193 bool get hasReferenceToSuper => _unImplemented(); 3428 bool get hasReferenceToSuper => _unImplemented();
3194 3429
3195 @override 3430 @override
3196 bool get hasStaticMember => _unImplemented(); 3431 bool get hasStaticMember => _unImplemented();
3197 3432
3198 @override 3433 @override
3199 bool get isAbstract => _unImplemented();
3200
3201 @override
3202 bool get isEnum => _unImplemented();
3203
3204 @override
3205 bool get isOrInheritsProxy => _unImplemented(); 3434 bool get isOrInheritsProxy => _unImplemented();
3206 3435
3207 @override 3436 @override
3208 bool get isProxy => _unImplemented(); 3437 bool get isProxy => _unImplemented();
3209 3438
3210 @override 3439 @override
3211 bool get isTypedef => _unImplemented(); 3440 bool get isTypedef => _unImplemented();
3212 3441
3213 @override 3442 @override
3214 bool get isValidMixin => _unImplemented(); 3443 bool get isValidMixin => _unImplemented();
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
3290 } 3519 }
3291 3520
3292 // This seems to be the defined behaviour according to dart:mirrors. 3521 // This seems to be the defined behaviour according to dart:mirrors.
3293 @override 3522 @override
3294 bool get isPrivate => false; 3523 bool get isPrivate => false;
3295 3524
3296 @override 3525 @override
3297 get context => _unImplemented(); 3526 get context => _unImplemented();
3298 3527
3299 @override 3528 @override
3300 String get displayName => _unImplemented();
3301
3302 @override
3303 Element get enclosingElement => _unImplemented(); 3529 Element get enclosingElement => _unImplemented();
3304 3530
3305 @override 3531 @override
3306 int get id => _unImplemented(); 3532 int get id => _unImplemented();
3307 3533
3308 @override 3534 @override
3309 bool get isDeprecated => _unImplemented(); 3535 bool get isDeprecated => _unImplemented();
3310 3536
3311 @override 3537 @override
3312 bool get isOverride => _unImplemented(); 3538 bool get isOverride => _unImplemented();
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
3349 3575
3350 @override 3576 @override
3351 void visitChildren(ElementVisitor visitor) => _unImplemented(); 3577 void visitChildren(ElementVisitor visitor) => _unImplemented();
3352 } 3578 }
3353 3579
3354 String _qualifiedName(ClassElement classElement) { 3580 String _qualifiedName(ClassElement classElement) {
3355 return classElement == null 3581 return classElement == null
3356 ? "null" 3582 ? "null"
3357 : "${classElement.library.name}.${classElement.name}"; 3583 : "${classElement.library.name}.${classElement.name}";
3358 } 3584 }
3585
3586 String _qualifiedFunctionName(FunctionElement functionElement) {
3587 return functionElement == null
3588 ? "null"
3589 : "${functionElement.library.name}.${functionElement.name}";
3590 }
OLDNEW
« no previous file with comments | « reflectable/lib/src/reflectable_transformer_based.dart ('k') | reflectable/test/mock_tests/check_literal_transform_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698