Skip to content

Commit 08977ba

Browse files
committed
fully use JuliaSyntax for SyntaxErrorReport
1 parent 591690d commit 08977ba

File tree

5 files changed

+33
-59
lines changed

5 files changed

+33
-59
lines changed

Project.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ version = "0.9.14"
77
CodeTracking = "da1fd8a2-8d9e-5ec2-8556-3022fb5608a2"
88
InteractiveUtils = "b77e0a4c-d291-57a0-90e8-8db25a27a240"
99
JuliaInterpreter = "aa1ae85d-cabe-5617-a682-6adf51b2e16a"
10+
JuliaSyntax = "70703baa-626e-46a2-a12c-08ffd08c73b4"
1011
LoweredCodeUtils = "6f1432cf-f94c-5a45-995e-cdbf5db27b0b"
1112
MacroTools = "1914dd2f-81c6-5fcd-8719-6d5c9610ff09"
1213
Pkg = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f"
@@ -30,6 +31,7 @@ Cthulhu = "2.14.0"
3031
Example = "0.5.3"
3132
InteractiveUtils = "1.10"
3233
JuliaInterpreter = "0.9.36"
34+
JuliaSyntax = "0.4.10"
3335
Libdl = "1.10"
3436
Logging = "1.10"
3537
LoweredCodeUtils = "3.0.2"

src/JET.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,8 @@ using Base.Meta: ParseError, isexpr, lower
5252

5353
using Base.Experimental: @MethodTable, @overlay
5454

55+
using JuliaSyntax: JuliaSyntax
56+
5557
using CodeTracking: CodeTracking
5658

5759
using LoweredCodeUtils: LoweredCodeUtils, add_ssa_preds!, callee_matches
@@ -334,8 +336,6 @@ include("abstractinterpret/typeinfer.jl")
334336

335337
function print_report end
336338

337-
const JULIA_SYNTAX_ENABLED = !(Base.get_bool_env("JULIA_USE_FLISP_PARSER", false))
338-
339339
include("toplevel/virtualprocess.jl")
340340

341341
# results

src/toplevel/virtualprocess.jl

Lines changed: 26 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -22,28 +22,34 @@ function Base.getproperty(er::ToplevelErrorReport, sym::Symbol)
2222
end
2323

2424
struct SyntaxErrorReport <: ToplevelErrorReport
25-
err::Exception
25+
err::JuliaSyntax.ParseError
2626
file::String
2727
line::Int
28-
function SyntaxErrorReport(@nospecialize(err), file, line)
29-
isa(err, Exception) || (err = ErrorException(err))
30-
return new(err, file, line)
28+
function SyntaxErrorReport(err::JuliaSyntax.ParseError)
29+
lnn = JuliaSyntax.source_location(LineNumberNode, err.source,
30+
JuliaSyntax.first_byte(first(err.diagnostics)))
31+
return new(err, String(lnn.file::Symbol), lnn.line)
3132
end
3233
end
3334
# don't show stacktrace for syntax errors
3435
print_report(io::IO, report::SyntaxErrorReport) = showerror(io, report.err)
3536

37+
# TODO Use JuliaLowering.jl here
38+
struct LoweringErrorReport <: ToplevelErrorReport
39+
msg::String
40+
file::String
41+
line::Int
42+
end
43+
# don't show stacktrace for syntax errors
44+
print_report(io::IO, report::LoweringErrorReport) = showerror(io, ErrorException(lazy"syntax: $(report.msg)"))
45+
3646
# wraps general errors from actual execution
3747
struct ActualErrorWrapped <: ToplevelErrorReport
3848
err
3949
st::Base.StackTraces.StackTrace
4050
file::String
4151
line::Int
4252
function ActualErrorWrapped(@nospecialize(err), st, file, line)
43-
if isa(err, ErrorException) && startswith(err.msg, "syntax: ")
44-
# forward syntax error
45-
return SyntaxErrorReport(err.msg, file, line)
46-
end
4753
return new(err, st, file, line)
4854
end
4955
end
@@ -580,16 +586,19 @@ function _virtual_process!(res::VirtualProcessResult,
580586
end
581587

582588
s = String(s)::String
583-
toplevelex = Base.parse_input_line(s; filename)
589+
parsed = try
590+
JuliaSyntax.parseall(Expr, s; filename)
591+
catch err
592+
err isa JuliaSyntax.ParseError || rethrow(err)
593+
err
594+
end
584595

585-
if isexpr(toplevelex, (:error, :incomplete))
596+
if parsed isa JuliaSyntax.ParseError
586597
# if there's any syntax error, try to identify all the syntax error location
587-
report_syntax_errors!(res, s, filename)
588-
elseif isnothing(toplevelex)
589-
# just return if there is nothing to analyze
598+
push!(res.toplevel_error_reports, SyntaxErrorReport(parsed))
590599
else
591-
@assert isexpr(toplevelex, :toplevel)
592-
_virtual_process!(res, toplevelex, filename, analyzer, config, context, pkg_mod_depth)
600+
@assert isexpr(parsed, :toplevel)
601+
_virtual_process!(res, parsed, filename, analyzer, config, context, pkg_mod_depth)
593602
end
594603

595604
with_toplevel_logger(config) do @nospecialize(io)
@@ -642,8 +651,8 @@ function _virtual_process!(res::VirtualProcessResult,
642651
lwr = lower(mod, x)
643652
# here we should capture syntax errors found during lowering
644653
if isexpr(lwr, :error)
645-
msg = first(lwr.args)
646-
push!(res.toplevel_error_reports, SyntaxErrorReport(lazy"syntax: $msg", filename, lnnref[].line))
654+
msg = first(lwr.args)::String
655+
push!(res.toplevel_error_reports, LoweringErrorReport(msg, filename, lnnref[].line))
647656
return nothing
648657
end
649658
return lwr
@@ -1530,35 +1539,6 @@ let s = string(nameof(AbstractGlobal))
15301539
end
15311540
end
15321541

1533-
function report_syntax_errors!(res, s, filename)
1534-
index = line = 1
1535-
while begin
1536-
ex, nextindex = Base.Meta._parse_string(s, filename, line, index, :statement)
1537-
!isnothing(ex)
1538-
end
1539-
line += count(==('\n'), s[index:nextindex-1])
1540-
if isexpr(ex, :error)
1541-
err = only(ex.args)
1542-
if (@static JULIA_SYNTAX_ENABLED && true) && isa(err, ParseError)
1543-
report = SyntaxErrorReport(err, filename, line)
1544-
else
1545-
report = SyntaxErrorReport(lazy"syntax: $err", filename, line)
1546-
end
1547-
elseif isexpr(ex, :incomplete)
1548-
err = only(ex.args)
1549-
if (@static JULIA_SYNTAX_ENABLED && true) && isa(err, ParseError)
1550-
report = SyntaxErrorReport(err, filename, line)
1551-
else
1552-
report = SyntaxErrorReport(lazy"syntax: $err", filename, line)
1553-
end
1554-
else
1555-
report = nothing
1556-
end
1557-
isnothing(report) || push!(res.toplevel_error_reports, report)
1558-
index = nextindex
1559-
end
1560-
end
1561-
15621542
# a bridge to abstract interpretation
15631543
function analyze_toplevel!(analyzer::AbstractAnalyzer, src::CodeInfo)
15641544
# construct toplevel `MethodInstance`

test/toplevel/test_virtualprocess.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -501,7 +501,7 @@ end
501501
end
502502

503503
@test !isempty(res.res.toplevel_error_reports)
504-
@test only(res.res.toplevel_error_reports) isa SyntaxErrorReport
504+
@test only(res.res.toplevel_error_reports) isa LoweringErrorReport
505505
end
506506
end
507507

test/ui/test_print.jl

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -21,23 +21,15 @@ end
2121
let s = String(take!(io))
2222
@test occursin("1 toplevel error found", s)
2323
@test occursin(Regex("@ $(@__FILE__):\\d"), s)
24-
@static if JET.JULIA_SYNTAX_ENABLED
25-
@test occursin("invalid identifier", s) || occursin("Expected `end`", s)
26-
else
27-
@test occursin("syntax: unexpected \"end\"", s)
28-
end
24+
@test occursin("invalid identifier", s)
2925
end
3026

3127
res = report_text(src, "foo")
3228
print_reports(io, res.res.toplevel_error_reports)
3329
let s = String(take!(io))
3430
@test occursin("1 toplevel error found", s)
3531
@test occursin(r"@ foo:\d", s)
36-
@static if JET.JULIA_SYNTAX_ENABLED
37-
@test occursin("invalid identifier", s) || occursin("Expected `end`", s)
38-
else
39-
@test occursin("syntax: unexpected \"end\"", s)
40-
end
32+
@test occursin("invalid identifier", s)
4133
end
4234
end
4335
end

0 commit comments

Comments
 (0)