OLD | NEW |
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 library dart2js.resolution.members; | 5 library dart2js.resolution.members; |
6 | 6 |
7 import '../compiler.dart' show | 7 import '../compiler.dart' show |
8 Compiler, | 8 Compiler, |
9 isPrivateName; | 9 isPrivateName; |
10 import '../constants/constructors.dart' show | 10 import '../constants/constructors.dart' show |
(...skipping 2780 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2791 } | 2791 } |
2792 | 2792 |
2793 // TODO(23998): Remove these when all information goes through | 2793 // TODO(23998): Remove these when all information goes through |
2794 // the [SendStructure]. | 2794 // the [SendStructure]. |
2795 registry.useElement(node, member); | 2795 registry.useElement(node, member); |
2796 registry.setSelector(node, selector); | 2796 registry.setSelector(node, selector); |
2797 | 2797 |
2798 return result; | 2798 return result; |
2799 } | 2799 } |
2800 | 2800 |
| 2801 /// Handle update of a static or top level [element]. |
| 2802 ResolutionResult handleStaticOrTopLevelUpdate( |
| 2803 SendSet node, Name name, Element element) { |
| 2804 AccessSemantics semantics; |
| 2805 if (element.isAbstractField) { |
| 2806 AbstractFieldElement abstractField = element; |
| 2807 if (abstractField.setter == null) { |
| 2808 ErroneousElement error = reportAndCreateErroneousElement( |
| 2809 node.selector, name.text, |
| 2810 MessageKind.CANNOT_RESOLVE_SETTER, const {}); |
| 2811 registry.registerThrowNoSuchMethod(); |
| 2812 |
| 2813 if (node.isComplex) { |
| 2814 // `a++` or `a += b` where `a` has no setter. |
| 2815 semantics = new CompoundAccessSemantics( |
| 2816 element.isTopLevel |
| 2817 ? CompoundAccessKind.UNRESOLVED_TOPLEVEL_SETTER |
| 2818 : CompoundAccessKind.UNRESOLVED_STATIC_SETTER, |
| 2819 abstractField.getter, |
| 2820 error); |
| 2821 } else { |
| 2822 // `a = b` where `a` has no setter. |
| 2823 semantics = element.isTopLevel |
| 2824 ? new StaticAccess.topLevelGetter(abstractField.getter) |
| 2825 : new StaticAccess.staticGetter(abstractField.getter); |
| 2826 } |
| 2827 registry.registerStaticUse(abstractField.getter); |
| 2828 } else if (node.isComplex) { |
| 2829 if (abstractField.getter == null) { |
| 2830 ErroneousElement error = reportAndCreateErroneousElement( |
| 2831 node.selector, name.text, |
| 2832 MessageKind.CANNOT_RESOLVE_GETTER, const {}); |
| 2833 registry.registerThrowNoSuchMethod(); |
| 2834 // `a++` or `a += b` where `a` has no getter. |
| 2835 semantics = new CompoundAccessSemantics( |
| 2836 element.isTopLevel |
| 2837 ? CompoundAccessKind.UNRESOLVED_TOPLEVEL_GETTER |
| 2838 : CompoundAccessKind.UNRESOLVED_STATIC_GETTER, |
| 2839 error, |
| 2840 abstractField.setter); |
| 2841 registry.registerStaticUse(abstractField.setter); |
| 2842 } else { |
| 2843 // `a++` or `a += b` where `a` has both a getter and a setter. |
| 2844 semantics = new CompoundAccessSemantics( |
| 2845 element.isTopLevel |
| 2846 ? CompoundAccessKind.TOPLEVEL_GETTER_SETTER |
| 2847 : CompoundAccessKind.STATIC_GETTER_SETTER, |
| 2848 abstractField.getter, |
| 2849 abstractField.setter); |
| 2850 registry.registerStaticUse(abstractField.getter); |
| 2851 registry.registerStaticUse(abstractField.setter); |
| 2852 } |
| 2853 } else { |
| 2854 // `a = b` where `a` has a setter. |
| 2855 semantics = element.isTopLevel |
| 2856 ? new StaticAccess.topLevelSetter(abstractField.setter) |
| 2857 : new StaticAccess.staticSetter(abstractField.setter); |
| 2858 registry.registerStaticUse(abstractField.setter); |
| 2859 } |
| 2860 } else { |
| 2861 MemberElement member = element; |
| 2862 // TODO(johnniwinther): Needed to provoke a parsing and with it discovery |
| 2863 // of parse errors to make [element] erroneous. Fix this! |
| 2864 member.computeType(compiler); |
| 2865 registry.registerStaticUse(member); |
| 2866 if (member.isErroneous) { |
| 2867 // [member] has parse errors. |
| 2868 semantics = new StaticAccess.unresolved(member); |
| 2869 } else if (member.isFunction) { |
| 2870 // `a = b`, `a++` or `a += b` where `a` is a function. |
| 2871 ErroneousElement error = reportAndCreateErroneousElement( |
| 2872 node.selector, name.text, |
| 2873 MessageKind.ASSIGNING_METHOD, const {}); |
| 2874 registry.registerThrowNoSuchMethod(); |
| 2875 if (node.isComplex) { |
| 2876 // `a++` or `a += b` where `a` is a function. |
| 2877 registry.registerGetOfStaticFunction(element); |
| 2878 } |
| 2879 semantics = member.isTopLevel |
| 2880 ? new StaticAccess.topLevelMethod(member) |
| 2881 : new StaticAccess.staticMethod(member); |
| 2882 } else { |
| 2883 // `a = b`, `a++` or `a += b` where `a` is a field. |
| 2884 assert(invariant(node, member.isField, |
| 2885 message: "Unexpected element: $member.")); |
| 2886 if (member.isFinal || member.isConst) { |
| 2887 ErroneousElement error = reportAndCreateErroneousElement( |
| 2888 node.selector, name.text, |
| 2889 MessageKind.CANNOT_RESOLVE_SETTER, const {}); |
| 2890 registry.registerThrowNoSuchMethod(); |
| 2891 semantics = member.isTopLevel |
| 2892 ? new StaticAccess.finalTopLevelField(member) |
| 2893 : new StaticAccess.finalStaticField(member); |
| 2894 } else { |
| 2895 semantics = member.isTopLevel |
| 2896 ? new StaticAccess.topLevelField(member) |
| 2897 : new StaticAccess.staticField(member); |
| 2898 } |
| 2899 } |
| 2900 } |
| 2901 return handleUpdate(node, name, semantics); |
| 2902 } |
| 2903 |
2801 /// Handle access to resolved [element]. | 2904 /// Handle access to resolved [element]. |
2802 ResolutionResult handleResolvedSend(Send node, Name name, Element element) { | 2905 ResolutionResult handleResolvedSend(Send node, Name name, Element element) { |
2803 if (element.isAmbiguous) { | 2906 if (element.isAmbiguous) { |
2804 return handleAmbiguousSend(node, name, element); | 2907 return handleAmbiguousSend(node, name, element); |
2805 } | 2908 } |
2806 if (element.isErroneous) { | 2909 if (element.isErroneous) { |
2807 // This handles elements with parser errors. | 2910 // This handles elements with parser errors. |
2808 // TODO(johnniwinther): Elements with parse error should not set | 2911 // TODO(johnniwinther): Elements with parse error should not set |
2809 // [isErroneous] to `true`. | 2912 // [isErroneous] to `true`. |
2810 assert(invariant(node, element is! ErroneousElement, | 2913 assert(invariant(node, element is! ErroneousElement, |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2862 } | 2965 } |
2863 if (element.isClass) { | 2966 if (element.isClass) { |
2864 // `C = b`, `C++`, or 'C += b` where 'C' is a class. | 2967 // `C = b`, `C++`, or 'C += b` where 'C' is a class. |
2865 return handleClassTypeLiteralUpdate(node, name, element); | 2968 return handleClassTypeLiteralUpdate(node, name, element); |
2866 } else if (element.isTypedef) { | 2969 } else if (element.isTypedef) { |
2867 // `C = b`, `C++`, or 'C += b` where 'F' is a typedef. | 2970 // `C = b`, `C++`, or 'C += b` where 'F' is a typedef. |
2868 return handleTypedefTypeLiteralUpdate(node, name, element); | 2971 return handleTypedefTypeLiteralUpdate(node, name, element); |
2869 } else if (element.isTypeVariable) { | 2972 } else if (element.isTypeVariable) { |
2870 // `T = b`, `T++`, or 'T += b` where 'T' is a type variable. | 2973 // `T = b`, `T++`, or 'T += b` where 'T' is a type variable. |
2871 return handleTypeVariableTypeLiteralUpdate(node, name, element); | 2974 return handleTypeVariableTypeLiteralUpdate(node, name, element); |
| 2975 } else if (element.isStatic || element.isTopLevel) { |
| 2976 return handleStaticOrTopLevelUpdate(node, name, element); |
2872 } | 2977 } |
2873 return oldVisitSendSet(node); | 2978 return oldVisitSendSet(node); |
2874 } | 2979 } |
2875 | 2980 |
2876 /// Handle an unqualified [Send], that is where the `node.receiver` is null, | 2981 /// Handle an unqualified [Send], that is where the `node.receiver` is null, |
2877 /// like `a`, `a()`, `this()`, `assert()`, and `(){}()`. | 2982 /// like `a`, `a()`, `this()`, `assert()`, and `(){}()`. |
2878 ResolutionResult handleUnqualifiedSend(Send node) { | 2983 ResolutionResult handleUnqualifiedSend(Send node) { |
2879 Identifier selector = node.selector.asIdentifier(); | 2984 Identifier selector = node.selector.asIdentifier(); |
2880 if (selector == null) { | 2985 if (selector == null) { |
2881 // `(){}()` and `(foo)()`. | 2986 // `(){}()` and `(foo)()`. |
(...skipping 1755 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4637 } | 4742 } |
4638 return const NoneResult(); | 4743 return const NoneResult(); |
4639 } | 4744 } |
4640 } | 4745 } |
4641 | 4746 |
4642 /// Looks up [name] in [scope] and unwraps the result. | 4747 /// Looks up [name] in [scope] and unwraps the result. |
4643 Element lookupInScope(Compiler compiler, Node node, | 4748 Element lookupInScope(Compiler compiler, Node node, |
4644 Scope scope, String name) { | 4749 Scope scope, String name) { |
4645 return Elements.unwrap(scope.lookup(name), compiler, node); | 4750 return Elements.unwrap(scope.lookup(name), compiler, node); |
4646 } | 4751 } |
OLD | NEW |