public void Scenario_RubyArgSplatting5() {
var c = Context.GetClass(typeof(MethodsWithParamArrays));
Runtime.Globals.SetVariable("C", new MethodsWithParamArrays());
// The post-param-array arguments might decide which overload to call:
c.SetMethodNoEvent(Context, "bar", new RubyMethodGroupInfo(new[] {
CreateParamsArrayMethod("B0", new[] { typeof(int), typeof(int), typeof(int[]), typeof(bool) }, 2, 0),
CreateParamsArrayMethod("B1", new[] { typeof(int), typeof(int[]), typeof(int), typeof(int) }, 1, 1),
}, c, true));
AssertOutput(delegate() {
CompilerTest(@"
x = C.bar(*[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,true])
p x.key, x.value
x = C.bar(*[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15])
p x.key, x.value
");
}, @"
0
[2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]
1
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]
");
// Huge splattees.
AssertOutput(delegate() {
CompilerTest(@"
[
[1],
[1] * 2,
[1] * 3,
[1] * 4,
[1] * 5,
[1] * 10003 + [true],
[1] * 10003,
].each do |s|
begin
x = C.bar(*s)
puts ""B#{x.key} -> #{x.value.length}""
rescue
p $!
end
end
");
}, @"
#<ArgumentError: wrong number of arguments (1 for 3)>
#<ArgumentError: wrong number of arguments (2 for 3)>
B1 -> 0
B1 -> 1
B1 -> 2
B0 -> 10001
B1 -> 10000
");
// Overloads might differ only in the element types of params-array.
// If binder decision is not based upon all splatted item types
c.SetMethodNoEvent(Context, "baz", new RubyMethodGroupInfo(new[] {
CreateParamsArrayMethod("Z0", new[] { typeof(int), typeof(object[]) }, 1, 0),
CreateParamsArrayMethod("Z1", new[] { typeof(int), typeof(MutableString[]) }, 1, 1),
CreateParamsArrayMethod("Z2", new[] { typeof(int), typeof(int[]) }, 1, 2),
}, c, true));
AssertOutput(delegate() {
CompilerTest(@"
[
[1] * 20 + ['x'] + [1] * 20,
[1] * 10001,
[1] * 10000 + [true],
[1] + ['x'] * 10000,
].each do |s|
x = C.baz(*s)
puts ""Z#{x.key} -> #{x.value.length}""
end
");
}, @"
Z0 -> 40
Z2 -> 10000
Z0 -> 10000
Z1 -> 10000
");
// Tests error handling and caching.
c.SetMethodNoEvent(Context, "error", new RubyMethodGroupInfo(new[] {
CreateParamsArrayMethod("E1", new[] { typeof(int), typeof(MutableString[]) }, 1, 1),
CreateParamsArrayMethod("E2", new[] { typeof(int), typeof(int[]) }, 1, 2),
}, c, true));
AssertOutput(delegate() {
CompilerTest(@"
[
[1] + [2] * 10000,
[1] * 20 + ['zzz'] + [1] * 20,
[1] + ['x'] * 10000,
].each do |s|
begin
x = C.error(*s)
puts ""Z#{x.key} -> #{x.value.length}""
rescue
p $!
end
end
");
}, @"
Z2 -> 10000
#<TypeError: can't convert String into Fixnum>
Z1 -> 10000
");
// TODO: test GetPreferredParameters with collapsed arguments
}