Skip to content

Commit

Permalink
Fix JuliaLang#3377. It allows for writing @methods @time 1+1, `@fun…
Browse files Browse the repository at this point in the history
…ctionloc @time

1+1` plus the equivalent for `@which`, `@edit` and `@less`. The macros check for method specialization of the macro and return the dispatched macro. The `@functionloc` macro is exported and the documentation is updated.
  • Loading branch information
dhoegh committed Mar 6, 2016
1 parent 8a7eac2 commit 305c25a
Show file tree
Hide file tree
Showing 5 changed files with 116 additions and 77 deletions.
65 changes: 0 additions & 65 deletions base/docs/helpdb/Base.jl
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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}
Expand All @@ -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)
Expand Down Expand Up @@ -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...])
Expand Down Expand Up @@ -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)
Expand Down
1 change: 1 addition & 0 deletions base/exports.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1385,6 +1385,7 @@ export
# reflection
@which,
@edit,
@functionloc,
@less,
@code_typed,
@code_warntype,
Expand Down
86 changes: 82 additions & 4 deletions base/interactiveutil.jl
Original file line number Diff line number Diff line change
Expand Up @@ -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) &&
Expand All @@ -278,15 +282,15 @@ 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")
end
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)
Expand All @@ -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
return 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
Expand All @@ -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
Expand Down
22 changes: 14 additions & 8 deletions doc/stdlib/base.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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])

Expand All @@ -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)

Expand Down Expand Up @@ -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])

Expand Down Expand Up @@ -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 return 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
---------

Expand Down Expand Up @@ -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)

Expand All @@ -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)

Expand All @@ -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)

Expand All @@ -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)

Expand All @@ -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}})

Expand Down
19 changes: 19 additions & 0 deletions test/reflection.jl
Original file line number Diff line number Diff line change
Expand Up @@ -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

0 comments on commit 305c25a

Please sign in to comment.