Skip to content

Commit f2452c4

Browse files
authored
A few fixes for ranges of diagnostic messages (#187)
1 parent 1e12afe commit f2452c4

File tree

2 files changed

+29
-19
lines changed

2 files changed

+29
-19
lines changed

src/parse_stream.jl

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -778,10 +778,17 @@ function steal_token_bytes!(stream::ParseStream, pos::ParseStreamPosition, numby
778778
return t2_is_empty
779779
end
780780

781+
# Get position of last item emitted into the output stream
781782
function Base.position(stream::ParseStream)
782783
ParseStreamPosition(lastindex(stream.tokens), lastindex(stream.ranges))
783784
end
784785

786+
# Get position of next item to be emitted into the output stream
787+
# TODO: Figure out how to remove this? It's only used with emit_diagnostic
788+
function next_position(stream::ParseStream)
789+
ParseStreamPosition(lastindex(stream.tokens)+1, lastindex(stream.ranges)+1)
790+
end
791+
785792
"""
786793
emit(stream, mark, kind, flags = EMPTY_FLAGS; error=nothing)
787794
@@ -837,10 +844,6 @@ function emit_diagnostic(stream::ParseStream, mark::ParseStreamPosition; kws...)
837844
_next_byte(stream) - 1; kws...)
838845
end
839846

840-
function emit_diagnostic(stream::ParseStream, r::NTuple{2,ParseStreamPosition}; kws...)
841-
emit_diagnostic(stream, first(r), last(r); kws...)
842-
end
843-
844847
function emit_diagnostic(stream::ParseStream, mark::ParseStreamPosition,
845848
end_mark::ParseStreamPosition; kws...)
846849
fbyte = token_first_byte(stream, mark.token_index)

src/parser.jl

Lines changed: 22 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,10 @@ function Base.position(ps::ParseState, args...)
113113
position(ps.stream, args...)
114114
end
115115

116+
function next_position(ps::ParseState, args...)
117+
next_position(ps.stream, args...)
118+
end
119+
116120
function emit(ps::ParseState, args...; kws...)
117121
emit(ps.stream, args...; kws...)
118122
end
@@ -1232,11 +1236,15 @@ function parse_unary(ps::ParseState)
12321236
# last case wrong)
12331237
op_pos = bump_dotsplit(ps, emit_dot_node=true)
12341238

1235-
# Setup possible whitespace error between operator and (
1236-
ws_mark = position(ps)
1237-
bump_trivia(ps)
1238-
ws_mark_end = position(ps)
1239-
ws_error_pos = emit(ps, ws_mark, K"TOMBSTONE")
1239+
space_before_paren = preceding_whitespace(t2)
1240+
if space_before_paren
1241+
# Setup possible whitespace error between operator and (
1242+
ws_node_mark = position(ps)
1243+
ws_mark = next_position(ps)
1244+
bump_trivia(ps)
1245+
ws_error_pos = emit(ps, ws_node_mark, K"TOMBSTONE")
1246+
ws_mark_end = next_position(ps)
1247+
end
12401248

12411249
mark_before_paren = position(ps)
12421250
bump(ps, TRIVIA_FLAG) # (
@@ -1251,7 +1259,7 @@ function parse_unary(ps::ParseState)
12511259
# The precedence between unary + and any following infix ^ depends on
12521260
# whether the parens are a function call or not
12531261
if opts.is_paren_call
1254-
if preceding_whitespace(t2)
1262+
if space_before_paren
12551263
# Whitespace not allowed before prefix function call bracket
12561264
# + (a,b) ==> (call + (error) a b)
12571265
reset_node!(ps, ws_error_pos, kind=K"error")
@@ -1592,7 +1600,7 @@ function parse_call_chain(ps::ParseState, mark, is_macrocall=false)
15921600
# A.B.@x ==> (macrocall (. (. A (quote B)) (quote @x)))
15931601
# @A.B.x ==> (macrocall (. (. A (quote B)) (quote @x)))
15941602
# [email protected] ==> (macrocall (. (. A (error-t) B) (quote @x)))
1595-
emit_diagnostic(ps, macro_atname_range,
1603+
emit_diagnostic(ps, macro_atname_range...,
15961604
error="`@` must appear on first or last macro name component")
15971605
bump(ps, TRIVIA_FLAG, error="Unexpected `.` after macro name")
15981606
else
@@ -1646,7 +1654,7 @@ function parse_call_chain(ps::ParseState, mark, is_macrocall=false)
16461654
end
16471655
parse_macro_name(ps)
16481656
macro_name_position = position(ps)
1649-
macro_atname_range = (m, macro_name_position)
1657+
macro_atname_range = (m, next_position(ps))
16501658
emit(ps, m, K"quote")
16511659
emit(ps, mark, K".")
16521660
elseif k == K"'"
@@ -2484,10 +2492,12 @@ function parse_import_path(ps::ParseState)
24842492
# import . .A ==> (import (. . . A))
24852493
first_dot = true
24862494
while true
2487-
m = position(ps)
2488-
bump_trivia(ps)
2489-
m2 = position(ps)
2490-
k = peek(ps)
2495+
t = peek_token(ps)
2496+
k = kind(t)
2497+
if !first_dot && preceding_whitespace(t)
2498+
emit_diagnostic(ps, whitespace=true,
2499+
warning="space between dots in import path")
2500+
end
24912501
if k == K"."
24922502
bump(ps)
24932503
elseif k == K".."
@@ -2497,9 +2507,6 @@ function parse_import_path(ps::ParseState)
24972507
else
24982508
break
24992509
end
2500-
if !first_dot && m != m2
2501-
emit_diagnostic(ps, m, m2, warning="space between dots in import path")
2502-
end
25032510
first_dot = false
25042511
end
25052512
if is_dotted(peek_token(ps))

0 commit comments

Comments
 (0)