diff --git a/base/docs/helpdb/Base.jl b/base/docs/helpdb/Base.jl index 52aceaba93d465..1ba3d3940d01af 100644 --- a/base/docs/helpdb/Base.jl +++ b/base/docs/helpdb/Base.jl @@ -218,14 +218,6 @@ Bessel function of the first kind of order `nu`, ``J_\\nu(x)``. """ besselj -""" - @code_lowered - -Evaluates the arguments to the function call, determines their types, and calls -[`code_lowered`](:func:`code_lowered`) on the resulting expression. -""" -:@code_lowered - """ //(num, den) @@ -723,14 +715,6 @@ keyword arguments `addprocs` was called with. """ launch -""" - @code_typed - -Evaluates the arguments to the function call, determines their types, and calls -[`code_typed`](:func:`code_typed`) on the resulting expression. -""" -:@code_typed - """ invdigamma(x) @@ -3507,13 +3491,6 @@ Returns the lower triangle of `M` starting from the `k`th superdiagonal. """ tril(M,k) -""" - @edit - -Evaluates the arguments to the function call, determines their types, and calls the `edit` -function on the resulting expression. -""" -:@edit """ subtypes(T::DataType) @@ -3628,14 +3605,6 @@ not representable. """ trunc -""" - @less - -Evaluates the arguments to the function call, determines their types, and calls the `less` -function on the resulting expression. -""" -:@less - """ broadcast_function(f) @@ -5583,14 +5552,6 @@ Returns `string` with the first character converted to lowercase. """ lcfirst -""" - @code_native - -Evaluates the arguments to the function call, determines their types, and calls -[`code_native`](:func:`code_native`) on the resulting expression. -""" -:@code_native - """ flipbits!(B::BitArray{N}) -> BitArray{N} @@ -5605,14 +5566,6 @@ Returns the value of a symbolic link `path`. """ readlink -""" - @code_warntype - -Evaluates the arguments to the function call, determines their types, and calls -[`code_warntype`](:func:`code_warntype`) on the resulting expression. -""" -:@code_warntype - """ deg2rad(x) @@ -8299,16 +8252,6 @@ Converts a packed boolean array to an array of booleans. """ bitunpack -""" - @which - -Applied to a function call, it evaluates the arguments to the specified function call, and -returns the `Method` object for the method that would be called for those arguments. Applied -to a variable, it returns the module in which the variable was bound. It calls out to the -`which` function. -""" -:@which - """ size(A, [dim...]) @@ -8496,14 +8439,6 @@ address will be either IPv4 or IPv6 as appropriate. """ recvfrom -""" - @code_llvm - -Evaluates the arguments to the function call, determines their types, and calls -[`code_llvm`](:func:`code_llvm`) on the resulting expression. -""" -:@code_llvm - """ nextfloat(f) diff --git a/base/exports.jl b/base/exports.jl index 2b7e3349b84524..1c52e855a9939e 100644 --- a/base/exports.jl +++ b/base/exports.jl @@ -1385,6 +1385,7 @@ export # reflection @which, @edit, + @functionloc, @less, @code_typed, @code_warntype, diff --git a/base/interactiveutil.jl b/base/interactiveutil.jl index 9dcc89e07aef60..e0fad17f865163 100644 --- a/base/interactiveutil.jl +++ b/base/interactiveutil.jl @@ -254,8 +254,12 @@ 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 isa(ex0, Expr) && ex0.head == :macrocall # Make @edit @time 1+2 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 +282,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 +290,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, :functionloc, :code_typed, :code_warntype, :code_lowered, :code_llvm, :code_llvm_raw, :code_native] @eval begin macro ($fname)(ex0) @@ -295,7 +299,80 @@ for fname in [:which, :less, :edit, :code_typed, :code_warntype, end end -# `methodswith` -- shows a list of methods using the type given +""" + @which + +Applied to a function or macro call, it evaluates the arguments to the specified call, and +returns the `Method` object for the method that would be called for those arguments. Applied +to a variable, it returns the module in which the variable was bound. It calls out to the +`which` function. +""" +:@which + +""" + @less + +Evaluates the arguments to the function or macro call, determines their types, and calls the `less` +function on the resulting expression. +""" +:@less + +""" + @edit + +Evaluates the arguments to the function or macro call, determines their types, and calls the `edit` +function on the resulting expression. +""" +:@edit + +""" + @functionloc + +Applied to a function or macro call, it evaluates the arguments to the specified call, and +returns a tuple `(filename,line)` giving the location for the method that would be called for those arguments. +It calls out to the `functionloc` function. +""" +:@functionloc + +""" + @code_typed + +Evaluates the arguments to the function or macro call, determines their types, and calls +[`code_typed`](:func:`code_typed`) on the resulting expression. +""" +:@code_typed + +""" + @code_warntype + +Evaluates the arguments to the function or macro call, determines their types, and calls +[`code_warntype`](:func:`code_warntype`) on the resulting expression. +""" +:@code_warntype + +""" + @code_lowered + +Evaluates the arguments to the function or macro call, determines their types, and calls +[`code_lowered`](:func:`code_lowered`) on the resulting expression. +""" +:@code_lowered + +""" + @code_llvm + +Evaluates the arguments to the function or macro call, determines their types, and calls +[`code_llvm`](:func:`code_llvm`) on the resulting expression. +""" +:@code_llvm + +""" + @code_native + +Evaluates the arguments to the function or macro call, determines their types, and calls +[`code_native`](:func:`code_native`) on the resulting expression. +""" +:@code_native function type_close_enough(x::ANY, t::ANY) x == t && return true @@ -304,6 +381,7 @@ function type_close_enough(x::ANY, t::ANY) (isa(x,Union) && isa(t,DataType) && any(u -> is(u,t), x.types)) end +# `methodswith` -- shows a list of methods using the type given function methodswith(t::Type, f::Function, showparents::Bool=false, meths = Method[]) mt = typeof(f).name.mt d = mt.defs diff --git a/doc/stdlib/base.rst b/doc/stdlib/base.rst index afcc79fe741248..1418c7f802dc5a 100644 --- a/doc/stdlib/base.rst +++ b/doc/stdlib/base.rst @@ -80,7 +80,7 @@ Getting Around .. Docstring generated from Julia source - Evaluates the arguments to the function call, determines their types, and calls the ``edit`` function on the resulting expression. + Evaluates the arguments to the function or macro call, determines their types, and calls the ``edit`` function on the resulting expression. .. function:: less(file::AbstractString, [line]) @@ -98,7 +98,7 @@ Getting Around .. Docstring generated from Julia source - Evaluates the arguments to the function call, determines their types, and calls the ``less`` function on the resulting expression. + Evaluates the arguments to the function or macro call, determines their types, and calls the ``less`` function on the resulting expression. .. function:: clipboard(x) @@ -188,7 +188,7 @@ Getting Around .. Docstring generated from Julia source - Applied to a function call, it evaluates the arguments to the specified function call, and returns the ``Method`` object for the method that would be called for those arguments. Applied to a variable, it returns the module in which the variable was bound. It calls out to the ``which`` function. + Applied to a function or macro call, it evaluates the arguments to the specified call, and returns the ``Method`` object for the method that would be called for those arguments. Applied to a variable, it returns the module in which the variable was bound. It calls out to the ``which`` function. .. function:: methods(f, [types]) @@ -1314,6 +1314,12 @@ Reflection Returns a tuple ``(filename,line)`` giving the location of a ``Method`` definition. +.. function:: @functionloc + + .. Docstring generated from Julia source + + Applied to a function or macro call, it evaluates the arguments to the specified call, and returns a tuple ``(filename,line)`` giving the location for the method that would be called for those arguments. It calls out to the ``functionloc`` function. + Internals --------- @@ -1351,7 +1357,7 @@ Internals .. Docstring generated from Julia source - Evaluates the arguments to the function call, determines their types, and calls :func:`code_lowered` on the resulting expression. + Evaluates the arguments to the function or macro call, determines their types, and calls :func:`code_lowered` on the resulting expression. .. function:: code_typed(f, types; optimize=true) @@ -1363,7 +1369,7 @@ Internals .. Docstring generated from Julia source - Evaluates the arguments to the function call, determines their types, and calls :func:`code_typed` on the resulting expression. + Evaluates the arguments to the function or macro call, determines their types, and calls :func:`code_typed` on the resulting expression. .. function:: code_warntype(f, types) @@ -1375,7 +1381,7 @@ Internals .. Docstring generated from Julia source - Evaluates the arguments to the function call, determines their types, and calls :func:`code_warntype` on the resulting expression. + Evaluates the arguments to the function or macro call, determines their types, and calls :func:`code_warntype` on the resulting expression. .. function:: code_llvm(f, types) @@ -1389,7 +1395,7 @@ Internals .. Docstring generated from Julia source - Evaluates the arguments to the function call, determines their types, and calls :func:`code_llvm` on the resulting expression. + Evaluates the arguments to the function or macro call, determines their types, and calls :func:`code_llvm` on the resulting expression. .. function:: code_native(f, types) @@ -1401,7 +1407,7 @@ Internals .. Docstring generated from Julia source - Evaluates the arguments to the function call, determines their types, and calls :func:`code_native` on the resulting expression. + Evaluates the arguments to the function or macro call, determines their types, and calls :func:`code_native` on the resulting expression. .. function:: precompile(f,args::Tuple{Vararg{Any}}) diff --git a/test/reflection.jl b/test/reflection.jl index 969050dfedfd87..f02ef6453470b5 100644 --- a/test/reflection.jl +++ b/test/reflection.jl @@ -237,3 +237,22 @@ 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 #This is here because of #15280 +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, Int})[1]==@which MacroTest.@macrotest 1 1 + @test functionloc(@which @macrotest 1 1) == @functionloc @macrotest 1 1 +end