Skip to content

Commit 8f8ba0d

Browse files
authored
Fix token error ranges + highlighting for multibyte chars (#271)
1 parent b1c6d54 commit 8f8ba0d

File tree

4 files changed

+22
-10
lines changed

4 files changed

+22
-10
lines changed

src/parse_stream.jl

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -888,7 +888,7 @@ function validate_tokens(stream::ParseStream)
888888
k = kind(t)
889889
fbyte = toks[i-1].next_byte
890890
nbyte = t.next_byte
891-
lbyte = prevind(text, t.next_byte)
891+
tokrange = fbyte:nbyte-1
892892
error_kind = K"None"
893893
if k in KSet"Integer BinInt OctInt HexInt"
894894
# The following shouldn't be able to error...
@@ -909,11 +909,11 @@ function validate_tokens(stream::ParseStream)
909909
if code === :ok
910910
# pass
911911
elseif code === :overflow
912-
emit_diagnostic(stream, fbyte:lbyte,
912+
emit_diagnostic(stream, tokrange,
913913
error="overflow in floating point literal")
914914
error_kind = K"ErrorNumericOverflow"
915915
elseif underflow0
916-
emit_diagnostic(stream, fbyte:lbyte,
916+
emit_diagnostic(stream, tokrange,
917917
warning="underflow to zero in floating point literal")
918918
end
919919
elseif k == K"Char"
@@ -928,7 +928,7 @@ function validate_tokens(stream::ParseStream)
928928
read(charbuf, Char)
929929
if !eof(charbuf)
930930
error_kind = K"ErrorOverLongCharacter"
931-
emit_diagnostic(stream, fbyte:lbyte,
931+
emit_diagnostic(stream, tokrange,
932932
error="character literal contains multiple characters")
933933
end
934934
end
@@ -940,7 +940,7 @@ function validate_tokens(stream::ParseStream)
940940
end
941941
elseif is_error(k) && k != K"error"
942942
# Emit messages for non-generic token errors
943-
emit_diagnostic(stream, fbyte:lbyte,
943+
emit_diagnostic(stream, tokrange,
944944
error=_token_error_descriptions[k])
945945
end
946946
if error_kind != K"None"

src/source_files.jl

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,10 @@ function Base.getindex(source::SourceFile, i::Int)
108108
source.code[i]
109109
end
110110

111+
function Base.thisind(source::SourceFile, i::Int)
112+
thisind(source.code, i)
113+
end
114+
111115
Base.firstindex(source::SourceFile) = firstindex(source.code)
112116
Base.lastindex(source::SourceFile) = lastindex(source.code)
113117

@@ -203,7 +207,7 @@ function highlight(io::IO, source::SourceFile, range::UnitRange;
203207
print(io, source[x:p-1])
204208
_printstyled(io, hitext; bgcolor=color)
205209
print(io, source[q+1:d])
206-
source[d] == '\n' || print(io, "\n")
210+
source[thisind(source, d)] == '\n' || print(io, "\n")
207211
_print_marker_line(io, source[a:p-1], hitext, true, true, marker_line_color, note, notecolor)
208212
else
209213
# x --------------
@@ -232,13 +236,13 @@ function highlight(io::IO, source::SourceFile, range::UnitRange;
232236
_printstyled(io, source[z:q]; bgcolor=color)
233237
end
234238
print(io, source[q+1:d])
235-
source[d] == '\n' || print(io, "\n")
239+
source[thisind(source, d)] == '\n' || print(io, "\n")
236240
qline = source[c:q]
237241
_print_marker_line(io, "", qline, true, false, marker_line_color, note, notecolor)
238242
end
239-
if context_lines_after > 0 && d+1 < lastindex(source)
243+
if context_lines_after > 0 && d+1 <= lastindex(source)
240244
print(io, '\n')
241-
w1 = source[w] == '\n' ? w - 1 : w
245+
w1 = source[thisind(source, w)] == '\n' ? w - 1 : w
242246
print(io, source[d+1:w1])
243247
end
244248
end

test/diagnostics.jl

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,10 @@ function diagnostic(str; only_first=false, allow_multiple=false)
1111
end
1212
end
1313

14+
@testset "token errors" begin
15+
@test diagnostic(":⥻") == Diagnostic(2, 4, :error, "unknown unicode character")
16+
end
17+
1418
@testset "parser errors" begin
1519
@test diagnostic("+ #==# (a,b)") ==
1620
Diagnostic(2, 7, :error, "whitespace not allowed between prefix function call and argument list")

test/source_files.jl

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ end
5252

5353

5454
@testset "highlight()" begin
55-
src = JuliaSyntax.SourceFile("""
55+
src = SourceFile("""
5656
abcd
5757
αβγδ
5858
+-*/""")
@@ -81,6 +81,10 @@ end
8181
αβγδ
8282
#└─┘
8383
+-*/"""
84+
# multi-byte char at eof
85+
@test sprint(highlight, SourceFile("a α"), 3:4) == "a α\n# ╙"
86+
@test sprint(highlight, SourceFile("a\nα"), 1:4) == "\na\nα\n"
87+
@test sprint(highlight, SourceFile("a\nb\nα"), 3:3) == "a\nb\n\nα"
8488

8589
# Multi-line ranges
8690
@test sprint(highlight, src, 1:7) == """

0 commit comments

Comments
 (0)