From f808a6a1fca5d82bffc6c540cdd263c5661c20ab Mon Sep 17 00:00:00 2001 From: c42f Date: Wed, 23 Nov 2022 16:11:08 +1000 Subject: [PATCH] Fix source line reporting at EOF --- src/source_files.jl | 9 +++++---- test/runtests.jl | 6 ++---- test/source_files.jl | 12 ++++++++++++ test/test_utils.jl | 1 + 4 files changed, 20 insertions(+), 8 deletions(-) create mode 100644 test/source_files.jl diff --git a/src/source_files.jl b/src/source_files.jl index fa95794a..bff823f9 100644 --- a/src/source_files.jl +++ b/src/source_files.jl @@ -23,7 +23,7 @@ function SourceFile(code::AbstractString; filename=nothing) code[i] == '\n' && push!(line_starts, i+1) end if isempty(code) || last(code) != '\n' - push!(line_starts, lastindex(code)+1) + push!(line_starts, ncodeunits(code)+1) end SourceFile(code, filename, line_starts) end @@ -34,14 +34,15 @@ end # Get line number of the given byte within the code function source_line(source::SourceFile, byte_index) - searchsortedlast(source.line_starts, byte_index) + line = searchsortedlast(source.line_starts, byte_index) + return (line < lastindex(source.line_starts)) ? line : line-1 end """ Get line number and character within the line at the given byte index. """ function source_location(source::SourceFile, byte_index) - line = searchsortedlast(source.line_starts, byte_index) + line = source_line(source, byte_index) i = source.line_starts[line] column = 1 while i < byte_index @@ -57,7 +58,7 @@ Get byte range of the source line at byte_index, buffered by """ function source_line_range(source::SourceFile, byte_index; context_lines_before=0, context_lines_after=0) - line = searchsortedlast(source.line_starts, byte_index) + line = source_line(source, byte_index) fbyte = source.line_starts[max(line-context_lines_before, 1)] lbyte = source.line_starts[min(line+1+context_lines_after, end)] - 1 fbyte,lbyte diff --git a/test/runtests.jl b/test/runtests.jl index b08da533..fad4278d 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -17,12 +17,10 @@ include("parser.jl") include("diagnostics.jl") include("parser_api.jl") include("expr.jl") -@testset "Parsing values from strings" begin +@testset "Parsing literals from strings" begin include("value_parsing.jl") end include("hooks.jl") include("parse_packages.jl") +include("source_files.jl") -# Prototypes -#include("syntax_interpolation.jl") -#include("simple_parser.jl") diff --git a/test/source_files.jl b/test/source_files.jl new file mode 100644 index 00000000..99071926 --- /dev/null +++ b/test/source_files.jl @@ -0,0 +1,12 @@ +@testset "SourceFile lines and column indexing" begin + @test source_location(SourceFile("a"), 1) == (1,1) + @test source_location(SourceFile("a"), 2) == (1,2) + + @test source_location(SourceFile("a\n"), 2) == (1,2) + @test source_location(SourceFile("a\n"), 3) == (1,3) + + @test source_location(SourceFile("a\nb\n"), 2) == (1,2) + @test source_location(SourceFile("a\nb\n"), 3) == (2,1) + @test source_location(SourceFile("a\nb\n"), 4) == (2,2) + @test source_location(SourceFile("a\nb\n"), 5) == (2,3) +end diff --git a/test/test_utils.jl b/test/test_utils.jl index 1cd77284..03bda337 100644 --- a/test/test_utils.jl +++ b/test/test_utils.jl @@ -7,6 +7,7 @@ using .JuliaSyntax: ParseState, Diagnostic, SourceFile, + source_location, parse!, parse, parseall,