Skip to content

Commit e78a222

Browse files
authored
Fix InexactError in peek_behind_pos when skipping nested trivia nodes (#604)
1 parent c5e4c03 commit e78a222

File tree

2 files changed

+17
-1
lines changed

2 files changed

+17
-1
lines changed

src/core/parse_stream.jl

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -635,8 +635,14 @@ function peek_behind_pos(stream::ParseStream; skip_trivia::Bool=true,
635635
while node_idx > 0
636636
node = stream.output[node_idx]
637637
if kind(node) == K"TOMBSTONE" || (skip_trivia && is_trivia(node))
638-
node_idx -= 1
639638
byte_idx -= node.byte_span
639+
# If this is a non-terminal node, skip its children without
640+
# subtracting their byte_spans, as they're already included in the parent
641+
if is_non_terminal(node)
642+
node_idx -= (1 + node.node_span)
643+
else
644+
node_idx -= 1
645+
end
640646
else
641647
break
642648
end

test/parse_stream.jl

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,3 +156,13 @@ end
156156
@test ParseStream(y) isa ParseStream
157157
@test parsestmt(Expr, y) == parsestmt(Expr, "1")
158158
end
159+
160+
@testset "peek_behind_pos with negative byte index" begin
161+
# Test that peek_behind_pos doesn't cause InexactError when byte_idx goes negative
162+
# This can happen when parsing certain incomplete keywords like "do"
163+
# where trivia skipping walks back past the beginning of the stream
164+
@test_throws JuliaSyntax.ParseError parseall(GreenNode, "do")
165+
@test_throws JuliaSyntax.ParseError parseall(GreenNode, "do ")
166+
@test_throws JuliaSyntax.ParseError parseall(GreenNode, " do")
167+
@test_throws JuliaSyntax.ParseError parseall(GreenNode, "do\n")
168+
end

0 commit comments

Comments
 (0)