Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix #25474, support more forms in edit, which, etc. macros #29159

Merged
merged 1 commit into from
Sep 14, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 38 additions & 10 deletions stdlib/InteractiveUtils/src/macros.jl
Original file line number Diff line number Diff line change
Expand Up @@ -15,22 +15,50 @@ function gen_call_with_extracted_types(__module__, fcn, ex0)
$(fcn)(Core.kwfunc(arg1),
Tuple{typeof(kwargs), Core.Typeof(arg1), map(Core.Typeof, args)...})
end
elseif ex0.head == :call
elseif ex0.head === :call
return Expr(:call, fcn, esc(ex0.args[1]),
Expr(:call, typesof, map(esc, ex0.args[2:end])...))
elseif ex0.head == :(=) && length(ex0.args) == 2 && ex0.args[1].head == :(.)
return Expr(:call, fcn, Base.setproperty!,
Expr(:call, typesof, map(esc, [ex0.args[1].args..., ex0.args[2]])...))
elseif ex0.head === :(=) && length(ex0.args) == 2
lhs, rhs = ex0.args
if isa(lhs, Expr)
if lhs.head === :(.)
return Expr(:call, fcn, Base.setproperty!,
Expr(:call, typesof, map(esc, lhs.args)..., esc(rhs)))
elseif lhs.head === :ref
return Expr(:call, fcn, Base.setindex!,
Expr(:call, typesof, esc(lhs.args[1]), esc(rhs), map(esc, lhs.args[2:end])...))
end
end
elseif ex0.head === :vcat || ex0.head === :typed_vcat
if ex0.head === :vcat
f, hf = Base.vcat, Base.hvcat
args = ex0.args
else
f, hf = Base.typed_vcat, Base.typed_hvcat
args = ex0.args[2:end]
end
if any(a->isa(a,Expr) && a.head === :row, args)
rows = Any[ (isa(x,Expr) && x.head === :row ? x.args : Any[x]) for x in args ]
lens = map(length, rows)
return Expr(:call, fcn, hf,
Expr(:call, typesof,
(ex0.head === :vcat ? [] : Any[esc(ex0.args[1])])...,
Expr(:tuple, lens...),
map(esc, vcat(rows...))...))
else
return Expr(:call, fcn, f,
Expr(:call, typesof, map(esc, ex0.args)...))
end
else
for (head, f) in (:ref => Base.getindex, :vcat => Base.vcat, :hcat => Base.hcat, :(.) => Base.getproperty, :vect => Base.vect)
if ex0.head == head
for (head, f) in (:ref => Base.getindex, :hcat => Base.hcat, :(.) => Base.getproperty, :vect => Base.vect, Symbol("'") => Base.adjoint, :typed_hcat => Base.typed_hcat, :string => string)
if ex0.head === head
return Expr(:call, fcn, f,
Expr(:call, typesof, map(esc, ex0.args)...))
end
end
end
end
if isa(ex0, Expr) && ex0.head == :macrocall # Make @edit @time 1+2 edit the macro by using the types of the *expressions*
if isa(ex0, Expr) && ex0.head === :macrocall # Make @edit @time 1+2 edit the macro by using the types of the *expressions*
return Expr(:call, fcn, esc(ex0.args[1]), Tuple{#=__source__=#LineNumberNode, #=__module__=#Module, Any[ Core.Typeof(a) for a in ex0.args[3:end] ]...})
end

Expand All @@ -40,8 +68,8 @@ function gen_call_with_extracted_types(__module__, fcn, ex0)
end

exret = Expr(:none)
if ex.head == :call
if any(e->(isa(e, Expr) && e.head==:(...)), ex0.args) &&
if ex.head === :call
if any(e->(isa(e, Expr) && e.head === :(...)), ex0.args) &&
(ex.args[1] === GlobalRef(Core,:_apply) ||
ex.args[1] === GlobalRef(Base,:_apply))
# check for splatting
Expand All @@ -53,7 +81,7 @@ function gen_call_with_extracted_types(__module__, fcn, ex0)
Expr(:call, typesof, map(esc, ex.args[2:end])...))
end
end
if ex.head == :thunk || exret.head == :none
if 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")
Expand Down
25 changes: 14 additions & 11 deletions stdlib/InteractiveUtils/test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -198,20 +198,23 @@ const curmod_str = curmod === Main ? "Main" : join(curmod_name, ".")
# issue #13264
@test (@which vcat(1...)).name == :vcat

# PR #28122
# PR #28122, issue #25474
@test (@which [1][1]).name === :getindex
@test (@which [1 2]).name == :hcat
@test (@which [1; 2]).name == :vcat
@test (@which [1]).name == :vect
@test (@which [1][1] = 2).name === :setindex!
@test (@which [1]).name === :vect
@test (@which [1 2]).name === :hcat
@test (@which [1; 2]).name === :vcat
@test (@which Int[1 2]).name === :typed_hcat
@test (@which Int[1; 2]).name === :typed_vcat
@test (@which [1 2;3 4]).name === :hvcat
@test (@which Int[1 2;3 4]).name === :typed_hvcat

# issue #13464
let t13464 = "hey there sailor"
try
@which t13464[1,1] = (1.0,true)
error("unexpected")
catch err13464
@test startswith(err13464.msg, "expression is not a function call, or is too complex")
end
try
@which x = 1
error("unexpected")
catch err13464
@test startswith(err13464.msg, "expression is not a function call, or is too complex")
end

module MacroTest
Expand Down