Skip to content

Commit

Permalink
pass __file__ and __line__ as arguments to all macros
Browse files Browse the repository at this point in the history
  • Loading branch information
ihnorton authored and vtjnash committed May 8, 2017
1 parent 2496b4e commit 10afb8f
Show file tree
Hide file tree
Showing 24 changed files with 218 additions and 150 deletions.
12 changes: 7 additions & 5 deletions base/docs/Docs.jl
Original file line number Diff line number Diff line change
Expand Up @@ -83,9 +83,11 @@ function initmeta(m::Module = current_module())
end

function signature!(tv, expr::Expr)
if isexpr(expr, [:call, :macrocall])
is_macrocall = isexpr(expr, :macrocall)
if is_macrocall || isexpr(expr, :call)
sig = :(Union{Tuple{}})
for arg in expr.args[2:end]
first_arg = is_macrocall ? 3 : 2 # skip function arguments
for arg in expr.args[first_arg:end]
isexpr(arg, :parameters) && continue
if isexpr(arg, :kw) # optional arg
push!(sig.args, :(Tuple{$(sig.args[end].args[2:end]...)}))
Expand Down Expand Up @@ -592,7 +594,7 @@ function __doc__!(meta, def, define)
# the Base image). We just need to convert each `@__doc__` marker to an `@doc`.
finddoc(def) do each
each.head = :macrocall
each.args = [Symbol("@doc"), meta, each.args[end], define]
each.args = [Symbol("@doc"), nothing, meta, each.args[end], define] # TODO: forward line number info
end
else
# `def` has already been defined during Base image gen so we just need to find and
Expand Down Expand Up @@ -635,7 +637,7 @@ const BINDING_HEADS = [:typealias, :const, :global, :(=)] # deprecation: remove
isquotedmacrocall(x) =
isexpr(x, :copyast, 1) &&
isa(x.args[1], QuoteNode) &&
isexpr(x.args[1].value, :macrocall, 1)
isexpr(x.args[1].value, :macrocall, 2)
# Simple expressions / atoms the may be documented.
isbasicdoc(x) = isexpr(x, :.) || isa(x, Union{QuoteNode, Symbol})
is_signature(x) = isexpr(x, :call) || (isexpr(x, :(::), 2) && isexpr(x.args[1], :call)) || isexpr(x, :where)
Expand Down Expand Up @@ -723,7 +725,7 @@ function docm(ex)
parsedoc(keywords[ex])
elseif isa(ex, Union{Expr, Symbol})
binding = esc(bindingexpr(namify(ex)))
if isexpr(ex, [:call, :macrocall])
if isexpr(ex, :call) || isexpr(ex, :macrocall)
sig = esc(signature(ex))
:($(doc)($binding, $sig))
else
Expand Down
7 changes: 0 additions & 7 deletions base/docs/basedocs.jl
Original file line number Diff line number Diff line change
Expand Up @@ -644,13 +644,6 @@ to be set after construction. See `struct` and the manual for more information.
"""
kw"mutable struct"

"""
@__LINE__ -> Int
`@__LINE__` expands to the line number of the call-site.
"""
kw"@__LINE__"

"""
ans
Expand Down
2 changes: 1 addition & 1 deletion base/docs/utils.jl
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,7 @@ function repl(io::IO, s::Symbol)
$(_repl(s))
end
end
isregex(x) = isexpr(x, :macrocall, 2) && x.args[1] === Symbol("@r_str") && !isempty(x.args[2])
isregex(x) = isexpr(x, :macrocall, 3) && x.args[1] === Symbol("@r_str") && !isempty(x.args[3])
repl(io::IO, ex::Expr) = isregex(ex) ? :(apropos($io, $ex)) : _repl(ex)
repl(io::IO, str::AbstractString) = :(apropos($io, $str))
repl(io::IO, other) = :(@doc $(esc(other)))
Expand Down
1 change: 1 addition & 0 deletions base/exports.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1247,6 +1247,7 @@ export
# parser internal
@__FILE__,
@__DIR__,
@__LINE__,
@int128_str,
@uint128_str,
@big_str,
Expand Down
11 changes: 9 additions & 2 deletions base/expr.jl
Original file line number Diff line number Diff line change
Expand Up @@ -276,9 +276,16 @@ end

remove_linenums!(ex) = ex
function remove_linenums!(ex::Expr)
filter!(x->!((isa(x,Expr) && x.head === :line) || isa(x,LineNumberNode)), ex.args)
if ex.head === :body || ex.head === :block || ex.head === :quote
# remove line number expressions from metadata (not argument literal or inert) position
filter!(ex.args) do x
isa(x, Expr) && x.head === :line && return false
isa(x, LineNumberNode) && return false
return true
end
end
for subex in ex.args
remove_linenums!(subex)
end
ex
return ex
end
6 changes: 3 additions & 3 deletions base/interactiveutil.jl
Original file line number Diff line number Diff line change
Expand Up @@ -349,7 +349,7 @@ function code_warntype(io::IO, f, t::ANY)
end
code_warntype(f, t::ANY) = code_warntype(STDOUT, f, t)

typesof(args...) = Tuple{map(a->(isa(a,Type) ? Type{a} : typeof(a)), args)...}
typesof(args...) = Tuple{Any[ Core.Typeof(a) for a in args ]...}

gen_call_with_extracted_types(fcn, ex0::Symbol) = Expr(:call, fcn, Meta.quot(ex0))
function gen_call_with_extracted_types(fcn, ex0)
Expand All @@ -371,9 +371,9 @@ function gen_call_with_extracted_types(fcn, ex0)
exret = Expr(:none)
is_macro = false
ex = expand(ex0)
if isa(ex0, Expr) && ex0.head == :macrocall # Make @edit @time 1+2 edit the macro
if isa(ex0, Expr) && ex0.head == :macrocall # Make @edit @time 1+2 edit the macro by using the types of the *expressions*
is_macro = true
exret = Expr(:call, fcn, esc(ex0.args[1]), typesof(ex0.args[2:end]...))
exret = Expr(:call, fcn, esc(ex0.args[1]), Tuple{#=__file__=#Any, #=__line__=#Any, Any[ Core.Typeof(a) for a in ex0.args[3:end] ]...})
elseif !isa(ex, Expr)
exret = Expr(:call, :error, "expression is not a function call or symbol")
elseif ex.head == :call
Expand Down
53 changes: 35 additions & 18 deletions base/loading.jl
Original file line number Diff line number Diff line change
Expand Up @@ -521,24 +521,6 @@ function source_dir()
p === nothing ? p : dirname(p)
end

"""
@__FILE__ -> AbstractString
`@__FILE__` expands to a string with the absolute file path of the file containing the
macro. Returns `nothing` if run from a REPL or an empty string if evaluated by
`julia -e <expr>`. Alternatively see [`PROGRAM_FILE`](@ref).
"""
macro __FILE__() source_path() end

"""
@__DIR__ -> AbstractString
`@__DIR__` expands to a string with the directory part of the absolute path of the file
containing the macro. Returns `nothing` if run from a REPL or an empty string if
evaluated by `julia -e <expr>`.
"""
macro __DIR__() source_dir() end

include_from_node1(path::AbstractString) = include_from_node1(String(path))
function include_from_node1(_path::String)
path, prev = _include_dependency(_path)
Expand Down Expand Up @@ -806,3 +788,38 @@ function stale_cachefile(modpath::String, cachefile::String)
close(io)
end
end

"""
@__LINE__ -> Int
`@__LINE__` expands to the line number of the location of the macrocall.
Returns `0` if the line number could not be determined.
"""
macro __LINE__()
__line__ === nothing && return 0
return __line__
end

"""
@__FILE__ -> AbstractString
`@__FILE__` expands to a string with the absolute file path of the file containing the
macrocall. Returns `nothing` if run from a REPL or an empty string if evaluated by
`julia -e <expr>`. Alternatively see [`PROGRAM_FILE`](@ref).
"""
macro __FILE__()
__file__ === nothing && return nothing
return String(__file__)
end

"""
@__DIR__ -> AbstractString
`@__DIR__` expands to a string with the directory part of the absolute path of the file
containing the macrocall. Returns `nothing` if run from a REPL or an empty string if
evaluated by `julia -e <expr>`.
"""
macro __DIR__()
__file__ === nothing && return nothing
return dirname(String(__file__))
end
2 changes: 1 addition & 1 deletion base/math.jl
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ macro evalpoly(z, p...)
:(s = muladd(x, x, y*y)),
as...,
:(muladd($ai, tt, $b)))
R = Expr(:macrocall, Symbol("@horner"), :tt, map(esc, p)...)
R = Expr(:macrocall, Symbol("@horner"), (), :tt, map(esc, p)...)
:(let tt = $(esc(z))
isa(tt, Complex) ? $C : $R
end)
Expand Down
20 changes: 14 additions & 6 deletions base/show.jl
Original file line number Diff line number Diff line change
Expand Up @@ -528,8 +528,8 @@ end

emphasize(io, str::AbstractString) = have_color ? print_with_color(Base.error_color(), io, str; bold = true) : print(io, uppercase(str))

show_linenumber(io::IO, line) = print(io," # line ",line,':')
show_linenumber(io::IO, line, file) = print(io," # ", file,", line ",line,':')
show_linenumber(io::IO, line) = print(io, " #= line ", line, " =#")
show_linenumber(io::IO, line, file) = print(io, " #= ", file, ":", line, " =#")

# show a block, e g if/for/etc
function show_block(io::IO, head, args::Vector, body, indent::Int)
Expand All @@ -556,7 +556,7 @@ end
# show an indented list
function show_list(io::IO, items, sep, indent::Int, prec::Int=0, enclose_operators::Bool=false)
n = length(items)
if n == 0; return end
n == 0 && return
indent += indent_width
first = true
for item in items
Expand Down Expand Up @@ -903,12 +903,20 @@ function show_unquoted(io::IO, ex::Expr, indent::Int, prec::Int)
print(io, head, ' ')
show_list(io, args, ", ", indent)

elseif head === :macrocall && nargs >= 1
elseif head === :macrocall && nargs >= 2
# first show the line number argument as a comment
if isa(args[2], LineNumberNode) || is_expr(args[2], :line)
print(io, args[2], ' ')
end
# Use the functional syntax unless specifically designated with prec=-1
# and hide the line number argument from the argument list
if prec >= 0
show_call(io, :call, ex.args[1], ex.args[2:end], indent)
show_call(io, :call, args[1], args[3:end], indent)
else
show_list(io, args, ' ', indent)
show_args = Vector{Any}(length(args) - 1)
show_args[1] = args[1]
show_args[2:end] = args[3:end]
show_list(io, show_args, ' ', indent)
end

elseif head === :line && 1 <= nargs <= 2
Expand Down
3 changes: 3 additions & 0 deletions doc/Makefile
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
# Makefile for building documentation

skip:
echo SKIPPING BUILD DOCS

default: html

# You can set these variables from the command line.
Expand Down
3 changes: 2 additions & 1 deletion examples/clustermanager/simple/UnixDomainCM.jl
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ function launch(manager::UnixDomainCM, params::Dict, launched::Array, c::Conditi
for i in 1:manager.np
sockname = tempname()
try
cmd = `$(params[:exename]) --startup-file=no $(@__FILE__) udwrkr $sockname $cookie`
__file__ = @__FILE__
cmd = `$(params[:exename]) --startup-file=no $__file__ udwrkr $sockname $cookie`
pobj = open(cmd)

wconfig = WorkerConfig()
Expand Down
2 changes: 1 addition & 1 deletion examples/clustermanager/simple/test_simple.jl
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# This file is a part of Julia. License is MIT: https://julialang.org/license

cmanpath = joinpath(dirname(@__FILE__), "UnixDomainCM.jl")
cmanpath = joinpath(@__DIR__, "UnixDomainCM.jl")
include(cmanpath)

npids = addprocs(UnixDomainCM(2))
Expand Down
25 changes: 21 additions & 4 deletions src/ast.c
Original file line number Diff line number Diff line change
Expand Up @@ -176,19 +176,36 @@ value_t fl_invoke_julia_macro(fl_context_t *fl_ctx, value_t *args, uint32_t narg
{
JL_TIMING(MACRO_INVOCATION);
jl_ptls_t ptls = jl_get_ptls_states();
if (nargs < 1)
argcount(fl_ctx, "invoke-julia-macro", nargs, 1);
if (nargs < 2) // macro name and location
argcount(fl_ctx, "invoke-julia-macro", nargs, 2);
nargs += 1; // split metadata into separate arguments
jl_method_instance_t *mfunc = NULL;
jl_value_t **margs;
// Reserve one more slot for the result
JL_GC_PUSHARGS(margs, nargs + 1);
int i;
for(i=1; i < nargs; i++) margs[i] = scm_to_julia(fl_ctx, args[i], 1);
margs[0] = scm_to_julia(fl_ctx, args[0], 1);
jl_value_t *lno = scm_to_julia(fl_ctx, args[1], 1);
margs[1] = jl_nothing; // __file__
margs[2] = jl_nothing; // __line__
if (jl_is_expr(lno) && ((jl_expr_t*)lno)->head == line_sym) {
switch (jl_expr_nargs(lno)) { // fall-through is intentional
case 2:
margs[1] = jl_exprarg(lno, 1); // file
case 1:
margs[2] = jl_exprarg(lno, 0); // line
default: ;
}
}
else if (jl_typeis(lno, jl_linenumbernode_type)) {
margs[2] = jl_box_long(*(intptr_t*)lno);
}
for (i = 3; i < nargs; i++)
margs[i] = scm_to_julia(fl_ctx, args[i - 1], 1);
jl_value_t *result = NULL;
size_t world = jl_get_ptls_states()->world_age;

JL_TRY {
margs[0] = scm_to_julia(fl_ctx, args[0], 1);
margs[0] = jl_toplevel_eval(margs[0]);
mfunc = jl_method_lookup(jl_gf_mtable(margs[0]), margs, nargs, 1, world);
if (mfunc == NULL) {
Expand Down
Loading

0 comments on commit 10afb8f

Please sign in to comment.