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 '../common.dart'; | 7 import '../common.dart'; |
8 import '../common/names.dart' show | 8 import '../common/names.dart' show |
9 Selectors; | 9 Selectors; |
10 import '../compiler.dart' show | 10 import '../compiler.dart' show |
(...skipping 358 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
369 // objects than [Element] from this method. | 369 // objects than [Element] from this method. |
370 element = compiler.typeClass; | 370 element = compiler.typeClass; |
371 // Set the type to be `dynamic` to mark that this is a type literal. | 371 // Set the type to be `dynamic` to mark that this is a type literal. |
372 registry.setType(node, const DynamicType()); | 372 registry.setType(node, const DynamicType()); |
373 } | 373 } |
374 element = reportLookupErrorIfAny(element, node, name); | 374 element = reportLookupErrorIfAny(element, node, name); |
375 if (element == null) { | 375 if (element == null) { |
376 if (!inInstanceContext) { | 376 if (!inInstanceContext) { |
377 element = reportCannotResolve(node, name); | 377 element = reportCannotResolve(node, name); |
378 } | 378 } |
379 } else if (element.isErroneous) { | 379 } else if (element.isMalformed) { |
380 // Use the erroneous element. | 380 // Use the malformed element. |
381 } else { | 381 } else { |
382 if ((element.kind.category & allowedCategory) == 0) { | 382 if ((element.kind.category & allowedCategory) == 0) { |
383 element = reportAndCreateErroneousElement( | 383 element = reportAndCreateErroneousElement( |
384 node, name, MessageKind.GENERIC, | 384 node, name, MessageKind.GENERIC, |
385 // TODO(ahe): Improve error message. Need UX input. | 385 // TODO(ahe): Improve error message. Need UX input. |
386 {'text': "is not an expression $element"}); | 386 {'text': "is not an expression $element"}); |
387 } | 387 } |
388 } | 388 } |
389 if (!Elements.isUnresolved(element) && element.isClass) { | 389 if (!Elements.isUnresolved(element) && element.isClass) { |
390 ClassElement classElement = element; | 390 ClassElement classElement = element; |
(...skipping 426 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
817 MessageKind.NO_THIS_AVAILABLE, const {}, | 817 MessageKind.NO_THIS_AVAILABLE, const {}, |
818 isError: true); | 818 isError: true); |
819 registry.registerCompileTimeError(error); | 819 registry.registerCompileTimeError(error); |
820 return new StaticAccess.invalid(error); | 820 return new StaticAccess.invalid(error); |
821 } | 821 } |
822 return null; | 822 return null; |
823 } | 823 } |
824 | 824 |
825 /// Compute the [AccessSemantics] corresponding to a super access of [target]. | 825 /// Compute the [AccessSemantics] corresponding to a super access of [target]. |
826 AccessSemantics computeSuperAccessSemantics(Spannable node, Element target) { | 826 AccessSemantics computeSuperAccessSemantics(Spannable node, Element target) { |
827 if (target.isErroneous) { | 827 if (target.isMalformed) { |
828 return new StaticAccess.unresolvedSuper(target); | 828 return new StaticAccess.unresolvedSuper(target); |
829 } else if (target.isGetter) { | 829 } else if (target.isGetter) { |
830 return new StaticAccess.superGetter(target); | 830 return new StaticAccess.superGetter(target); |
831 } else if (target.isSetter) { | 831 } else if (target.isSetter) { |
832 return new StaticAccess.superSetter(target); | 832 return new StaticAccess.superSetter(target); |
833 } else if (target.isField) { | 833 } else if (target.isField) { |
834 if (target.isFinal) { | 834 if (target.isFinal) { |
835 return new StaticAccess.superFinalField(target); | 835 return new StaticAccess.superFinalField(target); |
836 } else { | 836 } else { |
837 return new StaticAccess.superField(target); | 837 return new StaticAccess.superField(target); |
838 } | 838 } |
839 } else { | 839 } else { |
840 assert(invariant(node, target.isFunction, | 840 assert(invariant(node, target.isFunction, |
841 message: "Unexpected super target '$target'.")); | 841 message: "Unexpected super target '$target'.")); |
842 return new StaticAccess.superMethod(target); | 842 return new StaticAccess.superMethod(target); |
843 } | 843 } |
844 } | 844 } |
845 | 845 |
846 /// Compute the [AccessSemantics] corresponding to a compound super access | 846 /// Compute the [AccessSemantics] corresponding to a compound super access |
847 /// reading from [getter] and writing to [setter]. | 847 /// reading from [getter] and writing to [setter]. |
848 AccessSemantics computeCompoundSuperAccessSemantics( | 848 AccessSemantics computeCompoundSuperAccessSemantics( |
849 Spannable node, | 849 Spannable node, |
850 Element getter, | 850 Element getter, |
851 Element setter, | 851 Element setter, |
852 {bool isIndex: false}) { | 852 {bool isIndex: false}) { |
853 if (getter.isErroneous) { | 853 if (getter.isMalformed) { |
854 if (setter.isErroneous) { | 854 if (setter.isMalformed) { |
855 return new StaticAccess.unresolvedSuper(getter); | 855 return new StaticAccess.unresolvedSuper(getter); |
856 } else if (setter.isFunction) { | 856 } else if (setter.isFunction) { |
857 assert(invariant(node, setter.name == '[]=', | 857 assert(invariant(node, setter.name == '[]=', |
858 message: "Unexpected super setter '$setter'.")); | 858 message: "Unexpected super setter '$setter'.")); |
859 return new CompoundAccessSemantics( | 859 return new CompoundAccessSemantics( |
860 CompoundAccessKind.UNRESOLVED_SUPER_GETTER, getter, setter); | 860 CompoundAccessKind.UNRESOLVED_SUPER_GETTER, getter, setter); |
861 } else { | 861 } else { |
862 assert(invariant(node, setter.isSetter, | 862 assert(invariant(node, setter.isSetter, |
863 message: "Unexpected super setter '$setter'.")); | 863 message: "Unexpected super setter '$setter'.")); |
864 return new CompoundAccessSemantics( | 864 return new CompoundAccessSemantics( |
865 CompoundAccessKind.UNRESOLVED_SUPER_GETTER, getter, setter); | 865 CompoundAccessKind.UNRESOLVED_SUPER_GETTER, getter, setter); |
866 } | 866 } |
867 } else if (getter.isField) { | 867 } else if (getter.isField) { |
868 if (setter.isErroneous) { | 868 if (setter.isMalformed) { |
869 assert(invariant(node, getter.isFinal, | 869 assert(invariant(node, getter.isFinal, |
870 message: "Unexpected super setter '$setter' for getter '$getter.")); | 870 message: "Unexpected super setter '$setter' for getter '$getter.")); |
871 return new StaticAccess.superFinalField(getter); | 871 return new StaticAccess.superFinalField(getter); |
872 } else if (setter.isField) { | 872 } else if (setter.isField) { |
873 if (getter == setter) { | 873 if (getter == setter) { |
874 return new StaticAccess.superField(getter); | 874 return new StaticAccess.superField(getter); |
875 } else { | 875 } else { |
876 return new CompoundAccessSemantics( | 876 return new CompoundAccessSemantics( |
877 CompoundAccessKind.SUPER_FIELD_FIELD, getter, setter); | 877 CompoundAccessKind.SUPER_FIELD_FIELD, getter, setter); |
878 } | 878 } |
879 } else { | 879 } else { |
880 // Either the field is accessible directly, or a setter shadows the | 880 // Either the field is accessible directly, or a setter shadows the |
881 // setter access. If there was another instance member it would shadow | 881 // setter access. If there was another instance member it would shadow |
882 // the field. | 882 // the field. |
883 assert(invariant(node, setter.isSetter, | 883 assert(invariant(node, setter.isSetter, |
884 message: "Unexpected super setter '$setter'.")); | 884 message: "Unexpected super setter '$setter'.")); |
885 return new CompoundAccessSemantics( | 885 return new CompoundAccessSemantics( |
886 CompoundAccessKind.SUPER_FIELD_SETTER, getter, setter); | 886 CompoundAccessKind.SUPER_FIELD_SETTER, getter, setter); |
887 } | 887 } |
888 } else if (getter.isGetter) { | 888 } else if (getter.isGetter) { |
889 if (setter.isErroneous) { | 889 if (setter.isMalformed) { |
890 return new CompoundAccessSemantics( | 890 return new CompoundAccessSemantics( |
891 CompoundAccessKind.UNRESOLVED_SUPER_SETTER, getter, setter); | 891 CompoundAccessKind.UNRESOLVED_SUPER_SETTER, getter, setter); |
892 } else if (setter.isField) { | 892 } else if (setter.isField) { |
893 return new CompoundAccessSemantics( | 893 return new CompoundAccessSemantics( |
894 CompoundAccessKind.SUPER_GETTER_FIELD, getter, setter); | 894 CompoundAccessKind.SUPER_GETTER_FIELD, getter, setter); |
895 } else { | 895 } else { |
896 assert(invariant(node, setter.isSetter, | 896 assert(invariant(node, setter.isSetter, |
897 message: "Unexpected super setter '$setter'.")); | 897 message: "Unexpected super setter '$setter'.")); |
898 return new CompoundAccessSemantics( | 898 return new CompoundAccessSemantics( |
899 CompoundAccessKind.SUPER_GETTER_SETTER, getter, setter); | 899 CompoundAccessKind.SUPER_GETTER_SETTER, getter, setter); |
900 } | 900 } |
901 } else { | 901 } else { |
902 assert(invariant(node, getter.isFunction, | 902 assert(invariant(node, getter.isFunction, |
903 message: "Unexpected super getter '$getter'.")); | 903 message: "Unexpected super getter '$getter'.")); |
904 if (setter.isErroneous) { | 904 if (setter.isMalformed) { |
905 if (isIndex) { | 905 if (isIndex) { |
906 return new CompoundAccessSemantics( | 906 return new CompoundAccessSemantics( |
907 CompoundAccessKind.UNRESOLVED_SUPER_SETTER, getter, setter); | 907 CompoundAccessKind.UNRESOLVED_SUPER_SETTER, getter, setter); |
908 } else { | 908 } else { |
909 return new StaticAccess.superMethod(getter); | 909 return new StaticAccess.superMethod(getter); |
910 } | 910 } |
911 } else if (setter.isFunction) { | 911 } else if (setter.isFunction) { |
912 assert(invariant(node, setter.name == '[]=', | 912 assert(invariant(node, setter.name == '[]=', |
913 message: "Unexpected super setter '$setter'.")); | 913 message: "Unexpected super setter '$setter'.")); |
914 assert(invariant(node, getter.name == '[]', | 914 assert(invariant(node, getter.name == '[]', |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
946 } | 946 } |
947 } | 947 } |
948 | 948 |
949 /// Compute the [AccessSemantics] corresponding to a static or toplevel access | 949 /// Compute the [AccessSemantics] corresponding to a static or toplevel access |
950 /// of [target]. | 950 /// of [target]. |
951 AccessSemantics computeStaticOrTopLevelAccessSemantics( | 951 AccessSemantics computeStaticOrTopLevelAccessSemantics( |
952 Spannable node, | 952 Spannable node, |
953 Element target) { | 953 Element target) { |
954 | 954 |
955 target = target.declaration; | 955 target = target.declaration; |
956 if (target.isErroneous) { | 956 if (target.isMalformed) { |
957 // This handles elements with parser errors. | 957 // This handles elements with parser errors. |
958 // TODO(johnniwinther): Elements with parse error should not set | |
959 // [isErroneous] to `true`. | |
960 return new StaticAccess.unresolved(target); | 958 return new StaticAccess.unresolved(target); |
961 } | 959 } |
962 if (target.isStatic) { | 960 if (target.isStatic) { |
963 if (target.isGetter) { | 961 if (target.isGetter) { |
964 return new StaticAccess.staticGetter(target); | 962 return new StaticAccess.staticGetter(target); |
965 } else if (target.isSetter) { | 963 } else if (target.isSetter) { |
966 return new StaticAccess.staticSetter(target); | 964 return new StaticAccess.staticSetter(target); |
967 } else if (target.isField) { | 965 } else if (target.isField) { |
968 if (target.isFinal || target.isConst) { | 966 if (target.isFinal || target.isConst) { |
969 return new StaticAccess.finalStaticField(target); | 967 return new StaticAccess.finalStaticField(target); |
(...skipping 1914 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2884 ? new StaticAccess.topLevelSetter(abstractField.setter) | 2882 ? new StaticAccess.topLevelSetter(abstractField.setter) |
2885 : new StaticAccess.staticSetter(abstractField.setter); | 2883 : new StaticAccess.staticSetter(abstractField.setter); |
2886 registry.registerStaticUse(abstractField.setter); | 2884 registry.registerStaticUse(abstractField.setter); |
2887 } | 2885 } |
2888 } else { | 2886 } else { |
2889 MemberElement member = element; | 2887 MemberElement member = element; |
2890 // TODO(johnniwinther): Needed to provoke a parsing and with it discovery | 2888 // TODO(johnniwinther): Needed to provoke a parsing and with it discovery |
2891 // of parse errors to make [element] erroneous. Fix this! | 2889 // of parse errors to make [element] erroneous. Fix this! |
2892 member.computeType(resolution); | 2890 member.computeType(resolution); |
2893 registry.registerStaticUse(member); | 2891 registry.registerStaticUse(member); |
2894 if (member.isErroneous) { | 2892 if (member.isMalformed) { |
2895 // [member] has parse errors. | 2893 // [member] has parse errors. |
2896 semantics = new StaticAccess.unresolved(member); | 2894 semantics = new StaticAccess.unresolved(member); |
2897 } else if (member.isFunction) { | 2895 } else if (member.isFunction) { |
2898 // `a = b`, `a++` or `a += b` where `a` is a function. | 2896 // `a = b`, `a++` or `a += b` where `a` is a function. |
2899 ErroneousElement error = reportAndCreateErroneousElement( | 2897 ErroneousElement error = reportAndCreateErroneousElement( |
2900 node.selector, name.text, | 2898 node.selector, name.text, |
2901 MessageKind.ASSIGNING_METHOD, const {}); | 2899 MessageKind.ASSIGNING_METHOD, const {}); |
2902 registry.registerThrowNoSuchMethod(); | 2900 registry.registerThrowNoSuchMethod(); |
2903 if (node.isComplex) { | 2901 if (node.isComplex) { |
2904 // `a++` or `a += b` where `a` is a function. | 2902 // `a++` or `a += b` where `a` is a function. |
(...skipping 22 matching lines...) Expand all Loading... |
2927 } | 2925 } |
2928 } | 2926 } |
2929 return handleUpdate(node, name, semantics); | 2927 return handleUpdate(node, name, semantics); |
2930 } | 2928 } |
2931 | 2929 |
2932 /// Handle access to resolved [element]. | 2930 /// Handle access to resolved [element]. |
2933 ResolutionResult handleResolvedSend(Send node, Name name, Element element) { | 2931 ResolutionResult handleResolvedSend(Send node, Name name, Element element) { |
2934 if (element.isAmbiguous) { | 2932 if (element.isAmbiguous) { |
2935 return handleAmbiguousSend(node, name, element); | 2933 return handleAmbiguousSend(node, name, element); |
2936 } | 2934 } |
2937 if (element.isErroneous) { | 2935 if (element.isMalformed) { |
2938 // This handles elements with parser errors. | 2936 // This handles elements with parser errors. |
2939 // TODO(johnniwinther): Elements with parse error should not set | |
2940 // [isErroneous] to `true`. | |
2941 assert(invariant(node, element is! ErroneousElement, | 2937 assert(invariant(node, element is! ErroneousElement, |
2942 message: "Unexpected erroneous element $element.")); | 2938 message: "Unexpected erroneous element $element.")); |
2943 return handleErroneousAccess(node, name, | 2939 return handleErroneousAccess(node, name, |
2944 new StaticAccess.unresolved(element)); | 2940 new StaticAccess.unresolved(element)); |
2945 } | 2941 } |
2946 if (element.isInstanceMember) { | 2942 if (element.isInstanceMember) { |
2947 if (inInstanceContext) { | 2943 if (inInstanceContext) { |
2948 // TODO(johnniwinther): Maybe use the found [element]. | 2944 // TODO(johnniwinther): Maybe use the found [element]. |
2949 return handleThisPropertyAccess(node, name); | 2945 return handleThisPropertyAccess(node, name); |
2950 } else { | 2946 } else { |
(...skipping 18 matching lines...) Expand all Loading... |
2969 } | 2965 } |
2970 return reporter.internalError(node, "Unexpected resolved send: $element"); | 2966 return reporter.internalError(node, "Unexpected resolved send: $element"); |
2971 } | 2967 } |
2972 | 2968 |
2973 /// Handle update to resolved [element]. | 2969 /// Handle update to resolved [element]. |
2974 ResolutionResult handleResolvedSendSet( | 2970 ResolutionResult handleResolvedSendSet( |
2975 SendSet node, Name name, Element element) { | 2971 SendSet node, Name name, Element element) { |
2976 if (element.isAmbiguous) { | 2972 if (element.isAmbiguous) { |
2977 return handleAmbiguousUpdate(node, name, element); | 2973 return handleAmbiguousUpdate(node, name, element); |
2978 } | 2974 } |
2979 if (element.isErroneous) { | 2975 if (element.isMalformed) { |
2980 // This handles elements with parser errors. | 2976 // This handles elements with parser errors.. |
2981 // TODO(johnniwinther): Elements with parse error should not set | |
2982 // [isErroneous] to `true`. | |
2983 assert(invariant(node, element is! ErroneousElement, | 2977 assert(invariant(node, element is! ErroneousElement, |
2984 message: "Unexpected erroneous element $element.")); | 2978 message: "Unexpected erroneous element $element.")); |
2985 return handleUpdate(node, name,new StaticAccess.unresolved(element)); | 2979 return handleUpdate(node, name,new StaticAccess.unresolved(element)); |
2986 } | 2980 } |
2987 if (element.isInstanceMember) { | 2981 if (element.isInstanceMember) { |
2988 if (inInstanceContext) { | 2982 if (inInstanceContext) { |
2989 return handleThisPropertyUpdate(node, name, element); | 2983 return handleThisPropertyUpdate(node, name, element); |
2990 } else { | 2984 } else { |
2991 return handleUpdate(node, name, reportStaticInstanceAccess(node, name)); | 2985 return handleUpdate(node, name, reportStaticInstanceAccess(node, name)); |
2992 } | 2986 } |
(...skipping 1689 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4682 } | 4676 } |
4683 return const NoneResult(); | 4677 return const NoneResult(); |
4684 } | 4678 } |
4685 } | 4679 } |
4686 | 4680 |
4687 /// Looks up [name] in [scope] and unwraps the result. | 4681 /// Looks up [name] in [scope] and unwraps the result. |
4688 Element lookupInScope(DiagnosticReporter reporter, Node node, | 4682 Element lookupInScope(DiagnosticReporter reporter, Node node, |
4689 Scope scope, String name) { | 4683 Scope scope, String name) { |
4690 return Elements.unwrap(scope.lookup(name), reporter, node); | 4684 return Elements.unwrap(scope.lookup(name), reporter, node); |
4691 } | 4685 } |
OLD | NEW |