From 1cb35586ed93b02ddbcc5fc29bc743ce3a16fc4a Mon Sep 17 00:00:00 2001 From: Jeff Bezanson Date: Tue, 14 Apr 2020 14:32:55 -0400 Subject: [PATCH] fix #35134, regression in printing nested quote Exprs --- base/show.jl | 34 +++++------- doc/src/manual/metaprogramming.md | 16 +++--- test/show.jl | 92 ++++--------------------------- 3 files changed, 35 insertions(+), 107 deletions(-) diff --git a/base/show.jl b/base/show.jl index 9423fd7bbf235..80a8fb6c8faef 100644 --- a/base/show.jl +++ b/base/show.jl @@ -1207,13 +1207,7 @@ function show_unquoted_expr_fallback(io::IO, ex::Expr, indent::Int, quote_level: show(io, ex.head) for arg in ex.args print(io, ", ") - if isa(arg, Expr) - print(io, ":(") - show_unquoted(io, arg, indent, 0, quote_level+1) - print(io, ")") - else - show(io, arg) - end + show(io, arg) end print(io, "))") end @@ -1600,17 +1594,19 @@ function show_unquoted(io::IO, ex::Expr, indent::Int, prec::Int, quote_level::In elseif head === :quote && nargs == 1 && isa(args[1], Symbol) show_unquoted_quote_expr(IOContext(io, beginsym=>false), args[1]::Symbol, indent, 0, quote_level+1) - elseif head === :quote && nargs == 1 && is_expr(args[1], :block) - show_block(IOContext(io, beginsym=>false), "quote", Expr(:quote, args[1].args...), indent, - quote_level+1) - print(io, "end") - elseif head === :quote && nargs == 1 - print(io, ":(") - show_unquoted(IOContext(io, beginsym=>false), args[1], indent+2, 0, quote_level+1) - print(io, ")") - elseif head === :quote - show_block(IOContext(io, beginsym=>false), "quote", ex, indent, quote_level+1) - print(io, "end") + elseif head === :quote && !get(io, :unquote_fallback, true) + if nargs == 1 && is_expr(args[1], :block) + show_block(IOContext(io, beginsym=>false), "quote", Expr(:quote, args[1].args...), indent, + quote_level+1) + print(io, "end") + elseif nargs == 1 + print(io, ":(") + show_unquoted(IOContext(io, beginsym=>false), args[1], indent+2, 0, quote_level+1) + print(io, ")") + else + show_block(IOContext(io, beginsym=>false), "quote", ex, indent, quote_level+1) + print(io, "end") + end elseif head === :gotoifnot && nargs == 2 && isa(args[2], Int) print(io, "unless ") @@ -1645,7 +1641,7 @@ function show_unquoted(io::IO, ex::Expr, indent::Int, prec::Int, quote_level::In if head === :$ quote_level -= 1 end - if head === :$ && quote_level < 0 && get(io, :unquote_fallback, true) + if head === :$ && get(io, :unquote_fallback, true) unhandled = true else print(io, head) diff --git a/doc/src/manual/metaprogramming.md b/doc/src/manual/metaprogramming.md index 2093ad408008d..fc18b523942ec 100644 --- a/doc/src/manual/metaprogramming.md +++ b/doc/src/manual/metaprogramming.md @@ -261,10 +261,10 @@ julia> x = :(1 + 2); julia> e = quote quote $x end end quote #= none:1 =# - quote - #= none:1 =# - $x - end + $(Expr(:quote, quote + #= none:1 =# + $(Expr(:$, :x)) +end)) end ``` @@ -289,10 +289,10 @@ This is done with multiple `$`s: julia> e = quote quote $$x end end quote #= none:1 =# - quote - #= none:1 =# - $(1 + 2) - end + $(Expr(:quote, quote + #= none:1 =# + $(Expr(:$, :(1 + 2))) +end)) end ``` diff --git a/test/show.jl b/test/show.jl index 3104ce5c4bfba..dbb8b51470b4d 100644 --- a/test/show.jl +++ b/test/show.jl @@ -891,8 +891,8 @@ test_mt(show_f5, "show_f5(A::AbstractArray{T,N}, indices::Vararg{$Int,N})") @test_repr repr(Expr(:quote, Expr(:typed_hcat, Expr(:$, :a), 1))) @test_repr "Expr(:quote, Expr(:typed_vcat, Expr(:\$, :a), 1))" @test_repr "Expr(:quote, Expr(:typed_hcat, Expr(:\$, :a), 1))" -@test repr(Expr(:quote, Expr(:typed_vcat, Expr(:$, :a), 1))) == ":(:(\$a[1;]))" -@test repr(Expr(:quote, Expr(:typed_hcat, Expr(:$, :a), 1))) == ":(:(\$a[1]))" +@test_repr repr(Expr(:quote, Expr(:typed_vcat, Expr(:$, :a), 1))) +@test_repr repr(Expr(:quote, Expr(:typed_hcat, Expr(:$, :a), 1))) # Printing of :(function f end) @test sprint(show, :(function f end)) == ":(function f end)" @@ -914,64 +914,6 @@ end""" \$a + \$b end end""" -@test repr(Meta.parse( -"""macro m(a, b) - quote - \$a + \$b - end -end""")) == -""" -:(macro m(a, b) - #= none:1 =# - #= none:2 =# - quote - #= none:3 =# - \$a + \$b - end - end)""" -@test repr(Base.remove_linenums!(Meta.parse( -"""macro m(a, b) - quote - \$a + \$b - end -end"""))) == -""" -:(macro m(a, b) - quote - \$a + \$b - end - end)""" -@test repr(Meta.parse( -"""macro m(a, b) - :(\$a + \$b) -end""")) == -":(macro m(a, b)\n #= none:1 =#\n #= none:2 =#\n :(\$a + \$b)\n end)" -@test repr(Expr(:macro, Expr(:call, :m, :x), Expr(:quote, Expr(:call, :+, Expr(:($), :x), 1)))) == -":(macro m(x)\n :(\$x + 1)\n end)" - -# nested quotes and interpolations -@test repr(Meta.parse( -"""quote - quote - \$\$x - end -end""")) == -""" -:(quote - #= none:2 =# - quote - #= none:3 =# - \$\$x - end - end)""" -@weak_test_repr """ -quote - #= none:2 =# - quote - #= none:3 =# - \$\$x - end -end""" # fallback printing + nested quotes and unquotes @weak_test_repr repr(Expr(:block, LineNumberNode(0, :none), @@ -984,26 +926,15 @@ end""" @test_repr "Expr(:exotic_head, Expr(:call, :+, 1, \$\$y))" @test_repr ":(Expr(:exotic_head, Expr(:call, :+, 1, \$y)))" @test_repr ":(:(Expr(:exotic_head, Expr(:call, :+, 1, \$\$y))))" -@test repr(Expr(:block, LineNumberNode(0, :none), - Expr(:exotic_head, Expr(:$, :x)))) == -""" -quote - #= none:0 =# - \$(Expr(:exotic_head, :(\$x))) -end""" @test repr(Expr(:exotic_head, Expr(:call, :+, 1, :(Expr(:$, :y))))) == ":(\$(Expr(:exotic_head, :(1 + Expr(:\$, :y)))))" -@test repr(Expr(:exotic_head, Expr(:call, :+, 1, Expr(:quote, Expr(:$, :y))))) == - ":(\$(Expr(:exotic_head, :(1 + :(\$y)))))" -@test repr(Expr(:quote, Expr(:exotic_head, Expr(:call, :+, 1, Expr(:$, :y))))) == - ":(:(\$(Expr(:exotic_head, :(1 + \$y)))))" @test repr(Expr(:block, Expr(:(=), :y, 2), Expr(:quote, Expr(:exotic_head, Expr(:call, :+, 1, Expr(:$, :y)))))) == """ quote y = 2 - :(\$(Expr(:exotic_head, :(1 + \$y)))) + \$(Expr(:quote, :(\$(Expr(:exotic_head, :(1 + \$(Expr(:\$, :y)))))))) end""" @test repr(eval(Expr(:block, Expr(:(=), :y, 2), Expr(:quote, Expr(:exotic_head, @@ -1013,20 +944,20 @@ end""" # nested quotes and blocks @test_repr "Expr(:quote, Expr(:block, :a, :b))" @weak_test_repr repr(Expr(:quote, Expr(:block, LineNumberNode(0, :none), :a, LineNumberNode(0, :none), :b))) -@test repr(Expr(:quote, Expr(:block, :a, :b))) == +@test_broken repr(Expr(:quote, Expr(:block, :a, :b))) == ":(quote a b end)" @test_repr "Expr(:quote, Expr(:block, :a))" @weak_test_repr repr(Expr(:quote, Expr(:block, LineNumberNode(0, :none), :a))) -@test repr(Expr(:quote, Expr(:block, :a))) == +@test_broken repr(Expr(:quote, Expr(:block, :a))) == ":(quote a end)" @test_repr "Expr(:quote, Expr(:block, :(a + b)))" @weak_test_repr repr(Expr(:quote, Expr(:block, LineNumberNode(0, :none), :(a + b)))) -@test repr(Expr(:quote, Expr(:block, :(a + b)))) == +@test_broken repr(Expr(:quote, Expr(:block, :(a + b)))) == ":(quote a + b end)" @@ -1037,8 +968,9 @@ end""" @test_repr ":(QuoteNode(\$x))" @test_repr ":(:(QuoteNode(\$\$x)))" @test repr(QuoteNode(Expr(:$, :x))) == ":(\$(QuoteNode(:(\$(Expr(:\$, :x))))))" -@test repr(QuoteNode(Expr(:quote, Expr(:$, :x)))) == ":(\$(QuoteNode(:(:(\$x)))))" -@test repr(Expr(:quote, QuoteNode(Expr(:$, :x)))) == ":(:(\$(QuoteNode(:(\$(Expr(:\$, :x)))))))" +@test repr(QuoteNode(Expr(:quote, Expr(:$, :x)))) == ":(\$(QuoteNode(:(\$(Expr(:quote, :(\$(Expr(:\$, :x)))))))))" +@test repr(Expr(:quote, QuoteNode(Expr(:$, :x)))) == ":(\$(Expr(:quote, :(\$(QuoteNode(:(\$(Expr(:\$, :x)))))))))" +@test repr(Expr(:quote, Expr(:quote, Expr(:foo)))) == ":(\$(Expr(:quote, :(\$(Expr(:quote, :(\$(Expr(:foo)))))))))" # unquoting @test_repr "\$y" @@ -1061,13 +993,13 @@ y856739 = 2 x856739 = :y856739 z856739 = [:a, :b] @test_repr repr(:(:(f($$x856739)))) -@test repr(:(:(f($$x856739)))) == ":(:(f(\$y856739)))" +@test_broken repr(:(:(f($$x856739)))) == ":(:(f(\$y856739)))" @test repr(eval(:(:(f($$x856739))))) == ":(f(2))" @test_repr repr(:(:(f($x856739)))) -@test repr(:(:(f($x856739)))) == ":(:(f(\$x856739)))" +@test_broken repr(:(:(f($x856739)))) == ":(:(f(\$x856739)))" @test repr(eval(:(:(f($x856739))))) == ":(f(y856739))" @test_repr repr(:(:(f($(($z856739)...))))) -@test repr(:(:(f($(($z856739)...))))) == ":(:(f(\$([:a, :b]...))))" +@test_broken repr(:(:(f($(($z856739)...))))) == ":(:(f(\$([:a, :b]...))))" @test repr(eval(:(:(f($(($z856739)...)))))) == ":(f(a, b))" # string interpolation, if this is what the comment in test_rep function