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