OLD | NEW |
---|---|
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
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<PropertyAccessorElement> _gettersOfLibrary(LibraryElement library) { |
690 return library.units.map((CompilationUnitElement part) { | 717 return library.units.map((CompilationUnitElement part) { |
691 Iterable<Element> getters = <Iterable<Element>>[ | 718 Iterable<Element> getters = <Iterable<Element>>[ |
692 part.accessors | 719 part.accessors |
693 .where((PropertyAccessorElement accessor) => accessor.isGetter), | 720 .where((PropertyAccessorElement accessor) => accessor.isGetter), |
694 part.functions, | 721 part.functions |
695 part.topLevelVariables | |
696 ].expand((Iterable<Element> elements) => elements); | 722 ].expand((Iterable<Element> elements) => elements); |
697 return getters.where((Element getter) => | 723 return getters.where((Element getter) => |
698 _capabilities.supportsTopLevelInvoke(getter.name, getter.metadata)); | 724 _capabilities.supportsTopLevelInvoke(getter.name, getter.metadata)); |
699 }).expand((Iterable<Element> x) => x); | 725 }).expand((Iterable<Element> x) => x); |
700 } | 726 } |
701 | 727 |
702 Iterable<PropertyAccessorElement> _settersOfLibrary(LibraryElement library) { | 728 Iterable<PropertyAccessorElement> _settersOfLibrary(LibraryElement library) { |
703 return library.units.map((CompilationUnitElement part) { | 729 return library.units.map((CompilationUnitElement part) { |
704 Iterable setters = <Iterable<Element>>[ | 730 Iterable setters = <Iterable<Element>>[ |
705 part.accessors | 731 part.accessors |
706 .where((PropertyAccessorElement accessor) => accessor.isSetter), | 732 .where((PropertyAccessorElement accessor) => accessor.isSetter) |
707 part.topLevelVariables | |
708 .where((TopLevelVariableElement variable) => !variable.isFinal) | |
709 ].expand((Iterable<Element> elements) => elements); | 733 ].expand((Iterable<Element> elements) => elements); |
710 return setters.where((Element setter) => | 734 return setters.where((Element setter) => |
711 _capabilities.supportsTopLevelInvoke(setter.name, setter.metadata)); | 735 _capabilities.supportsTopLevelInvoke(setter.name, setter.metadata)); |
712 }).expand((Iterable<Element> x) => x); | 736 }).expand((Iterable<Element> x) => x); |
713 } | 737 } |
714 | 738 |
715 String _classMirrorCode( | 739 String _classMirrorCode( |
716 _ClassDomain classDomain, | 740 _ClassDomain classDomain, |
717 Enumerator<FieldElement> fields, | 741 Enumerator<FieldElement> fields, |
742 int fieldsOffset, | |
743 int methodsOffset, | |
718 Enumerator<ExecutableElement> members, | 744 Enumerator<ExecutableElement> members, |
719 Enumerator<LibraryElement> libraries, | 745 Enumerator<_LibraryDomain> libraries, |
746 Map<LibraryElement, _LibraryDomain> libraryMap, | |
720 _ImportCollector importCollector, | 747 _ImportCollector importCollector, |
721 TransformLogger logger) { | 748 TransformLogger logger) { |
749 int descriptor = _classDescriptor(classDomain._classElement); | |
750 | |
722 // Fields go first in [memberMirrors], so they will get the | 751 // Fields go first in [memberMirrors], so they will get the |
723 // same index as in [fields]. | 752 // same index as in [fields]. |
724 Iterable<int> fieldsIndices = | 753 Iterable<int> fieldsIndices = |
725 classDomain._declaredFields.map((FieldElement element) { | 754 classDomain._declaredFields.map((FieldElement element) { |
726 return fields.indexOf(element); | 755 return fields.indexOf(element) + fieldsOffset; |
727 }); | 756 }); |
728 | 757 |
729 // All the elements in the behavioral interface go after the | 758 // All the elements in the behavioral interface go after the |
730 // fields in [memberMirrors], so they must get an offset of | 759 // fields in [memberMirrors], so they must get an offset of |
731 // `fields.length` on the index. | 760 // `fields.length` on the index. |
732 Iterable<int> methodsIndices = classDomain._declarations | 761 Iterable<int> methodsIndices = classDomain._declarations |
733 .where(_executableIsntImplicitGetterOrSetter) | 762 .where(_executableIsntImplicitGetterOrSetter) |
734 .map((ExecutableElement element) { | 763 .map((ExecutableElement element) { |
735 // TODO(eernst) implement: The "magic" default constructor in `Object` | 764 // TODO(eernst) implement: The "magic" default constructor in `Object` |
736 // (the one that ultimately allocates the memory for _every_ new | 765 // (the one that ultimately allocates the memory for _every_ new |
737 // object) has no index, which creates the need to catch a `null` | 766 // object) has no index, which creates the need to catch a `null` |
738 // here. Search for "magic" to find other occurrences of the same | 767 // here. Search for "magic" to find other occurrences of the same |
739 // issue. For now, we use the index [constants.NO_CAPABILITY_INDEX] | 768 // issue. For now, we use the index [constants.NO_CAPABILITY_INDEX] |
740 // for this declaration, because it is not yet supported. | 769 // for this declaration, because it is not yet supported. |
741 // Need to find the correct solution, though! | 770 // Need to find the correct solution, though! |
742 int index = members.indexOf(element); | 771 int index = members.indexOf(element); |
743 return index == null | 772 return index == null |
744 ? constants.NO_CAPABILITY_INDEX | 773 ? constants.NO_CAPABILITY_INDEX |
745 : index + fields.length; | 774 : index + methodsOffset; |
746 }); | 775 }); |
747 | 776 |
748 String declarationsCode = "<int>[${constants | 777 String declarationsCode = _capabilities._impliesDeclarations |
749 .NO_CAPABILITY_INDEX}]"; | 778 ? _formatAsList( |
750 if (_capabilities._impliesDeclarations) { | 779 "int", |
751 List<int> declarationsIndices = <int>[] | 780 () sync* { |
752 ..addAll(fieldsIndices) | 781 yield* fieldsIndices; |
753 ..addAll(methodsIndices); | 782 yield* methodsIndices; |
754 declarationsCode = _formatAsList("int", declarationsIndices); | 783 }()) |
755 } | 784 : "<int>[${constants.NO_CAPABILITY_INDEX}]"; |
756 | 785 |
757 // All instance members belong to the behavioral interface, so they | 786 // All instance members belong to the behavioral interface, so they |
758 // also get an offset of `fields.length`. | 787 // also get an offset of `fields.length`. |
759 String instanceMembersCode = _formatAsList("int", | 788 String instanceMembersCode = _formatAsList("int", |
760 classDomain._instanceMembers.map((ExecutableElement element) { | 789 classDomain._instanceMembers.map((ExecutableElement element) { |
761 // TODO(eernst) implement: The "magic" default constructor has | 790 // TODO(eernst) implement: The "magic" default constructor has |
762 // index: NO_CAPABILITY_INDEX; adjust this when support for it has | 791 // index: NO_CAPABILITY_INDEX; adjust this when support for it has |
763 // been implemented. | 792 // been implemented. |
764 int index = members.indexOf(element); | 793 int index = members.indexOf(element); |
765 return index == null | 794 return index == null |
766 ? constants.NO_CAPABILITY_INDEX | 795 ? constants.NO_CAPABILITY_INDEX |
767 : index + fields.length; | 796 : index + methodsOffset; |
768 })); | 797 })); |
769 | 798 |
770 // All static members belong to the behavioral interface, so they | 799 // All static members belong to the behavioral interface, so they |
771 // also get an offset of `fields.length`. | 800 // also get an offset of `fields.length`. |
772 String staticMembersCode = _formatAsList("int", | 801 String staticMembersCode = _formatAsList("int", |
773 classDomain._staticMembers.map((ExecutableElement element) { | 802 classDomain._staticMembers.map((ExecutableElement element) { |
774 int index = members.indexOf(element); | 803 int index = members.indexOf(element); |
775 return index == null | 804 return index == null |
776 ? constants.NO_CAPABILITY_INDEX | 805 ? constants.NO_CAPABILITY_INDEX |
777 : index + fields.length; | 806 : index + methodsOffset; |
778 })); | 807 })); |
779 | 808 |
780 ClassElement classElement = classDomain._classElement; | 809 ClassElement classElement = classDomain._classElement; |
781 ClassElement superclass = classes.superclassOf(classElement); | 810 ClassElement superclass = classes.superclassOf(classElement); |
782 // [Object]'s superclass is reported as `null`: it does not exist and | 811 // [Object]'s superclass is reported as `null`: it does not exist and |
783 // hence we cannot decide whether it's supported or unsupported; by | 812 // 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 | 813 // convention we make it supported and report it in the same way as |
785 // 'dart:mirrors'. Other superclasses use `NO_CAPABILITY_INDEX` to | 814 // 'dart:mirrors'. Other superclasses use `NO_CAPABILITY_INDEX` to |
786 // indicate missing support. | 815 // indicate missing support. |
787 String superclassIndex = (classElement is! MixinApplication && | 816 String superclassIndex = (classElement is! MixinApplication && |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
825 // Named mixin application (using the syntax `class B = A with M;`). | 854 // Named mixin application (using the syntax `class B = A with M;`). |
826 mixinIndex = classes.indexOf(classElement.mixins.last.element); | 855 mixinIndex = classes.indexOf(classElement.mixins.last.element); |
827 } else { | 856 } else { |
828 mixinIndex = (classElement is MixinApplication) | 857 mixinIndex = (classElement is MixinApplication) |
829 ? classes.indexOf(classElement.mixin) | 858 ? classes.indexOf(classElement.mixin) |
830 : classes.indexOf(classElement); | 859 : classes.indexOf(classElement); |
831 } | 860 } |
832 if (mixinIndex == null) mixinIndex = constants.NO_CAPABILITY_INDEX; | 861 if (mixinIndex == null) mixinIndex = constants.NO_CAPABILITY_INDEX; |
833 | 862 |
834 int ownerIndex = _capabilities.supportsLibraries | 863 int ownerIndex = _capabilities.supportsLibraries |
835 ? libraries.indexOf(classElement.library) | 864 ? libraries.indexOf(libraryMap[classElement.library]) |
836 : constants.NO_CAPABILITY_INDEX; | 865 : constants.NO_CAPABILITY_INDEX; |
837 | 866 |
838 String superinterfaceIndices = _formatAsList( | 867 String superinterfaceIndices = _formatAsList( |
839 'int', | 868 'int', |
840 classElement.interfaces | 869 classElement.interfaces |
841 .map((InterfaceType type) => type.element) | 870 .map((InterfaceType type) => type.element) |
842 .where(classes.contains) | 871 .where(classes.contains) |
843 .map(classes.indexOf)); | 872 .map(classes.indexOf)); |
844 | 873 |
845 String classMetadataCode; | 874 String classMetadataCode; |
846 if (_capabilities._supportsMetadata) { | 875 if (_capabilities._supportsMetadata) { |
847 classMetadataCode = _extractMetadataCode(classElement, _resolver, | 876 classMetadataCode = _extractMetadataCode(classElement, _resolver, |
848 importCollector, logger, _generatedLibraryId); | 877 importCollector, logger, _generatedLibraryId); |
849 } else { | 878 } else { |
850 classMetadataCode = "null"; | 879 classMetadataCode = "null"; |
851 } | 880 } |
852 | 881 |
853 int classIndex = classes.indexOf(classElement); | 882 int classIndex = classes.indexOf(classElement); |
854 | 883 |
855 String result = 'new r.ClassMirrorImpl(r"${classDomain._simpleName}", ' | 884 String result = 'new r.ClassMirrorImpl(r"${classDomain._simpleName}", ' |
856 'r"${_qualifiedName(classElement)}", $classIndex, ' | 885 'r"${_qualifiedName(classElement)}", $descriptor, $classIndex, ' |
857 '${_constConstructionCode(importCollector)}, ' | 886 '${_constConstructionCode(importCollector)}, ' |
858 '$declarationsCode, $instanceMembersCode, $staticMembersCode, ' | 887 '$declarationsCode, $instanceMembersCode, $staticMembersCode, ' |
859 '$superclassIndex, $staticGettersCode, $staticSettersCode, ' | 888 '$superclassIndex, $staticGettersCode, $staticSettersCode, ' |
860 '$constructorsCode, $ownerIndex, $mixinIndex, ' | 889 '$constructorsCode, $ownerIndex, $mixinIndex, ' |
861 '$superinterfaceIndices, $classMetadataCode)'; | 890 '$superinterfaceIndices, $classMetadataCode)'; |
862 return result; | 891 return result; |
863 } | 892 } |
864 | 893 |
865 String _methodMirrorCode( | 894 String _methodMirrorCode( |
866 ExecutableElement element, | 895 ExecutableElement element, |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
943 '${dartType.element}")'; | 972 '${dartType.element}")'; |
944 } | 973 } |
945 return _typeCodeOfClass(dartType.element, importCollector); | 974 return _typeCodeOfClass(dartType.element, importCollector); |
946 } | 975 } |
947 | 976 |
948 String _typeCodeOfClass( | 977 String _typeCodeOfClass( |
949 ClassElement classElement, _ImportCollector importCollector) { | 978 ClassElement classElement, _ImportCollector importCollector) { |
950 if (classElement is MixinApplication && classElement.declaredName == null) { | 979 if (classElement is MixinApplication && classElement.declaredName == null) { |
951 return 'new r.FakeType(r"${_qualifiedName(classElement)}")'; | 980 return 'new r.FakeType(r"${_qualifiedName(classElement)}")'; |
952 } | 981 } |
953 if (classElement is! MixinApplication && classElement.type.isDynamic) { | 982 if (classElement.type.isDynamic) return "dynamic"; |
954 return "dynamic"; | |
955 } | |
956 String prefix = importCollector._getPrefix(classElement.library); | 983 String prefix = importCollector._getPrefix(classElement.library); |
957 return "$prefix.${classElement.name}"; | 984 return "$prefix.${classElement.name}"; |
958 } | 985 } |
959 | 986 |
960 String _libraryMirrorCode(LibraryElement library, | 987 String _libraryMirrorCode( |
961 _ImportCollector importCollector, TransformLogger logger) { | 988 _LibraryDomain libraryDomain, |
989 Enumerator<ExecutableElement> members, | |
990 Enumerator<TopLevelVariableElement> variables, | |
991 int fieldsLength, | |
992 _ImportCollector importCollector, | |
993 TransformLogger logger) { | |
994 LibraryElement library = libraryDomain._libraryElement; | |
962 String gettersCode = _formatAsMap( | 995 String gettersCode = _formatAsMap( |
963 _gettersOfLibrary(library).map((PropertyAccessorElement getter) { | 996 _gettersOfLibrary(library).map((PropertyAccessorElement getter) { |
964 return _topLevelGettingClosure(importCollector, library, getter.name); | 997 return _topLevelGettingClosure(importCollector, library, getter.name); |
965 })); | 998 })); |
sigurdm
2015/10/09 07:52:04
A newline here would look better.
eernst
2015/10/09 10:09:05
Not sure what you mean?
sigurdm
2015/10/09 10:47:20
Initialization of settersCode and variableIndices
eernst
2015/10/09 11:24:14
Done.
| |
966 String settersCode = _formatAsMap( | 999 String settersCode = _formatAsMap( |
967 _settersOfLibrary(library).map((PropertyAccessorElement setter) { | 1000 _settersOfLibrary(library).map((PropertyAccessorElement setter) { |
968 return topLevelSettingClosure(importCollector, library, setter.name); | 1001 return topLevelSettingClosure(importCollector, library, setter.name); |
969 })); | 1002 })); |
970 | 1003 |
1004 // Fields go first in [memberMirrors], so they will get the | |
1005 // same index as in [fields]. | |
1006 Iterable<int> variableIndices = | |
1007 libraryDomain._declaredVariables.map((TopLevelVariableElement element) { | |
1008 return variables.indexOf(element); | |
1009 }); | |
1010 | |
1011 // All the elements in the behavioral interface go after the | |
1012 // fields in [memberMirrors], so they must get an offset of | |
1013 // `fields.length` on the index. | |
1014 Iterable<int> methodsIndices = libraryDomain._declarations | |
1015 .where(_executableIsntImplicitGetterOrSetter) | |
1016 .map((ExecutableElement element) { | |
1017 int index = members.indexOf(element); | |
1018 return index + fieldsLength; | |
1019 }); | |
1020 | |
1021 String declarationsCode = "<int>[${constants.NO_CAPABILITY_INDEX}]"; | |
1022 if (_capabilities._impliesDeclarations) { | |
1023 List<int> declarationsIndices = <int>[] | |
1024 ..addAll(variableIndices) | |
1025 ..addAll(methodsIndices); | |
1026 declarationsCode = _formatAsList("int", declarationsIndices); | |
1027 } | |
1028 | |
971 // TODO(sigurdm) clarify: Find out how to get good uri's in a | 1029 // TODO(sigurdm) clarify: Find out how to get good uri's in a |
972 // transformer. | 1030 // transformer. |
973 // TODO(sigurdm) implement: Check for `uriCapability`. | 1031 // TODO(sigurdm) implement: Check for `uriCapability`. |
974 String uriCode = "null"; | 1032 String uriCode = "null"; |
975 | 1033 |
976 String metadataCode; | 1034 String metadataCode; |
977 if (_capabilities._supportsMetadata) { | 1035 if (_capabilities._supportsMetadata) { |
978 metadataCode = _extractMetadataCode( | 1036 metadataCode = _extractMetadataCode( |
979 library, _resolver, importCollector, logger, _generatedLibraryId); | 1037 library, _resolver, importCollector, logger, _generatedLibraryId); |
980 } else { | 1038 } else { |
981 metadataCode = "null"; | 1039 metadataCode = "null"; |
982 } | 1040 } |
983 | 1041 |
984 return 'new r.LibraryMirrorImpl(r"${library.name}", $uriCode, ' | 1042 return 'new r.LibraryMirrorImpl(r"${library.name}", $uriCode, ' |
985 '$gettersCode, $settersCode, $metadataCode)'; | 1043 '${_constConstructionCode(importCollector)}, ' |
1044 '$declarationsCode, $gettersCode, $settersCode, $metadataCode)'; | |
986 } | 1045 } |
987 | 1046 |
988 String _parameterMirrorCode( | 1047 String _parameterMirrorCode( |
989 ParameterElement element, | 1048 ParameterElement element, |
990 Enumerator<FieldElement> fields, | 1049 Enumerator<FieldElement> fields, |
991 Enumerator<ExecutableElement> members, | 1050 Enumerator<ExecutableElement> members, |
992 _ImportCollector importCollector, | 1051 _ImportCollector importCollector, |
993 TransformLogger logger, | 1052 TransformLogger logger, |
994 bool reflectedTypeRequested) { | 1053 bool reflectedTypeRequested) { |
995 int descriptor = _parameterDescriptor(element); | 1054 int descriptor = _parameterDescriptor(element); |
(...skipping 301 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1297 } else if (getterName == "~") { | 1356 } else if (getterName == "~") { |
1298 closure = "(dynamic instance) => () => ~instance"; | 1357 closure = "(dynamic instance) => () => ~instance"; |
1299 } else { | 1358 } else { |
1300 closure = "(dynamic instance) => (x) => instance ${getterName} x"; | 1359 closure = "(dynamic instance) => (x) => instance ${getterName} x"; |
1301 } | 1360 } |
1302 return 'r"${getterName}": $closure'; | 1361 return 'r"${getterName}": $closure'; |
1303 } | 1362 } |
1304 | 1363 |
1305 // Auxiliary function used by `_generateCode`. | 1364 // Auxiliary function used by `_generateCode`. |
1306 String _settingClosure(String setterName) { | 1365 String _settingClosure(String setterName) { |
1307 assert(setterName.substring(setterName.length - 1) == "="); | 1366 String name = setterName.substring(setterName.length - 1) == "=" |
sigurdm
2015/10/09 07:52:04
Can we now get a setterName not ending in '='? Whe
eernst
2015/10/09 10:09:05
I found `someName = value` in the generated code a
sigurdm
2015/10/09 10:47:20
I think we should track down where that happens. M
eernst
2015/10/09 11:24:14
Did that, and it doesn't fail now. I think this ma
| |
1308 // The [setterName] includes the "=", remove it. | 1367 ? setterName.substring(0, setterName.length - 1) |
1309 String name = setterName.substring(0, setterName.length - 1); | 1368 : setterName; |
1310 | |
1311 return 'r"$setterName": (dynamic instance, value) => ' | 1369 return 'r"$setterName": (dynamic instance, value) => ' |
1312 'instance.$name = value'; | 1370 'instance.$name = value'; |
1313 } | 1371 } |
1314 | 1372 |
1315 // Auxiliary function used by `_generateCode`. | 1373 // Auxiliary function used by `_generateCode`. |
1316 String _staticGettingClosure(_ImportCollector importCollector, | 1374 String _staticGettingClosure(_ImportCollector importCollector, |
1317 ClassElement classElement, String getterName) { | 1375 ClassElement classElement, String getterName) { |
1318 String className = classElement.name; | 1376 String className = classElement.name; |
1319 String prefix = importCollector._getPrefix(classElement.library); | 1377 String prefix = importCollector._getPrefix(classElement.library); |
1320 // Operators cannot be static. | 1378 // Operators cannot be static. |
(...skipping 22 matching lines...) Expand all Loading... | |
1343 // Auxiliary function used by `_generateCode`. | 1401 // Auxiliary function used by `_generateCode`. |
1344 String topLevelSettingClosure(_ImportCollector importCollector, | 1402 String topLevelSettingClosure(_ImportCollector importCollector, |
1345 LibraryElement library, String setterName) { | 1403 LibraryElement library, String setterName) { |
1346 assert(setterName.substring(setterName.length - 1) == "="); | 1404 assert(setterName.substring(setterName.length - 1) == "="); |
1347 // The [setterName] includes the "=", remove it. | 1405 // The [setterName] includes the "=", remove it. |
1348 String name = setterName.substring(0, setterName.length - 1); | 1406 String name = setterName.substring(0, setterName.length - 1); |
1349 String prefix = importCollector._getPrefix(library); | 1407 String prefix = importCollector._getPrefix(library); |
1350 return 'r"$setterName": (value) => $prefix.$name = value'; | 1408 return 'r"$setterName": (value) => $prefix.$name = value'; |
1351 } | 1409 } |
1352 | 1410 |
1411 /// Information about reflectability for a given library. | |
1412 class _LibraryDomain { | |
1413 /// Element describing the target library. | |
1414 final LibraryElement _libraryElement; | |
1415 | |
1416 /// Fields declared by [_libraryElement] and included for reflection support, | |
1417 /// according to the reflector described by the [_reflectorDomain]; | |
1418 /// obtained by filtering `_libraryElement.fields`. | |
1419 final Iterable<TopLevelVariableElement> _declaredVariables; | |
1420 | |
1421 /// Methods which are declared by [_libraryElement] and included for | |
1422 /// reflection support, according to the reflector described by | |
1423 /// [_reflectorDomain]; obtained by filtering `_libraryElement.functions`. | |
1424 final Iterable<FunctionElement> _declaredFunctions; | |
1425 | |
1426 /// Formal parameters declared by one of the [_declaredFunctions]. | |
1427 final Iterable<ParameterElement> _declaredParameters; | |
1428 | |
1429 /// Getters and setters possessed by [_libraryElement] and included for | |
1430 /// reflection support, according to the reflector described by | |
1431 /// [_reflectorDomain]; obtained by filtering `_libraryElement.accessors`. | |
1432 /// Note that it includes declared as well as synthetic accessors, | |
1433 /// implicitly created as getters/setters for fields. | |
1434 final Iterable<PropertyAccessorElement> _declaredAndImplicitAccessors; | |
1435 | |
1436 /// The reflector domain that holds [this] object as one of its | |
1437 /// library domains. | |
1438 final _ReflectorDomain _reflectorDomain; | |
1439 | |
1440 _LibraryDomain( | |
1441 this._libraryElement, | |
1442 this._declaredVariables, | |
1443 this._declaredFunctions, | |
1444 this._declaredParameters, | |
1445 this._declaredAndImplicitAccessors, | |
1446 this._reflectorDomain); | |
1447 | |
1448 String get _simpleName { | |
1449 return _libraryElement.name; | |
1450 } | |
1451 | |
1452 /// Returns the declared methods, accessors and constructors in | |
1453 /// [_classElement]. Note that this includes synthetic getters and | |
1454 /// setters, and omits fields; in other words, it provides the | |
1455 /// behavioral point of view on the class. Also note that this is not | |
1456 /// the same semantics as that of `declarations` in [ClassMirror]. | |
1457 Iterable<ExecutableElement> get _declarations sync* { | |
1458 yield* _declaredFunctions; | |
1459 yield* _declaredAndImplicitAccessors; | |
1460 } | |
1461 | |
1462 String toString() { | |
1463 return "LibraryDomain($_libraryElement)"; | |
1464 } | |
1465 | |
1466 bool operator ==(Object other) { | |
1467 if (other is _LibraryDomain) { | |
1468 return _libraryElement == other._libraryElement && | |
1469 _reflectorDomain == other._reflectorDomain; | |
1470 } else { | |
1471 return false; | |
1472 } | |
1473 } | |
1474 | |
1475 int get hashCode => _libraryElement.hashCode ^ _reflectorDomain.hashCode; | |
1476 } | |
1477 | |
1353 /// Information about reflectability for a given class. | 1478 /// Information about reflectability for a given class. |
1354 class _ClassDomain { | 1479 class _ClassDomain { |
1355 /// Element describing the target class. | 1480 /// Element describing the target class. |
1356 final ClassElement _classElement; | 1481 final ClassElement _classElement; |
1357 | 1482 |
1358 /// Fields declared by [classElement] and included for reflection support, | 1483 /// Fields declared by [_classElement] and included for reflection support, |
1359 /// according to the reflector described by the [reflectorDomain]; | 1484 /// according to the reflector described by the [_reflectorDomain]; |
1360 /// obtained by filtering `classElement.fields`. | 1485 /// obtained by filtering `_classElement.fields`. |
1361 final Iterable<FieldElement> _declaredFields; | 1486 final Iterable<FieldElement> _declaredFields; |
1362 | 1487 |
1363 /// Methods which are declared by [classElement] and included for | 1488 /// Methods which are declared by [_classElement] and included for |
1364 /// reflection support, according to the reflector described by | 1489 /// reflection support, according to the reflector described by |
1365 /// [reflectorDomain]; obtained by filtering `classElement.methods`. | 1490 /// [reflectorDomain]; obtained by filtering `_classElement.methods`. |
1366 final Iterable<MethodElement> _declaredMethods; | 1491 final Iterable<MethodElement> _declaredMethods; |
1367 | 1492 |
1368 /// Formal parameters declared by one of the [_declaredMethods]. | 1493 /// Formal parameters declared by one of the [_declaredMethods]. |
1369 final Iterable<ParameterElement> _declaredParameters; | 1494 final Iterable<ParameterElement> _declaredParameters; |
1370 | 1495 |
1371 /// Getters and setters possessed by [classElement] and included for | 1496 /// Getters and setters possessed by [_classElement] and included for |
1372 /// reflection support, according to the reflector described by | 1497 /// reflection support, according to the reflector described by |
1373 /// [reflectorDomain]; obtained by filtering `classElement.accessors`. | 1498 /// [reflectorDomain]; obtained by filtering `_classElement.accessors`. |
1374 /// Note that it includes declared as well as synthetic accessors, | 1499 /// Note that it includes declared as well as synthetic accessors, |
1375 /// implicitly created as getters/setters for fields. | 1500 /// implicitly created as getters/setters for fields. |
1376 final Iterable<PropertyAccessorElement> _declaredAndImplicitAccessors; | 1501 final Iterable<PropertyAccessorElement> _declaredAndImplicitAccessors; |
1377 | 1502 |
1378 /// Constructors declared by [classElement] and included for reflection | 1503 /// Constructors declared by [_classElement] and included for reflection |
1379 /// support, according to the reflector described by [reflectorDomain]; | 1504 /// support, according to the reflector described by [_reflectorDomain]; |
1380 /// obtained by filtering `classElement.constructors`. | 1505 /// obtained by filtering `_classElement.constructors`. |
1381 final Iterable<ConstructorElement> _constructors; | 1506 final Iterable<ConstructorElement> _constructors; |
1382 | 1507 |
1383 /// The reflector domain that holds [this] object as one of its | 1508 /// The reflector domain that holds [this] object as one of its |
1384 /// class domains. | 1509 /// class domains. |
1385 final _ReflectorDomain _reflectorDomain; | 1510 final _ReflectorDomain _reflectorDomain; |
1386 | 1511 |
1387 _ClassDomain( | 1512 _ClassDomain( |
1388 this._classElement, | 1513 this._classElement, |
1389 this._declaredFields, | 1514 this._declaredFields, |
1390 this._declaredMethods, | 1515 this._declaredMethods, |
(...skipping 243 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1634 // Handle API based capabilities. | 1759 // Handle API based capabilities. |
1635 if ((capability is ec.TopLevelInvokeCapability) && | 1760 if ((capability is ec.TopLevelInvokeCapability) && |
1636 _supportsName(capability, methodName)) { | 1761 _supportsName(capability, methodName)) { |
1637 return true; | 1762 return true; |
1638 } | 1763 } |
1639 if ((capability is ec.TopLevelInvokeMetaCapability) && | 1764 if ((capability is ec.TopLevelInvokeMetaCapability) && |
1640 _supportsMeta(capability, metadata)) { | 1765 _supportsMeta(capability, metadata)) { |
1641 return true; | 1766 return true; |
1642 } | 1767 } |
1643 // Quantifying capabilities do not influence the availability | 1768 // Quantifying capabilities do not influence the availability |
1644 // of reflection support for top level invocation. | 1769 // of reflection support for top-level invocation. |
1645 } | 1770 } |
1646 | 1771 |
1647 // All options exhausted, give up. | 1772 // All options exhausted, give up. |
1648 return false; | 1773 return false; |
1649 } | 1774 } |
1650 | 1775 |
1651 bool _supportsStaticInvoke(List<ec.ReflectCapability> capabilities, | 1776 bool _supportsStaticInvoke(List<ec.ReflectCapability> capabilities, |
1652 String methodName, Iterable<DartObject> metadata) { | 1777 String methodName, Iterable<DartObject> metadata) { |
1653 for (ec.ReflectCapability capability in capabilities) { | 1778 for (ec.ReflectCapability capability in capabilities) { |
1654 // Handle API based capabilities. | 1779 // Handle API based capabilities. |
(...skipping 280 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1935 // types (types whose name does not end in `..Impl`) declare the getter | 2060 // types (types whose name does not end in `..Impl`) declare the getter |
1936 // `evaluationResult`. Another possible choice of type would be | 2061 // `evaluationResult`. Another possible choice of type would be |
1937 // [VariableElementImpl], but with that one we would have to test | 2062 // [VariableElementImpl], but with that one we would have to test |
1938 // `isConst` as well. | 2063 // `isConst` as well. |
1939 if (variable is ConstTopLevelVariableElementImpl) { | 2064 if (variable is ConstTopLevelVariableElementImpl) { |
1940 EvaluationResultImpl result = variable.evaluationResult; | 2065 EvaluationResultImpl result = variable.evaluationResult; |
1941 if (result.value == null) return null; // Errors during evaluation. | 2066 if (result.value == null) return null; // Errors during evaluation. |
1942 bool isOk = checkInheritance(result.value.type, focusClass.type); | 2067 bool isOk = checkInheritance(result.value.type, focusClass.type); |
1943 return isOk ? result.value.type.element : null; | 2068 return isOk ? result.value.type.element : null; |
1944 } else { | 2069 } else { |
1945 // Not a const top level variable, not relevant. | 2070 // Not a const top-level variable, not relevant. |
1946 return null; | 2071 return null; |
1947 } | 2072 } |
1948 } | 2073 } |
1949 // Otherwise [element] is some other construct which is not supported. | 2074 // Otherwise [element] is some other construct which is not supported. |
1950 // | 2075 // |
1951 // TODO(eernst) clarify: We need to consider whether there could be some | 2076 // TODO(eernst) clarify: We need to consider whether there could be some |
1952 // other syntactic constructs that are incorrectly assumed by programmers | 2077 // other syntactic constructs that are incorrectly assumed by programmers |
1953 // to be usable with Reflectable. Currently, such constructs will silently | 2078 // to be usable with Reflectable. Currently, such constructs will silently |
1954 // have no effect; it might be better to emit a diagnostic message (a | 2079 // 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". | 2080 // hint?) in order to notify the programmer that "it does not work". |
(...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2126 } else { | 2251 } else { |
2127 _ReflectorDomain domain = getReflectorDomain(reflector); | 2252 _ReflectorDomain domain = getReflectorDomain(reflector); |
2128 if (!domain._classes.contains(type)) { | 2253 if (!domain._classes.contains(type)) { |
2129 if (type.isMixinApplication) { | 2254 if (type.isMixinApplication) { |
2130 // Iterate over all mixins in most-general-first order (so with | 2255 // Iterate over all mixins in most-general-first order (so with |
2131 // `class C extends B with M1, M2..` we visit `M1` then `M2`. | 2256 // `class C extends B with M1, M2..` we visit `M1` then `M2`. |
2132 ClassElement superclass = type.supertype.element; | 2257 ClassElement superclass = type.supertype.element; |
2133 for (InterfaceType mixin in type.mixins) { | 2258 for (InterfaceType mixin in type.mixins) { |
2134 ClassElement mixinElement = mixin.element; | 2259 ClassElement mixinElement = mixin.element; |
2135 ClassElement subClass = mixin == type.mixins.last ? type : null; | 2260 ClassElement subClass = mixin == type.mixins.last ? type : null; |
2136 String name = subClass == null ? null : type.name; | 2261 String name = subClass == null |
sigurdm
2015/10/09 07:52:04
Could be
```
String name = subClass ?? (type.isMix
eernst
2015/10/09 10:09:04
It's a bit more tricky than that: If `subClass ==
sigurdm
2015/10/09 10:47:20
Oops - you're right!
| |
2262 ? null | |
2263 : (type.isMixinApplication ? type.name : null); | |
2137 MixinApplication mixinApplication = new MixinApplication( | 2264 MixinApplication mixinApplication = new MixinApplication( |
2138 name, superclass, mixinElement, type.library, subClass); | 2265 name, superclass, mixinElement, type.library, subClass); |
2139 domain._classes.add(mixinApplication); | 2266 domain._classes.add(mixinApplication); |
2140 superclass = mixinApplication; | 2267 superclass = mixinApplication; |
2141 } | 2268 } |
2142 } else { | 2269 } else { |
2143 domain._classes.add(type); | 2270 domain._classes.add(type); |
2144 } | 2271 } |
2145 addLibrary(type.library, reflector); | 2272 addLibrary(type.library, reflector); |
2146 // We need to ensure that the [importCollector] has indeed added | 2273 // We need to ensure that the [importCollector] has indeed added |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2214 addLibrary(library, reflector); | 2341 addLibrary(library, reflector); |
2215 } | 2342 } |
2216 | 2343 |
2217 for (CompilationUnitElement unit in library.units) { | 2344 for (CompilationUnitElement unit in library.units) { |
2218 for (ClassElement type in unit.types) { | 2345 for (ClassElement type in unit.types) { |
2219 for (ClassElement reflector | 2346 for (ClassElement reflector |
2220 in getReflectors(_qualifiedName(type), type.metadata)) { | 2347 in getReflectors(_qualifiedName(type), type.metadata)) { |
2221 addClassDomain(type, reflector); | 2348 addClassDomain(type, reflector); |
2222 } | 2349 } |
2223 } | 2350 } |
2351 for (FunctionElement function in unit.functions) { | |
2352 for (ClassElement reflector in getReflectors( | |
2353 _qualifiedFunctionName(function), function.metadata)) { | |
2354 // We just add the library here, the function itself will be | |
2355 // supported using `invoke` and `declarations` of that library | |
2356 // mirror. | |
2357 addLibrary(library, reflector); | |
2358 } | |
2359 } | |
2224 } | 2360 } |
2225 } | 2361 } |
2226 | 2362 |
2227 return new ReflectionWorld(_resolver, dataId, domains.values.toList(), | 2363 return new ReflectionWorld(_resolver, dataId, domains.values.toList(), |
2228 reflectableLibrary, entryPoint, importCollector); | 2364 reflectableLibrary, entryPoint, importCollector); |
2229 } | 2365 } |
2230 | 2366 |
2231 /// Returns the [ReflectCapability] denoted by the given [initializer]. | 2367 /// Returns the [ReflectCapability] denoted by the given [initializer]. |
2232 ec.ReflectCapability _capabilityOfExpression(LibraryElement capabilityLibrary, | 2368 ec.ReflectCapability _capabilityOfExpression(LibraryElement capabilityLibrary, |
2233 Expression expression, LibraryElement containingLibrary) { | 2369 Expression expression, LibraryElement containingLibrary) { |
(...skipping 347 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2581 bool _accessorIsntImplicitGetterOrSetter(PropertyAccessorElement accessor) { | 2717 bool _accessorIsntImplicitGetterOrSetter(PropertyAccessorElement accessor) { |
2582 return !accessor.isSynthetic || (!accessor.isGetter && !accessor.isSetter); | 2718 return !accessor.isSynthetic || (!accessor.isGetter && !accessor.isSetter); |
2583 } | 2719 } |
2584 | 2720 |
2585 bool _executableIsntImplicitGetterOrSetter(ExecutableElement executable) { | 2721 bool _executableIsntImplicitGetterOrSetter(ExecutableElement executable) { |
2586 return executable is! PropertyAccessorElement || | 2722 return executable is! PropertyAccessorElement || |
2587 _accessorIsntImplicitGetterOrSetter(executable); | 2723 _accessorIsntImplicitGetterOrSetter(executable); |
2588 } | 2724 } |
2589 | 2725 |
2590 /// Returns an integer encoding of the kind and attributes of the given | 2726 /// Returns an integer encoding of the kind and attributes of the given |
2727 /// class. | |
2728 int _classDescriptor(ClassElement element) { | |
2729 int result = constants.clazz; | |
2730 if (element.isPrivate) result |= constants.privateAttribute; | |
2731 if (element.isSynthetic) result |= constants.syntheticAttribute; | |
2732 if (element.isAbstract) result |= constants.abstractAttribute; | |
2733 if (element.isEnum) result |= constants.enumAttribute; | |
2734 return result; | |
2735 } | |
2736 | |
2737 /// Returns an integer encoding of the kind and attributes of the given | |
2591 /// field. | 2738 /// field. |
2592 int _fieldDescriptor(FieldElement element) { | 2739 int _fieldDescriptor(FieldElement element) { |
2593 int result = constants.field; | 2740 int result = constants.field; |
2594 if (element.isPrivate) result |= constants.privateAttribute; | 2741 if (element.isPrivate) result |= constants.privateAttribute; |
2595 if (element.isSynthetic) result |= constants.syntheticAttribute; | 2742 if (element.isSynthetic) result |= constants.syntheticAttribute; |
2596 if (element.isConst) { | 2743 if (element.isConst) { |
2597 result |= constants.constAttribute; | 2744 result |= constants.constAttribute; |
2598 // We will get `false` from `element.isFinal` in this case, but with | 2745 // We will get `false` from `element.isFinal` in this case, but with |
2599 // a mirror from 'dart:mirrors' it is considered to be "implicitly | 2746 // a mirror from 'dart:mirrors' it is considered to be "implicitly |
2600 // final", so we follow that and ignore `element.isFinal`. | 2747 // final", so we follow that and ignore `element.isFinal`. |
(...skipping 332 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2933 metadataParts.add("const $prefix.$constructor($arguments)"); | 3080 metadataParts.add("const $prefix.$constructor($arguments)"); |
2934 } else { | 3081 } else { |
2935 // A field reference. | 3082 // A field reference. |
2936 metadataParts.add("$prefix.${annotationNode.name}"); | 3083 metadataParts.add("$prefix.${annotationNode.name}"); |
2937 } | 3084 } |
2938 } | 3085 } |
2939 | 3086 |
2940 return _formatAsList("Object", metadataParts); | 3087 return _formatAsList("Object", metadataParts); |
2941 } | 3088 } |
2942 | 3089 |
3090 Iterable<TopLevelVariableElement> _extractDeclaredVariables( | |
sigurdm
2015/10/09 07:52:04
Give these functions a (short) comment
eernst
2015/10/09 10:09:05
Done.
| |
3091 LibraryElement libraryElement, _Capabilities capabilities) sync* { | |
3092 for (CompilationUnitElement unit in libraryElement.units) { | |
3093 for (TopLevelVariableElement variable in unit.topLevelVariables) { | |
3094 if (variable.isPrivate || variable.isSynthetic) continue; | |
3095 // TODO(eernst) clarify: Do we want to subsume variables under invoke? | |
3096 if (capabilities.supportsTopLevelInvoke( | |
3097 variable.name, variable.metadata)) { | |
3098 yield variable; | |
3099 } | |
3100 } | |
3101 } | |
3102 } | |
3103 | |
3104 Iterable<FunctionElement> _extractDeclaredFunctions( | |
3105 LibraryElement libraryElement, _Capabilities capabilities) sync* { | |
3106 for (CompilationUnitElement unit in libraryElement.units) { | |
3107 for (FunctionElement function in unit.functions) { | |
3108 if (function.isPrivate) continue; | |
3109 if (capabilities.supportsTopLevelInvoke( | |
3110 function.name, function.metadata)) { | |
3111 yield function; | |
3112 } | |
3113 } | |
3114 } | |
3115 } | |
3116 | |
3117 Iterable<ParameterElement> _extractDeclaredFunctionParameters( | |
3118 Iterable<FunctionElement> declaredFunctions, | |
3119 Iterable<PropertyAccessorElement> accessors) { | |
3120 List<ParameterElement> result = <ParameterElement>[]; | |
3121 for (FunctionElement declaredFunction in declaredFunctions) { | |
3122 result.addAll(declaredFunction.parameters); | |
3123 } | |
3124 for (PropertyAccessorElement accessor in accessors) { | |
3125 if (accessor.isSetter) { | |
3126 result.addAll(accessor.parameters); | |
3127 } | |
3128 } | |
3129 return result; | |
3130 } | |
3131 | |
2943 Iterable<FieldElement> _extractDeclaredFields( | 3132 Iterable<FieldElement> _extractDeclaredFields( |
2944 ClassElement classElement, _Capabilities capabilities) { | 3133 ClassElement classElement, _Capabilities capabilities) { |
2945 return classElement.fields.where((FieldElement field) { | 3134 return classElement.fields.where((FieldElement field) { |
2946 if (field.isPrivate) return false; | 3135 if (field.isPrivate) return false; |
2947 Function capabilityChecker = field.isStatic | 3136 Function capabilityChecker = field.isStatic |
2948 ? capabilities.supportsStaticInvoke | 3137 ? capabilities.supportsStaticInvoke |
2949 : capabilities.supportsInstanceInvoke; | 3138 : capabilities.supportsInstanceInvoke; |
2950 return !field.isSynthetic && capabilityChecker(field.name, field.metadata); | 3139 return !field.isSynthetic && capabilityChecker(field.name, field.metadata); |
2951 }); | 3140 }); |
2952 } | 3141 } |
(...skipping 21 matching lines...) Expand all Loading... | |
2974 result.addAll(declaredConstructor.parameters); | 3163 result.addAll(declaredConstructor.parameters); |
2975 } | 3164 } |
2976 for (PropertyAccessorElement accessor in accessors) { | 3165 for (PropertyAccessorElement accessor in accessors) { |
2977 if (accessor.isSetter) { | 3166 if (accessor.isSetter) { |
2978 result.addAll(accessor.parameters); | 3167 result.addAll(accessor.parameters); |
2979 } | 3168 } |
2980 } | 3169 } |
2981 return result; | 3170 return result; |
2982 } | 3171 } |
2983 | 3172 |
3173 Iterable<PropertyAccessorElement> _declaredAndImplicitLibraryAccessors( | |
3174 LibraryElement libraryElement, _Capabilities capabilities) sync* { | |
3175 for (CompilationUnitElement unit in libraryElement.units) { | |
3176 for (PropertyAccessorElement accessor in unit.accessors) { | |
3177 if (accessor.isPrivate) continue; | |
3178 if (capabilities.supportsTopLevelInvoke( | |
3179 accessor.name, accessor.metadata)) { | |
3180 yield accessor; | |
3181 } | |
3182 } | |
3183 } | |
3184 } | |
3185 | |
2984 /// Returns the [PropertyAccessorElement]s which are the accessors | 3186 /// Returns the [PropertyAccessorElement]s which are the accessors |
2985 /// of the given [classElement], including both the declared ones | 3187 /// of the given [classElement], including both the declared ones |
2986 /// and the implicitly generated ones corresponding to fields. This | 3188 /// and the implicitly generated ones corresponding to fields. This |
2987 /// is the set of accessors that corresponds to the behavioral interface | 3189 /// is the set of accessors that corresponds to the behavioral interface |
2988 /// of the corresponding instances, as opposed to the source code oriented | 3190 /// of the corresponding instances, as opposed to the source code oriented |
2989 /// interface, e.g., `declarations`. But the latter can be computed from | 3191 /// interface, e.g., `declarations`. But the latter can be computed from |
2990 /// here, by filtering out the accessors whose `isSynthetic` is true | 3192 /// here, by filtering out the accessors whose `isSynthetic` is true |
2991 /// and adding the fields. | 3193 /// and adding the fields. |
2992 Iterable<PropertyAccessorElement> _declaredAndImplicitAccessors( | 3194 Iterable<PropertyAccessorElement> _declaredAndImplicitAccessors( |
2993 ClassElement classElement, _Capabilities capabilities) { | 3195 ClassElement classElement, _Capabilities capabilities) { |
2994 return classElement.accessors.where((PropertyAccessorElement accessor) { | 3196 return classElement.accessors.where((PropertyAccessorElement accessor) { |
2995 if (accessor.isPrivate) return false; | 3197 if (accessor.isPrivate) return false; |
2996 Function capabilityChecker = accessor.isStatic | 3198 Function capabilityChecker = accessor.isStatic |
2997 ? capabilities.supportsStaticInvoke | 3199 ? capabilities.supportsStaticInvoke |
2998 : capabilities.supportsInstanceInvoke; | 3200 : capabilities.supportsInstanceInvoke; |
2999 return capabilityChecker(accessor.name, accessor.metadata); | 3201 return capabilityChecker(accessor.name, accessor.metadata); |
3000 }); | 3202 }); |
3001 } | 3203 } |
3002 | 3204 |
3003 Iterable<ConstructorElement> _declaredConstructors( | 3205 Iterable<ConstructorElement> _declaredConstructors( |
3004 ClassElement classElement, _Capabilities capabilities) { | 3206 ClassElement classElement, _Capabilities capabilities) { |
3005 return classElement.constructors.where((ConstructorElement constructor) { | 3207 return classElement.constructors.where((ConstructorElement constructor) { |
3006 if (constructor.isPrivate) return false; | 3208 if (constructor.isPrivate) return false; |
3007 return capabilities.supportsNewInstance( | 3209 return capabilities.supportsNewInstance( |
3008 constructor.name, constructor.metadata); | 3210 constructor.name, constructor.metadata); |
3009 }); | 3211 }); |
3010 } | 3212 } |
3011 | 3213 |
3214 _LibraryDomain _createLibraryDomain( | |
3215 LibraryElement library, _ReflectorDomain domain) { | |
3216 List<TopLevelVariableElement> declaredVariablesOfLibrary = | |
3217 _extractDeclaredVariables(library, domain._capabilities).toList(); | |
3218 List<FunctionElement> declaredFunctionsOfLibrary = | |
3219 _extractDeclaredFunctions(library, domain._capabilities).toList(); | |
3220 List<PropertyAccessorElement> declaredAndImplicitAccessorsOfLibrary = | |
3221 _declaredAndImplicitLibraryAccessors(library, domain._capabilities); | |
3222 List<ParameterElement> declaredParametersOfLibrary = | |
3223 _extractDeclaredFunctionParameters( | |
3224 declaredFunctionsOfLibrary, declaredAndImplicitAccessorsOfLibrary); | |
3225 return new _LibraryDomain( | |
3226 library, | |
3227 declaredVariablesOfLibrary, | |
3228 declaredFunctionsOfLibrary, | |
3229 declaredParametersOfLibrary, | |
3230 declaredAndImplicitAccessorsOfLibrary, | |
3231 domain); | |
3232 } | |
3233 | |
3012 _ClassDomain _createClassDomain(ClassElement type, _ReflectorDomain domain) { | 3234 _ClassDomain _createClassDomain(ClassElement type, _ReflectorDomain domain) { |
3013 if (type is MixinApplication) { | 3235 if (type is MixinApplication) { |
3014 List<FieldElement> declaredFieldsOfClass = | 3236 List<FieldElement> declaredFieldsOfClass = |
3015 _extractDeclaredFields(type.mixin, domain._capabilities) | 3237 _extractDeclaredFields(type.mixin, domain._capabilities) |
3016 .where((FieldElement e) => !e.isStatic) | 3238 .where((FieldElement e) => !e.isStatic) |
3017 .toList(); | 3239 .toList(); |
3018 List<MethodElement> declaredMethodsOfClass = | 3240 List<MethodElement> declaredMethodsOfClass = |
3019 _extractDeclaredMethods(type.mixin, domain._capabilities) | 3241 _extractDeclaredMethods(type.mixin, domain._capabilities) |
3020 .where((MethodElement e) => !e.isStatic) | 3242 .where((MethodElement e) => !e.isStatic) |
3021 .toList(); | 3243 .toList(); |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3109 String get name { | 3331 String get name { |
3110 if (declaredName != null) return declaredName; | 3332 if (declaredName != null) return declaredName; |
3111 if (superclass is MixinApplication) { | 3333 if (superclass is MixinApplication) { |
3112 return "${superclass.name}, ${_qualifiedName(mixin)}"; | 3334 return "${superclass.name}, ${_qualifiedName(mixin)}"; |
3113 } else { | 3335 } else { |
3114 return "${_qualifiedName(superclass)} with ${_qualifiedName(mixin)}"; | 3336 return "${_qualifiedName(superclass)} with ${_qualifiedName(mixin)}"; |
3115 } | 3337 } |
3116 } | 3338 } |
3117 | 3339 |
3118 @override | 3340 @override |
3341 String get displayName => name; | |
3342 | |
3343 @override | |
3119 List<InterfaceType> get interfaces => <InterfaceType>[]; | 3344 List<InterfaceType> get interfaces => <InterfaceType>[]; |
3120 | 3345 |
3121 @override | 3346 @override |
3122 List<ElementAnnotation> get metadata => <ElementAnnotation>[]; | 3347 List<ElementAnnotation> get metadata => <ElementAnnotation>[]; |
3123 | 3348 |
3124 @override | 3349 @override |
3125 bool get isSynthetic => declaredName != null; | 3350 bool get isSynthetic => declaredName == null; |
3126 | 3351 |
3127 // Note that the `InterfaceTypeImpl` may well call methods on this | 3352 // Note that the `InterfaceTypeImpl` may well call methods on this |
3128 // `MixinApplication` whose body is `_unImplemented()`, but it still provides | 3353 // `MixinApplication` whose body is `_unImplemented()`, but it still provides |
3129 // a slightly better service than leaving this method `_unImplemented()`: | 3354 // a slightly better service than leaving this method `_unImplemented()`: |
3130 // We are allowed to take one more step, which may be enough. | 3355 // We are allowed to take one more step, which may be enough. |
3131 @override | 3356 @override |
3132 InterfaceType get type => new InterfaceTypeImpl(this); | 3357 InterfaceType get type => new InterfaceTypeImpl(this); |
3133 | 3358 |
3134 @override | 3359 @override |
3135 InterfaceType get supertype { | 3360 InterfaceType get supertype { |
(...skipping 12 matching lines...) Expand all Loading... | |
3148 } | 3373 } |
3149 | 3374 |
3150 /// Returns true iff this class was declared using the syntax | 3375 /// 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 | 3376 /// `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 | 3377 /// application. We do not create instances of this class in that |
3153 /// case. | 3378 /// case. |
3154 @override | 3379 @override |
3155 bool get isMixinApplication => declaredName != null; | 3380 bool get isMixinApplication => declaredName != null; |
3156 | 3381 |
3157 @override | 3382 @override |
3383 bool get isAbstract => !isMixinApplication || mixin.isAbstract; | |
3384 | |
3385 @override | |
3386 // TODO(eernst) clarify: Is this test correct? Are all cases possible? | |
3387 bool get isEnum => mixin.isEnum || superclass.isEnum; | |
sigurdm
2015/10/09 07:52:04
As I understand it you cannot mix an enum in or su
eernst
2015/10/09 10:09:04
Yep, the spec confirms that. Removed the comment,
| |
3388 | |
3389 @override | |
3158 NamedCompilationUnitMember computeNode() => | 3390 NamedCompilationUnitMember computeNode() => |
3159 declaredName != null ? subclass.computeNode() : null; | 3391 declaredName != null ? subclass.computeNode() : null; |
3160 | 3392 |
3161 @override | 3393 @override |
3162 bool operator ==(Object object) { | 3394 bool operator ==(Object object) { |
3163 return object is MixinApplication && | 3395 return object is MixinApplication && |
3164 superclass == object.superclass && | 3396 superclass == object.superclass && |
3165 mixin == object.mixin && | 3397 mixin == object.mixin && |
3166 library == object.library && | 3398 library == object.library && |
3167 subclass == object.subclass; | 3399 subclass == object.subclass; |
(...skipping 21 matching lines...) Expand all Loading... | |
3189 @override | 3421 @override |
3190 bool get hasNonFinalField => _unImplemented(); | 3422 bool get hasNonFinalField => _unImplemented(); |
3191 | 3423 |
3192 @override | 3424 @override |
3193 bool get hasReferenceToSuper => _unImplemented(); | 3425 bool get hasReferenceToSuper => _unImplemented(); |
3194 | 3426 |
3195 @override | 3427 @override |
3196 bool get hasStaticMember => _unImplemented(); | 3428 bool get hasStaticMember => _unImplemented(); |
3197 | 3429 |
3198 @override | 3430 @override |
3199 bool get isAbstract => _unImplemented(); | |
3200 | |
3201 @override | |
3202 bool get isEnum => _unImplemented(); | |
3203 | |
3204 @override | |
3205 bool get isOrInheritsProxy => _unImplemented(); | 3431 bool get isOrInheritsProxy => _unImplemented(); |
3206 | 3432 |
3207 @override | 3433 @override |
3208 bool get isProxy => _unImplemented(); | 3434 bool get isProxy => _unImplemented(); |
3209 | 3435 |
3210 @override | 3436 @override |
3211 bool get isTypedef => _unImplemented(); | 3437 bool get isTypedef => _unImplemented(); |
3212 | 3438 |
3213 @override | 3439 @override |
3214 bool get isValidMixin => _unImplemented(); | 3440 bool get isValidMixin => _unImplemented(); |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3290 } | 3516 } |
3291 | 3517 |
3292 // This seems to be the defined behaviour according to dart:mirrors. | 3518 // This seems to be the defined behaviour according to dart:mirrors. |
3293 @override | 3519 @override |
3294 bool get isPrivate => false; | 3520 bool get isPrivate => false; |
3295 | 3521 |
3296 @override | 3522 @override |
3297 get context => _unImplemented(); | 3523 get context => _unImplemented(); |
3298 | 3524 |
3299 @override | 3525 @override |
3300 String get displayName => _unImplemented(); | |
3301 | |
3302 @override | |
3303 Element get enclosingElement => _unImplemented(); | 3526 Element get enclosingElement => _unImplemented(); |
3304 | 3527 |
3305 @override | 3528 @override |
3306 int get id => _unImplemented(); | 3529 int get id => _unImplemented(); |
3307 | 3530 |
3308 @override | 3531 @override |
3309 bool get isDeprecated => _unImplemented(); | 3532 bool get isDeprecated => _unImplemented(); |
3310 | 3533 |
3311 @override | 3534 @override |
3312 bool get isOverride => _unImplemented(); | 3535 bool get isOverride => _unImplemented(); |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3349 | 3572 |
3350 @override | 3573 @override |
3351 void visitChildren(ElementVisitor visitor) => _unImplemented(); | 3574 void visitChildren(ElementVisitor visitor) => _unImplemented(); |
3352 } | 3575 } |
3353 | 3576 |
3354 String _qualifiedName(ClassElement classElement) { | 3577 String _qualifiedName(ClassElement classElement) { |
3355 return classElement == null | 3578 return classElement == null |
3356 ? "null" | 3579 ? "null" |
3357 : "${classElement.library.name}.${classElement.name}"; | 3580 : "${classElement.library.name}.${classElement.name}"; |
3358 } | 3581 } |
3582 | |
3583 String _qualifiedFunctionName(FunctionElement functionElement) { | |
3584 return functionElement == null | |
3585 ? "null" | |
3586 : "${functionElement.library.name}.${functionElement.name}"; | |
3587 } | |
OLD | NEW |