diff --git a/src/macro_tools.jl b/src/macro_tools.jl index 0ef2acb8..b89000e1 100644 --- a/src/macro_tools.jl +++ b/src/macro_tools.jl @@ -75,23 +75,25 @@ function process_args(exprs) end primary_index = length(args) รท 2 + 2 i = 3 - while args[i] === :_ && i <= lastindex(args) + while i <= lastindex(args) && args[i] === :_ args[i] = nothing i += 1 end - if i == primary_index && args[i] isa Expr && args[i].head === :tuple - map!(create_first_function, args[i].args, args[i].args) - else - args[i] = create_first_function(args[i]) - end - i += 1 - while i <= lastindex(args) + if i <= lastindex(args) if i == primary_index && args[i] isa Expr && args[i].head === :tuple - map!(create_function, args[i].args, args[i].args) + map!(create_first_function, args[i].args, args[i].args) else - args[i] = create_function(args[i]) + args[i] = create_first_function(args[i]) end i += 1 + while i <= lastindex(args) + if i == primary_index && args[i] isa Expr && args[i].head === :tuple + map!(create_function, args[i].args, args[i].args) + else + args[i] = create_function(args[i]) + end + i += 1 + end end call = exprarray(:call, args) esc(isempty(interpolations) ? call : Expr(:let, exprarray(:block, interpolations), Expr(:block, call))) diff --git a/test/runtests.jl b/test/runtests.jl index 766e933c..0b818ae0 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -73,6 +73,14 @@ else @test Chairmarks.only(b.samples).evals == 1 end + @testset "process_args" begin + @test Chairmarks.process_args(()) == esc(:($(Chairmarks.benchmark)(;))) + @test Chairmarks.process_args((:(k=v),)) == esc(:($(Chairmarks.benchmark)(; k=v))) + @test Chairmarks.process_args((:(k=v), :(k=v2))) == esc(:($(Chairmarks.benchmark)(; k=v, k=v2))) + @test Chairmarks.process_args((:f,:(k=v))) == esc(:($(Chairmarks.benchmark)(f; k=v))) + @test_throws ErrorException("Positional argument after keyword argument") Chairmarks.process_args((:(k=v),:f)) + end + @testset "errors" begin @test_throws UndefKeywordError Sample(allocs=1.5, bytes=1729) # needs `time` @@ -89,6 +97,14 @@ else t = @test_throws LoadError @eval(@b seconds=1 1+1) @test t.value.error == ErrorException("Positional argument after keyword argument") + + #149 + t = @test_throws MethodError @b # no arguments + @test t.value.f === Chairmarks.benchmark + @test t.value.args === () + + t = @test_throws ErrorException @eval(@b seconds=1 seconds=2) + @test startswith(t.value.msg, "syntax: keyword argument \"seconds\" repeated in call to \"") end @testset "time_ns() close to typemax(UInt64)" begin