Skip to content

Commit

Permalink
Fix insertion of space before comment
Browse files Browse the repository at this point in the history
This patch changes where spaces are inserted before comments so that it
is always added as a sibling to the comment instead of as a "uncle" when
a comment is found as the first leaf of a kid.
  • Loading branch information
fredrikekre committed Sep 10, 2024
1 parent be162ee commit 3bc939e
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 15 deletions.
15 changes: 15 additions & 0 deletions src/chisels.jl
Original file line number Diff line number Diff line change
Expand Up @@ -423,6 +423,21 @@ function replace_last_leaf(node::Node, kid′::Union{Node, NullNode})
end
end

# Insert a node before the first leaf (at the same level)
# TODO: Currently only works for inserting a space before a comment
function add_before_first_leaf(node::Node, kid′::Union{Node, NullNode})
@assert !is_leaf(node)
kids = verified_kids(node)
@assert length(kids) > 0
kids′ = copy(kids)
if kind(kids′[1]) === K"Comment"
pushfirst!(kids′, kid′)
else
kids′[1] = add_before_first_leaf(kids′[1], kid′)
end
return make_node(node, kids′)
end

function last_leaf(node::Node)
if is_leaf(node)
return node
Expand Down
35 changes: 21 additions & 14 deletions src/runestone.jl
Original file line number Diff line number Diff line change
Expand Up @@ -3372,26 +3372,33 @@ function spaces_around_comments(ctx::Context, node::Node)
prev_kid_ends_with_ws = true
ws = Node(JuliaSyntax.SyntaxHead(K"Whitespace", JuliaSyntax.TRIVIA_FLAG), 1)
for (i, kid) in pairs(kids)
if kind(kid) === K"Comment" ||
(fl = first_leaf(kid); fl !== nothing && kind(fl) === K"Comment")
# TODO: In the case where the comment is found within the kid the whitespace
# should maybe be added right before the comment in the tree (which is how
# JuliaSyntax would have parsed the source if the space was already there). I
# don't know if this really matters though since it is already pretty random
# where whitespace ends up.
if !prev_kid_ends_with_ws
kids′ = kids′ === kids ? kids[1:(i - 1)] : kids′
kid= kid
if !prev_kid_ends_with_ws && (
kind(kid) === K"Comment" ||
(fl = first_leaf(kid); fl !== nothing && kind(fl) === K"Comment")
)
@assert !prev_kid_ends_with_ws
kids′ = kids′ === kids ? kids[1:(i - 1)] : kids′
replace_bytes!(ctx, " ", 0)
if kind(kid) === K"Comment"
push!(kids′, ws)
replace_bytes!(ctx, " ", 0)
accept_node!(ctx, ws)
else
@assert (fl = first_leaf(kid); fl !== nothing && kind(fl) === K"Comment")
# When the comment is found within the kid the whitespace is added right
# before the comment inside of the kid instead of in this outer context.
# This does not necessarily match how JuliaSyntax would have parsed it, but
# seems to work better than the alternative.
kid′ = add_before_first_leaf(kid, ws)
@assert span(kid′) == span(kid) + 1
end
end
if kids′ !== kids
push!(kids′, kid)
push!(kids′, kid)
end
accept_node!(ctx, kid)
prev_kid_ends_with_ws = kind(kid) in KSet"Whitespace NewlineWs" ||
(ll = last_leaf(kid); ll !== nothing && kind(ll) in KSet"Whitespace NewlineWs")
accept_node!(ctx, kid)
prev_kid_ends_with_ws = kind(kid) in KSet"Whitespace NewlineWs" ||
(ll = last_leaf(kid); ll !== nothing && kind(ll) in KSet"Whitespace NewlineWs")
end
# Reset the stream and return
seek(ctx.fmt_io, pos)
Expand Down
3 changes: 2 additions & 1 deletion test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -83,9 +83,10 @@ end
@test format_string("1 + 1$(sp)# comment") == "1 + 1$(csp)# comment"
@test format_string("(a,$(sp)# comment\nb)") ==
"(\n a,$(csp)# comment\n b,\n)"
# Edgecase where the comment ends up as the first leaf inside the call
# Edgecases where the comment ends up as the first leaf inside a node
@test format_string("(a,$(sp)# comment\nb + b)") ==
"(\n a,$(csp)# comment\n b + b,\n)"
@test format_string("if c$(sp)# a\n b\nend") == "if c$(csp)# a\n b\nend"
end
let str = "a = 1 # a comment\nab = 2 # ab comment\n"
@test format_string(str) == str
Expand Down

0 comments on commit 3bc939e

Please sign in to comment.