This is just syntactic sugar for a function taking an array as an argument:
public void printf(String format, Object[] args) {
// ...
}
and then constructing the appropriate array at the call site.
How can we support it?
We'll need to make changes in a few places.
Type checking
Internally, Java reports the println function above as taking exactly two arguments: a String and an Object array. But there is also a Method.isVarArgs function that tells us that argsactually means a list of arguments instead of just an array.
In type inference, we need to separate varargs methods from non-varargs methods and consider the non-varargs methods first. If none of those match, we then consider the varargs methods. In the varargs case, we look for a method whose last parameter is an array and check that all the varargs parameters are subtypes of the element type of that array.
For example, if we have the Flix code
System.in.printf("hello", "test", "blah")
Then we:
Consider all non-varargs methods matching printf (there are none)
Consider all varargs methods matching printf:
printf(Locale l, String format, Object... args) does not fit due to the first parameter Locale
printf(String format, Object... args) does fit: test and blah are both Strings which are subtypes of Object
Code gen
We still need to desugar the varargs into Arrays. We can do this in code generation: Add a new array literal construction for the varargs at the call site.
What is "VarArgs?"
Java supports "variable arity" methods (also called varargs). These allow one to write a function like
and then call it with a variable number of arguments:
This is just syntactic sugar for a function taking an array as an argument:
and then constructing the appropriate array at the call site.
How can we support it?
We'll need to make changes in a few places.
Type checking
Internally, Java reports the
println
function above as taking exactly two arguments: a String and an Object array. But there is also aMethod.isVarArgs
function that tells us thatargs
actually means a list of arguments instead of just an array.In type inference, we need to separate varargs methods from non-varargs methods and consider the non-varargs methods first. If none of those match, we then consider the varargs methods. In the varargs case, we look for a method whose last parameter is an array and check that all the varargs parameters are subtypes of the element type of that array.
For example, if we have the Flix code
Then we:
printf
(there are none)printf
:printf(Locale l, String format, Object... args)
does not fit due to the first parameterLocale
printf(String format, Object... args)
does fit:test
andblah
are bothString
s which are subtypes ofObject
Code gen
We still need to desugar the varargs into Arrays. We can do this in code generation: Add a new array literal construction for the varargs at the call site.