Skip to content

Commit

Permalink
Ensure at least one space before comments
Browse files Browse the repository at this point in the history
Closes #51.
  • Loading branch information
fredrikekre committed Aug 29, 2024
1 parent a0a5dff commit 5d0983f
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 3 deletions.
1 change: 1 addition & 0 deletions src/Runic.jl
Original file line number Diff line number Diff line change
Expand Up @@ -432,6 +432,7 @@ function format_node!(ctx::Context, node::Node)::Union{Node, Nothing, NullNode}
@return_something spaces_around_keywords(ctx, node)
@return_something spaces_in_import_using(ctx, node)
@return_something spaces_in_export_public(ctx, node)
@return_something spaces_around_comments(ctx, node)
@return_something no_spaces_around_colon_etc(ctx, node)
@return_something parens_around_op_calls_in_colon(ctx, node)
@return_something for_loop_use_in(ctx, node)
Expand Down
40 changes: 40 additions & 0 deletions src/runestone.jl
Original file line number Diff line number Diff line change
Expand Up @@ -3355,3 +3355,43 @@ function remove_trailing_semicolon(ctx::Context, node::Node)
seek(ctx.fmt_io, pos)
return any_changed ? make_node(node, kids′) : nothing
end

function spaces_around_comments(ctx::Context, node::Node)
is_leaf(node) && return
pos = position(ctx.fmt_io)
kids = verified_kids(node)
kids′ = kids
# We assume that the previous node ends with ws, which should be true since the same
# pass here adds it if the first kid is a comment.
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′
push!(kids′, ws)
replace_bytes!(ctx, " ", 0)
accept_node!(ctx, ws)
end
end
if kids′ !== kids
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")
end
# Reset the stream and return
seek(ctx.fmt_io, pos)
if kids === kids′
return nothing
else
return make_node(node, kids′)
end
end
23 changes: 20 additions & 3 deletions test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,22 @@ end
format_string("# comment \t ") == format_string("# comment\t \t") == "# comment"
end

@testset "space before comment" begin
for sp in ("", " ", " ")
csp = sp == "" ? " " : sp
@test format_string("a$(sp)# comment") == "a$(csp)# comment"
@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
@test format_string("(a,$(sp)# comment\nb + b)") ==
"(\n a,$(csp)# comment\n b + b,\n)"
end
let str = "a = 1 # a comment\nab = 2 # ab comment\n"
@test format_string(str) == str
end
end

@testset "Hex/oct/bin literal integers" begin
z(n) = "0"^n
test_cases = [
Expand Down Expand Up @@ -193,6 +209,7 @@ end

@testset "spaces in listlike" begin
for sp in ("", " ", " "), a in ("a", "a + a", "a(x)"), b in ("b", "b + b", "b(y)")
csp = sp == "" ? " " : sp # at least one space before comment (but more allowed)
# tuple, call, dotcall, vect, ref
for (o, c) in (("(", ")"), ("f(", ")"), ("@f(", ")"), ("f.(", ")"), ("[", "]"), ("T[", "]"))
tr = o in ("f(", "@f(", "f.(") ? "" : ","
Expand Down Expand Up @@ -235,9 +252,9 @@ end
"$(o)\n $(a),\n $(b),\n$(c)"
# trailing comments
@test format_string("$(o)$(sp)# x\n$(sp)$(a)$(sp),$(sp)# a\n$(sp)$(b)$(sp)# b\n$(c)") ==
"$(o)\n # x\n $(a),$(sp)# a\n $(b)$(tr)$(sp)# b\n$(c)"
"$(o)\n # x\n $(a),$(csp)# a\n $(b)$(tr)$(csp)# b\n$(c)"
@test format_string("$(o)$(sp)# x\n$(sp)$(a)$(sp),$(sp)# a\n$(sp)$(b),$(sp)# b\n$(c)") ==
"$(o)\n # x\n $(a),$(sp)# a\n $(b),$(sp)# b\n$(c)"
"$(o)\n # x\n $(a),$(csp)# a\n $(b),$(csp)# b\n$(c)"
# comments on separate lines between items
@test format_string("$(o)\n# a\n$(a)$(sp),\n# b\n$(b)\n$(c)") ==
"$(o)\n # a\n $(a),\n # b\n $(b)$(tr)\n$(c)"
Expand All @@ -259,7 +276,7 @@ end
@test format_string("$(a)$(sp),\n$(sp)$(b)") == "$(a),\n $(b)"
# trailing comments
@test format_string("$(a)$(sp),$(sp)# a\n$(sp)$(b)$(sp)# b") ==
"$(a),$(sp)# a\n $(b)$(sp)# b"
"$(a),$(csp)# a\n $(b)$(csp)# b"
@test format_string("# a\n$(a)$(sp),\n# b\n$(b)") ==
"# a\n$(a),\n # b\n $(b)"
end
Expand Down

0 comments on commit 5d0983f

Please sign in to comment.