468 |
468 |
469 if (formals.head != varargsFormal) |
469 if (formals.head != varargsFormal) |
470 throw inapplicableMethodException.setMessage("arg.length.mismatch"); // not enough args |
470 throw inapplicableMethodException.setMessage("arg.length.mismatch"); // not enough args |
471 |
471 |
472 if (useVarargs) { |
472 if (useVarargs) { |
473 Type elt = types.elemtype(varargsFormal); |
473 //note: if applicability check is triggered by most specific test, |
|
474 //the last argument of a varargs is _not_ an array type (see JLS 15.12.2.5) |
|
475 Type elt = types.elemtypeOrType(varargsFormal); |
474 while (argtypes.nonEmpty()) { |
476 while (argtypes.nonEmpty()) { |
475 if (!types.isConvertible(argtypes.head, elt, warn)) |
477 if (!types.isConvertible(argtypes.head, elt, warn)) |
476 throw inapplicableMethodException.setMessage("varargs.argument.mismatch", |
478 throw inapplicableMethodException.setMessage("varargs.argument.mismatch", |
477 argtypes.head, |
479 argtypes.head, |
478 elt); |
480 elt); |
825 //where |
827 //where |
826 private Symbol adjustVarargs(Symbol to, Symbol from, boolean useVarargs) { |
828 private Symbol adjustVarargs(Symbol to, Symbol from, boolean useVarargs) { |
827 List<Type> fromArgs = from.type.getParameterTypes(); |
829 List<Type> fromArgs = from.type.getParameterTypes(); |
828 List<Type> toArgs = to.type.getParameterTypes(); |
830 List<Type> toArgs = to.type.getParameterTypes(); |
829 if (useVarargs && |
831 if (useVarargs && |
830 toArgs.length() < fromArgs.length() && |
|
831 (from.flags() & VARARGS) != 0 && |
832 (from.flags() & VARARGS) != 0 && |
832 (to.flags() & VARARGS) != 0) { |
833 (to.flags() & VARARGS) != 0) { |
833 //if we are checking a varargs method 'from' against another varargs |
|
834 //method 'to' (where arity of 'to' < arity of 'from') then expand signature |
|
835 //of 'to' to 'fit' arity of 'from' (this means adding fake formals to 'to' |
|
836 //until 'to' signature has the same arity as 'from') |
|
837 ListBuffer<Type> args = ListBuffer.lb(); |
|
838 Type varargsTypeFrom = fromArgs.last(); |
834 Type varargsTypeFrom = fromArgs.last(); |
839 Type varargsTypeTo = toArgs.last(); |
835 Type varargsTypeTo = toArgs.last(); |
840 while (fromArgs.head != varargsTypeFrom) { |
836 ListBuffer<Type> args = ListBuffer.lb(); |
841 args.append(toArgs.head == varargsTypeTo ? types.elemtype(varargsTypeTo) : toArgs.head); |
837 if (toArgs.length() < fromArgs.length()) { |
842 fromArgs = fromArgs.tail; |
838 //if we are checking a varargs method 'from' against another varargs |
843 toArgs = toArgs.head == varargsTypeTo ? |
839 //method 'to' (where arity of 'to' < arity of 'from') then expand signature |
844 toArgs : |
840 //of 'to' to 'fit' arity of 'from' (this means adding fake formals to 'to' |
845 toArgs.tail; |
841 //until 'to' signature has the same arity as 'from') |
846 } |
842 while (fromArgs.head != varargsTypeFrom) { |
847 args.append(varargsTypeTo); |
843 args.append(toArgs.head == varargsTypeTo ? types.elemtype(varargsTypeTo) : toArgs.head); |
|
844 fromArgs = fromArgs.tail; |
|
845 toArgs = toArgs.head == varargsTypeTo ? |
|
846 toArgs : |
|
847 toArgs.tail; |
|
848 } |
|
849 } else { |
|
850 //formal argument list is same as original list where last |
|
851 //argument (array type) is removed |
|
852 args.appendList(toArgs.reverse().tail.reverse()); |
|
853 } |
|
854 //append varargs element type as last synthetic formal |
|
855 args.append(types.elemtype(varargsTypeTo)); |
848 MethodSymbol msym = new MethodSymbol(to.flags_field, |
856 MethodSymbol msym = new MethodSymbol(to.flags_field, |
849 to.name, |
857 to.name, |
850 (Type)to.type.clone(), //see: 6990136 |
858 (Type)to.type.clone(), //see: 6990136 |
851 to.owner); |
859 to.owner); |
852 MethodType mtype = msym.type.asMethodType(); |
860 MethodType mtype = msym.type.asMethodType(); |