diff --git a/src/parser_api.jl b/src/parser_api.jl index 6eca864d..51548a99 100644 --- a/src/parser_api.jl +++ b/src/parser_api.jl @@ -17,7 +17,13 @@ end function Base.showerror(io::IO, err::ParseError) println(io, "ParseError:") - show_diagnostics(io, err.diagnostics, err.source) + # Only show the first parse error for now - later errors are often + # misleading due to the way recovery works + i = findfirst(is_error, err.diagnostics) + if isnothing(i) + i = lastindex(err.diagnostics) + end + show_diagnostics(io, err.diagnostics[1:i], err.source) end """ diff --git a/test/parser_api.jl b/test/parser_api.jl index 4ceb8b58..9e05dee1 100644 --- a/test/parser_api.jl +++ b/test/parser_api.jl @@ -117,7 +117,7 @@ end @testset "ParseError printing" begin try - JuliaSyntax.parsestmt(JuliaSyntax.SyntaxNode, "a -- b -- c", filename="somefile.jl") + parsestmt(SyntaxNode, "a -- b -- c", filename="somefile.jl") @assert false "error should be thrown" catch exc @test exc isa JuliaSyntax.ParseError @@ -125,20 +125,48 @@ end ParseError: # Error @ somefile.jl:1:3 a -- b -- c - # └┘ ── invalid operator - # Error @ somefile.jl:1:8 - a -- b -- c - # └┘ ── invalid operator""" + # └┘ ── invalid operator""" @test occursin("Stacktrace:\n", sprint(showerror, exc, catch_backtrace())) file_url = JuliaSyntax._file_url("somefile.jl") @test sprint(showerror, exc, context=:color=>true) == """ ParseError: \e[90m# Error @ \e[0;0m\e]8;;$file_url#1:3\e\\\e[90msomefile.jl:1:3\e[0;0m\e]8;;\e\\ a \e[48;2;120;70;70m--\e[0;0m b -- c - \e[90m# └┘ ── \e[0;0m\e[91minvalid operator\e[0;0m - \e[90m# Error @ \e[0;0m\e]8;;$file_url#1:8\e\\\e[90msomefile.jl:1:8\e[0;0m\e]8;;\e\\ - a -- b \e[48;2;120;70;70m--\e[0;0m c - \e[90m# └┘ ── \e[0;0m\e[91minvalid operator\e[0;0m""" + \e[90m# └┘ ── \e[0;0m\e[91minvalid operator\e[0;0m""" + end + + try + # Test that warnings are printed first followed by only the first error + parsestmt(SyntaxNode, """ + @(a) + x -- y + z -- y""", filename="somefile.jl") + @assert false "error should be thrown" + catch exc + @test exc isa JuliaSyntax.ParseError + @test sprint(showerror, exc) == """ + ParseError: + # Warning @ somefile.jl:1:2 + @(a) + #└─┘ ── parenthesizing macro names is unnecessary + # Error @ somefile.jl:2:1 + @(a) + x + ╙ ── unexpected text after parsing statement""" + end + + try + # Test that initial warnings are always printed + parsestmt(SyntaxNode, """ + @(a)""", filename="somefile.jl") + @assert false "error should be thrown" + catch exc + @test exc isa JuliaSyntax.ParseError + @test sprint(showerror, exc) == """ + ParseError: + # Warning @ somefile.jl:1:2 + @(a) + #└─┘ ── parenthesizing macro names is unnecessary""" end end