diff --git a/base/interactiveutil.jl b/base/interactiveutil.jl index 9dcc89e07aef60..9d55e77d8125e3 100644 --- a/base/interactiveutil.jl +++ b/base/interactiveutil.jl @@ -254,8 +254,13 @@ function gen_call_with_extracted_types(fcn, ex0) Expr(:call, typesof, map(esc, args[2:end])...)) end exret = Expr(:none) + is_macro = false ex = expand(ex0) - if !isa(ex, Expr) + if fcn in [:which, :less, :edit, :methods, :functionloc] && ex0.head == :macrocall + # special case @edit @time 1+2 to edit the macro + is_macro = true + exret = Expr(:call, fcn, esc(ex0.args[1]), typesof(ex0.args[2:end]...)) + elseif !isa(ex, Expr) exret = Expr(:call, :error, "expression is not a function call or symbol") elseif ex.head == :call if any(e->(isa(e, Expr) && e.head==:(...)), ex0.args) && @@ -278,7 +283,7 @@ function gen_call_with_extracted_types(fcn, ex0) end end end - if ex.head == :thunk || exret.head == :none + if (!is_macro && ex.head == :thunk) || exret.head == :none exret = Expr(:call, :error, "expression is not a function call, " * "or is too complex for @$fcn to analyze; " * "break it down to simpler parts if possible") @@ -286,7 +291,7 @@ function gen_call_with_extracted_types(fcn, ex0) exret end -for fname in [:which, :less, :edit, :code_typed, :code_warntype, +for fname in [:which, :less, :edit, :methods, :functionloc, :code_typed, :code_warntype, :code_lowered, :code_llvm, :code_llvm_raw, :code_native] @eval begin macro ($fname)(ex0) diff --git a/test/reflection.jl b/test/reflection.jl index 969050dfedfd87..edf35faf49c862 100644 --- a/test/reflection.jl +++ b/test/reflection.jl @@ -237,3 +237,26 @@ let rts = return_types(TLayout) @test length(rts) >= 3 # general constructor, specific constructor, and call-to-convert adapter(s) @test all(rts .== TLayout) end + +module MacroTest +export @macrotest +macro macrotest(x::Int, y::Symbol) end +macro macrotest(x::Int, y::Int) + nothing +end +end + +let + using MacroTest + a = 1 + m = getfield(current_module(), Symbol("@macrotest")) + @test which(m, Tuple{Int,Symbol})==@which @macrotest 1 a + @test which(m, Tuple{Int,Int})==@which @macrotest 1 1 + @test methods(m, Tuple{Int,Symbol})==@methods @macrotest 1 a + @test methods(m, Tuple{Int,Int})==@methods @macrotest 1 1 + + @test methods(m,Tuple{Int, Int})[1]==@which MacroTest.@macrotest 1 1 + @test functionloc(@which @macrotest 1 1)[1] == @functionloc @macrotest 1 1 + #Uncomment when #15280 is solved + #@test basename(functionloc(@which @macrotest 1 a)[1]) == "reflection.jl" +end