| 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 |