Skip to content

Commit 4fb97b8

Browse files
authored
Support for lineno in core parser hooks (#259)
Closes #241
1 parent 694d7c2 commit 4fb97b8

File tree

3 files changed

+19
-6
lines changed

3 files changed

+19
-6
lines changed

src/hooks.jl

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,8 @@ function _core_parser_hook(code, filename::String, lineno::Int, offset::Int, opt
162162
end
163163

164164
if any_error(stream)
165-
tree = build_tree(SyntaxNode, stream, wrap_toplevel_as_kind=K"None")
165+
tree = build_tree(SyntaxNode, stream,
166+
wrap_toplevel_as_kind=K"None", first_line=lineno)
166167
_,err = _first_error(tree)
167168
# In the flisp parser errors are normally `Expr(:error, msg)` where
168169
# `msg` is a String. By using a ParseError for msg we can do fancy
@@ -179,7 +180,7 @@ function _core_parser_hook(code, filename::String, lineno::Int, offset::Int, opt
179180
"incomplete: premature end of input"
180181
error_ex = Expr(:incomplete, msg)
181182
else
182-
error_ex = Expr(:error, ParseError(stream, filename=filename))
183+
error_ex = Expr(:error, ParseError(stream, filename=filename, first_line=lineno))
183184
end
184185
ex = options === :all ? Expr(:toplevel, error_ex) : error_ex
185186
else
@@ -190,8 +191,8 @@ function _core_parser_hook(code, filename::String, lineno::Int, offset::Int, opt
190191
#
191192
# show_diagnostics(stdout, stream.diagnostics, code)
192193
#
193-
# FIXME: Add support to lineno to this tree build (via SourceFile?)
194-
ex = build_tree(Expr, stream; filename=filename, wrap_toplevel_as_kind=K"None")
194+
ex = build_tree(Expr, stream; filename=filename,
195+
wrap_toplevel_as_kind=K"None", first_line=lineno)
195196
if Meta.isexpr(ex, :None)
196197
# The None wrapping is only to give somewhere for trivia to be
197198
# attached; unwrap!

src/source_files.jl

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ function SourceFile(code::AbstractString; filename=nothing, first_line=1)
2222
line_starts = Int[1]
2323
for i in eachindex(code)
2424
# The line is considered to start after the `\n`
25-
# FIXME: \r and \n\r
2625
code[i] == '\n' && push!(line_starts, i+1)
2726
end
2827
if isempty(code) || last(code) != '\n'

test/hooks.jl

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,23 @@
1010
@test JuliaSyntax._core_parser_hook(" x \n", "somefile", 1, 0, :atom) == Core.svec(:x,2)
1111
end
1212

13-
@testset "filename is used" begin
13+
@testset "filename and lineno" begin
1414
ex = JuliaSyntax._core_parser_hook("@a", "somefile", 1, 0, :statement)[1]
1515
@test Meta.isexpr(ex, :macrocall)
1616
@test ex.args[2] == LineNumberNode(1, "somefile")
17+
18+
ex = JuliaSyntax._core_parser_hook("@a", "otherfile", 2, 0, :statement)[1]
19+
@test ex.args[2] == LineNumberNode(2, "otherfile")
20+
21+
# Errors also propagate file & lineno
22+
err = JuliaSyntax._core_parser_hook("[x)", "f1", 1, 0, :statement)[1].args[1]
23+
@test err isa JuliaSyntax.ParseError
24+
@test err.source.filename == "f1"
25+
@test err.source.first_line == 1
26+
err = JuliaSyntax._core_parser_hook("[x)", "f2", 2, 0, :statement)[1].args[1]
27+
@test err isa JuliaSyntax.ParseError
28+
@test err.source.filename == "f2"
29+
@test err.source.first_line == 2
1730
end
1831

1932
@testset "enable_in_core!" begin

0 commit comments

Comments
 (0)