OLD | NEW |
1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2011, 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 /** A formal parameter to a [Method]. */ | 5 /** A formal parameter to a [Method]. */ |
6 class Parameter { | 6 class Parameter { |
7 FormalNode definition; | 7 FormalNode definition; |
8 Member method; | 8 Member method; |
9 | 9 |
10 String name; | 10 String name; |
(...skipping 820 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
831 if (arg != null && arg.needsConversion(parameters[i].type)) { | 831 if (arg != null && arg.needsConversion(parameters[i].type)) { |
832 return true; | 832 return true; |
833 } | 833 } |
834 } | 834 } |
835 } | 835 } |
836 | 836 |
837 return false; | 837 return false; |
838 } | 838 } |
839 | 839 |
840 static String _argCountMsg(int actual, int expected, [bool atLeast=false]) { | 840 static String _argCountMsg(int actual, int expected, [bool atLeast=false]) { |
841 // TODO(jimhug): better messages with default named args. | 841 return 'wrong number of positional arguments, expected ' + |
842 return 'wrong number of arguments, expected ' + | |
843 '${atLeast ? "at least " : ""}$expected but found $actual'; | 842 '${atLeast ? "at least " : ""}$expected but found $actual'; |
844 } | 843 } |
845 | 844 |
846 Value _argError(MethodGenerator context, Node node, Value target, | 845 Value _argError(MethodGenerator context, Node node, Value target, |
847 Arguments args, String msg) { | 846 Arguments args, String msg, SourceSpan span) { |
848 if (isStatic || isConstructor) { | 847 if (isStatic || isConstructor) { |
849 world.error(msg, node.span); | 848 world.error(msg, span); |
850 } else { | 849 } else { |
851 world.warning(msg, node.span); | 850 world.warning(msg, span); |
852 } | 851 } |
853 return target.invokeNoSuchMethod(context, name, node, args); | 852 return target.invokeNoSuchMethod(context, name, node, args); |
854 } | 853 } |
855 | 854 |
856 genParameterValues() { | 855 genParameterValues() { |
857 // Pure lazy? | 856 // Pure lazy? |
858 for (var p in parameters) p.genValue(this, generator); | 857 for (var p in parameters) p.genValue(this, generator); |
859 } | 858 } |
860 | 859 |
861 /** | 860 /** |
(...skipping 28 matching lines...) Expand all Loading... |
890 | 889 |
891 var argsCode = []; | 890 var argsCode = []; |
892 if (!target.isType && (isConstructor || target.isSuper)) { | 891 if (!target.isType && (isConstructor || target.isSuper)) { |
893 argsCode.add('this'); | 892 argsCode.add('this'); |
894 } | 893 } |
895 | 894 |
896 int bareCount = args.bareCount; | 895 int bareCount = args.bareCount; |
897 for (int i = 0; i < bareCount; i++) { | 896 for (int i = 0; i < bareCount; i++) { |
898 var arg = args.values[i]; | 897 var arg = args.values[i]; |
899 if (i >= parameters.length) { | 898 if (i >= parameters.length) { |
900 // TODO(jimhug): better error location | |
901 var msg = _argCountMsg(args.length, parameters.length); | 899 var msg = _argCountMsg(args.length, parameters.length); |
902 return _argError(context, node, target, args, msg); | 900 return _argError(context, node, target, args, msg, args.nodes[i].span); |
903 } | 901 } |
904 arg = arg.convertTo(context, parameters[i].type, node, isDynamic); | 902 arg = arg.convertTo(context, parameters[i].type, node, isDynamic); |
905 if (isConst && arg.isConst) { | 903 if (isConst && arg.isConst) { |
906 argsCode.add(arg.canonicalCode); | 904 argsCode.add(arg.canonicalCode); |
907 } else { | 905 } else { |
908 argsCode.add(arg.code); | 906 argsCode.add(arg.code); |
909 } | 907 } |
910 } | 908 } |
911 | 909 |
| 910 int namedArgsUsed = 0; |
912 if (bareCount < parameters.length) { | 911 if (bareCount < parameters.length) { |
913 genParameterValues(); | 912 genParameterValues(); |
914 | 913 |
915 int namedArgsUsed = 0; | |
916 for (int i = bareCount; i < parameters.length; i++) { | 914 for (int i = bareCount; i < parameters.length; i++) { |
917 var arg = args.getValue(parameters[i].name); | 915 var arg = args.getValue(parameters[i].name); |
918 if (arg == null) { | 916 if (arg == null) { |
919 arg = parameters[i].value; | 917 arg = parameters[i].value; |
920 } else { | 918 } else { |
921 arg = arg.convertTo(context, parameters[i].type, node, isDynamic); | 919 arg = arg.convertTo(context, parameters[i].type, node, isDynamic); |
922 namedArgsUsed++; | 920 namedArgsUsed++; |
923 } | 921 } |
924 | 922 |
925 if (arg == null || !parameters[i].isOptional) { | 923 if (arg == null || !parameters[i].isOptional) { |
926 // TODO(jimhug): better error location | |
927 var msg = _argCountMsg(Math.min(i, args.length), i + 1, atLeast:true); | 924 var msg = _argCountMsg(Math.min(i, args.length), i + 1, atLeast:true); |
928 return _argError(context, node, target, args, msg); | 925 return _argError(context, node, target, args, msg, |
| 926 args.nodes[i].span); |
929 } else { | 927 } else { |
930 argsCode.add(isConst && arg.isConst | 928 argsCode.add(isConst && arg.isConst |
931 ? arg.canonicalCode : arg.code); | 929 ? arg.canonicalCode : arg.code); |
932 } | 930 } |
933 } | 931 } |
934 | |
935 if (namedArgsUsed < args.nameCount) { | |
936 // TODO(jmesserly): better error location | |
937 // Find the unused argument name | |
938 var seen = new Set<String>(); | |
939 for (int i = bareCount; i < args.length; i++) { | |
940 var name = args.getName(i); | |
941 if (seen.contains(name)) { | |
942 return _argError(context, node, target, args, | |
943 'duplicate argument "$name"'); | |
944 } | |
945 seen.add(name); | |
946 int p = indexOfParameter(name); | |
947 if (p < 0) { | |
948 return _argError(context, node, target, args, | |
949 'method does not have optional parameter "$name"'); | |
950 } else if (p < bareCount) { | |
951 return _argError(context, node, target, args, | |
952 'argument "$name" passed as positional and named'); | |
953 } | |
954 } | |
955 world.internalError('wrong named arguments calling $name', node.span); | |
956 } | |
957 | |
958 Arguments.removeTrailingNulls(argsCode); | 932 Arguments.removeTrailingNulls(argsCode); |
959 } | 933 } |
960 | 934 |
| 935 if (namedArgsUsed < args.nameCount) { |
| 936 // Find the unused argument name |
| 937 var seen = new Set<String>(); |
| 938 for (int i = bareCount; i < args.length; i++) { |
| 939 var name = args.getName(i); |
| 940 if (seen.contains(name)) { |
| 941 return _argError(context, node, target, args, |
| 942 'duplicate argument "$name"', args.nodes[i].span); |
| 943 } |
| 944 seen.add(name); |
| 945 int p = indexOfParameter(name); |
| 946 if (p < 0) { |
| 947 return _argError(context, node, target, args, |
| 948 'method does not have optional parameter "$name"', |
| 949 args.nodes[i].span); |
| 950 } else if (p < bareCount) { |
| 951 return _argError(context, node, target, args, |
| 952 'argument "$name" passed as positional and named', |
| 953 // Given that the named was mentioned explicitly, highlight the |
| 954 // positional location instead: |
| 955 args.nodes[p].span); |
| 956 } |
| 957 } |
| 958 world.internalError('wrong named arguments calling $name', node.span); |
| 959 } |
| 960 |
961 var argsString = Strings.join(argsCode, ', '); | 961 var argsString = Strings.join(argsCode, ', '); |
962 | 962 |
963 if (isConstructor) { | 963 if (isConstructor) { |
964 return _invokeConstructor(context, node, target, args, argsString); | 964 return _invokeConstructor(context, node, target, args, argsString); |
965 } | 965 } |
966 | 966 |
967 if (target.isSuper) { | 967 if (target.isSuper) { |
968 return new Value(inferredResult, | 968 return new Value(inferredResult, |
969 '${declaringType.jsname}.prototype.$jsname.call($argsString)', | 969 '${declaringType.jsname}.prototype.$jsname.call($argsString)', |
970 node.span); | 970 node.span); |
(...skipping 776 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1747 } | 1747 } |
1748 | 1748 |
1749 void forEach(void f(Member member)) { | 1749 void forEach(void f(Member member)) { |
1750 factories.forEach((_, Map constructors) { | 1750 factories.forEach((_, Map constructors) { |
1751 constructors.forEach((_, Member member) { | 1751 constructors.forEach((_, Member member) { |
1752 f(member); | 1752 f(member); |
1753 }); | 1753 }); |
1754 }); | 1754 }); |
1755 } | 1755 } |
1756 } | 1756 } |
OLD | NEW |