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 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 } |
OLD | NEW |