Browse Source

Fix insertion of space before comment

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.
pull/62/head
Fredrik Ekre 1 year ago
parent
commit
3bc939ec72
No known key found for this signature in database
GPG Key ID: DE82E6D5E364C0A2
  1. 15
      src/chisels.jl
  2. 35
      src/runestone.jl
  3. 3
      test/runtests.jl

15
src/chisels.jl

@ -423,6 +423,21 @@ function replace_last_leaf(node::Node, kid′::Union{Node, NullNode})
end end
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) function last_leaf(node::Node)
if is_leaf(node) if is_leaf(node)
return node return node

35
src/runestone.jl

@ -3372,26 +3372,33 @@ function spaces_around_comments(ctx::Context, node::Node)
prev_kid_ends_with_ws = true prev_kid_ends_with_ws = true
ws = Node(JuliaSyntax.SyntaxHead(K"Whitespace", JuliaSyntax.TRIVIA_FLAG), 1) ws = Node(JuliaSyntax.SyntaxHead(K"Whitespace", JuliaSyntax.TRIVIA_FLAG), 1)
for (i, kid) in pairs(kids) for (i, kid) in pairs(kids)
if kind(kid) === K"Comment" || kid′ = kid
(fl = first_leaf(kid); fl !== nothing && kind(fl) === K"Comment") if !prev_kid_ends_with_ws && (
# TODO: In the case where the comment is found within the kid the whitespace kind(kid) === K"Comment" ||
# should maybe be added right before the comment in the tree (which is how (fl = first_leaf(kid); fl !== nothing && kind(fl) === K"Comment")
# 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 @assert !prev_kid_ends_with_ws
# where whitespace ends up. kids′ = kids′ === kids ? kids[1:(i - 1)] : kids′
if !prev_kid_ends_with_ws replace_bytes!(ctx, " ", 0)
kids′ = kids′ === kids ? kids[1:(i - 1)] : kids′ if kind(kid) === K"Comment"
push!(kids′, ws) push!(kids′, ws)
replace_bytes!(ctx, " ", 0)
accept_node!(ctx, ws) 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
end end
if kids′ !== kids if kids′ !== kids
push!(kids′, kid) push!(kids′, kid)
end end
accept_node!(ctx, kid) accept_node!(ctx, kid)
prev_kid_ends_with_ws = kind(kid) in KSet"Whitespace NewlineWs" || prev_kid_ends_with_ws = kind(kid) in KSet"Whitespace NewlineWs" ||
(ll = last_leaf(kid); ll !== nothing && kind(ll) in KSet"Whitespace NewlineWs") (ll = last_leaf(kid); ll !== nothing && kind(ll) in KSet"Whitespace NewlineWs")
end end
# Reset the stream and return # Reset the stream and return
seek(ctx.fmt_io, pos) seek(ctx.fmt_io, pos)

3
test/runtests.jl

@ -83,9 +83,10 @@ end
@test format_string("1 + 1$(sp)# comment") == "1 + 1$(csp)# comment" @test format_string("1 + 1$(sp)# comment") == "1 + 1$(csp)# comment"
@test format_string("(a,$(sp)# comment\nb)") == @test format_string("(a,$(sp)# comment\nb)") ==
"(\n a,$(csp)# comment\n b,\n)" "(\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)") == @test format_string("(a,$(sp)# comment\nb + b)") ==
"(\n a,$(csp)# comment\n b + b,\n)" "(\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 end
let str = "a = 1 # a comment\nab = 2 # ab comment\n" let str = "a = 1 # a comment\nab = 2 # ab comment\n"
@test format_string(str) == str @test format_string(str) == str

Loading…
Cancel
Save