Skip to content

Commit 58082d9

Browse files
authored
Make source_location() and line_starts consistent (#552)
when the last source byte is a newline
1 parent d426bda commit 58082d9

File tree

3 files changed

+19
-10
lines changed

3 files changed

+19
-10
lines changed

src/source_files.jl

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -156,9 +156,6 @@ function SourceFile(code::AbstractString; filename=nothing, first_line=1,
156156
# The line is considered to start after the `\n`
157157
code[i] == '\n' && push!(line_starts, i+1)
158158
end
159-
if isempty(code) || last(code) != '\n'
160-
push!(line_starts, ncodeunits(code)+1)
161-
end
162159
SourceFile(code, first_index-1, filename, first_line, line_starts)
163160
end
164161

@@ -168,8 +165,7 @@ end
168165

169166
# Get line number of the given byte within the code
170167
function _source_line_index(source::SourceFile, byte_index)
171-
lineidx = searchsortedlast(source.line_starts, byte_index - source.byte_offset)
172-
return (lineidx < lastindex(source.line_starts)) ? lineidx : lineidx-1
168+
searchsortedlast(source.line_starts, byte_index - source.byte_offset)
173169
end
174170
_source_line(source::SourceFile, lineidx) = lineidx + source.first_line - 1
175171

@@ -204,7 +200,10 @@ function source_line_range(source::SourceFile, byte_index::Integer;
204200
context_lines_before=0, context_lines_after=0)
205201
lineidx = _source_line_index(source, byte_index)
206202
fbyte = source.line_starts[max(lineidx-context_lines_before, 1)]
207-
lbyte = source.line_starts[min(lineidx+1+context_lines_after, end)] - 1
203+
lline = lineidx + context_lines_after
204+
lbyte = lline >= lastindex(source.line_starts) ?
205+
ncodeunits(source.code) : source.line_starts[lline + 1] - 1
206+
208207
return (fbyte + source.byte_offset,
209208
lbyte + source.byte_offset)
210209
end

test/source_files.jl

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,23 +3,28 @@
33
@test source_location(SourceFile("a"), 2) == (1,2)
44

55
@test source_location(SourceFile("a\n"), 2) == (1,2)
6-
@test source_location(SourceFile("a\n"), 3) == (1,3)
6+
@test source_location(SourceFile("a\n"), 3) == (2,1)
77

88
@test source_location(SourceFile("a\nb\n"), 2) == (1,2)
99
@test source_location(SourceFile("a\nb\n"), 3) == (2,1)
1010
@test source_location(SourceFile("a\nb\n"), 4) == (2,2)
11-
@test source_location(SourceFile("a\nb\n"), 5) == (2,3)
11+
@test source_location(SourceFile("a\nb\n"), 5) == (3,1)
12+
13+
@test source_location(SourceFile("\n\n"), 1) == (1,1)
14+
@test source_location(SourceFile("\n\n"), 2) == (2,1)
15+
@test source_location(SourceFile("\n\n"), 3) == (3,1)
1216

1317
@test source_location(SourceFile("a"; first_line=7), 1) == (7,1)
1418
@test source_location(SourceFile("a"; first_line=7), 2) == (7,2)
1519

1620
@test source_location(SourceFile("a\n"; first_line=7), 2) == (7,2)
17-
@test source_location(SourceFile("a\n"; first_line=7), 3) == (7,3)
21+
@test source_location(SourceFile("a\n"; first_line=7), 3) == (8,1)
1822

1923
@test source_location(SourceFile("a\nb\n"; first_line=7), 2) == (7,2)
2024
@test source_location(SourceFile("a\nb\n"; first_line=7), 3) == (8,1)
2125
@test source_location(SourceFile("a\nb\n"; first_line=7), 4) == (8,2)
22-
@test source_location(SourceFile("a\nb\n"; first_line=7), 5) == (8,3)
26+
@test source_location(SourceFile("a\nb\n"; first_line=7), 5) == (9,1)
27+
2328

2429
mktemp() do path, io
2530
write(io, "a\n")

test/syntax_tree.jl

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,11 @@
3737
e = try node.val = :q catch e e end
3838
@test occursin("immutable", e.msg) && occursin("SyntaxData", e.msg)
3939

40+
# Newline-terminated source
41+
t = parsestmt(SyntaxNode, "a*b + c\n")
42+
@test sprint(highlight, t[1][3]) == "a*b + c\n# ╙"
43+
@test sprint(highlight, t.source, t.raw, 1, 3) == "a*b + c\n# ╙"
44+
4045
# copy
4146
t = parsestmt(SyntaxNode, "a*b + c")
4247
ct = copy(t)

0 commit comments

Comments
 (0)