Skip to content

Commit

Permalink
Support for lineno in core parser hooks (#259)
Browse files Browse the repository at this point in the history
Closes #241
  • Loading branch information
c42f committed Apr 28, 2023
1 parent 694d7c2 commit 4fb97b8
Show file tree
Hide file tree
Showing 3 changed files with 19 additions and 6 deletions.
9 changes: 5 additions & 4 deletions src/hooks.jl
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,8 @@ function _core_parser_hook(code, filename::String, lineno::Int, offset::Int, opt
end

if any_error(stream)
tree = build_tree(SyntaxNode, stream, wrap_toplevel_as_kind=K"None")
tree = build_tree(SyntaxNode, stream,
wrap_toplevel_as_kind=K"None", first_line=lineno)
_,err = _first_error(tree)
# In the flisp parser errors are normally `Expr(:error, msg)` where
# `msg` is a String. By using a ParseError for msg we can do fancy
Expand All @@ -179,7 +180,7 @@ function _core_parser_hook(code, filename::String, lineno::Int, offset::Int, opt
"incomplete: premature end of input"
error_ex = Expr(:incomplete, msg)
else
error_ex = Expr(:error, ParseError(stream, filename=filename))
error_ex = Expr(:error, ParseError(stream, filename=filename, first_line=lineno))
end
ex = options === :all ? Expr(:toplevel, error_ex) : error_ex
else
Expand All @@ -190,8 +191,8 @@ function _core_parser_hook(code, filename::String, lineno::Int, offset::Int, opt
#
# show_diagnostics(stdout, stream.diagnostics, code)
#
# FIXME: Add support to lineno to this tree build (via SourceFile?)
ex = build_tree(Expr, stream; filename=filename, wrap_toplevel_as_kind=K"None")
ex = build_tree(Expr, stream; filename=filename,
wrap_toplevel_as_kind=K"None", first_line=lineno)
if Meta.isexpr(ex, :None)
# The None wrapping is only to give somewhere for trivia to be
# attached; unwrap!
Expand Down
1 change: 0 additions & 1 deletion src/source_files.jl
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ function SourceFile(code::AbstractString; filename=nothing, first_line=1)
line_starts = Int[1]
for i in eachindex(code)
# The line is considered to start after the `\n`
# FIXME: \r and \n\r
code[i] == '\n' && push!(line_starts, i+1)
end
if isempty(code) || last(code) != '\n'
Expand Down
15 changes: 14 additions & 1 deletion test/hooks.jl
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,23 @@
@test JuliaSyntax._core_parser_hook(" x \n", "somefile", 1, 0, :atom) == Core.svec(:x,2)
end

@testset "filename is used" begin
@testset "filename and lineno" begin
ex = JuliaSyntax._core_parser_hook("@a", "somefile", 1, 0, :statement)[1]
@test Meta.isexpr(ex, :macrocall)
@test ex.args[2] == LineNumberNode(1, "somefile")

ex = JuliaSyntax._core_parser_hook("@a", "otherfile", 2, 0, :statement)[1]
@test ex.args[2] == LineNumberNode(2, "otherfile")

# Errors also propagate file & lineno
err = JuliaSyntax._core_parser_hook("[x)", "f1", 1, 0, :statement)[1].args[1]
@test err isa JuliaSyntax.ParseError
@test err.source.filename == "f1"
@test err.source.first_line == 1
err = JuliaSyntax._core_parser_hook("[x)", "f2", 2, 0, :statement)[1].args[1]
@test err isa JuliaSyntax.ParseError
@test err.source.filename == "f2"
@test err.source.first_line == 2
end

@testset "enable_in_core!" begin
Expand Down

0 comments on commit 4fb97b8

Please sign in to comment.