Browse Source

Remove optional trailing commas

pull/53/head
Fredrik Ekre 1 year ago
parent
commit
13b6402a66
No known key found for this signature in database
GPG Key ID: DE82E6D5E364C0A2
  1. 2
      src/JuliaSyntax.jl
  2. 8
      src/Runic.jl
  3. 2
      src/debug.jl
  4. 4
      src/main.jl
  5. 30
      src/runestone.jl
  6. 32
      test/runtests.jl

2
src/JuliaSyntax.jl

@ -34,7 +34,7 @@ function _show_green_node(io, node, indent, pos, str, show_trivia)
posstr = "$(lpad(pos, 6)):$(rpad(pos + span(node) - 1, 6))" posstr = "$(lpad(pos, 6)):$(rpad(pos + span(node) - 1, 6))"
brackets = is_leaf(node) ? ("" => "") : ("[" => "]") brackets = is_leaf(node) ? ("" => "") : ("[" => "]")
line = string( line = string(
posstr, indent, brackets.first, JuliaSyntax.summary(head(node)), brackets.second, posstr, indent, brackets.first, JuliaSyntax.summary(head(node)), brackets.second
) )
if node.tags != 0 if node.tags != 0
line = string(rpad(line, 50), ' ', "tags: $(stringify_tags(node))") line = string(rpad(line, 50), ' ', "tags: $(stringify_tags(node))")

8
src/Runic.jl

@ -53,7 +53,7 @@ function Node(node::JuliaSyntax.GreenNode)
tags = 0 % TagType tags = 0 % TagType
return Node( return Node(
JuliaSyntax.head(node), JuliaSyntax.span(node), JuliaSyntax.head(node), JuliaSyntax.span(node),
map(Node, JuliaSyntax.children(node)), tags, map(Node, JuliaSyntax.children(node)), tags
) )
end end
@ -141,11 +141,11 @@ end
function Context( function Context(
src_str::String; assert::Bool = true, debug::Bool = false, verbose::Bool = debug, src_str::String; assert::Bool = true, debug::Bool = false, verbose::Bool = debug,
diff::Bool = false, check::Bool = false, quiet::Bool = false, filemode::Bool = true, diff::Bool = false, check::Bool = false, quiet::Bool = false, filemode::Bool = true
) )
src_io = IOBuffer(src_str) src_io = IOBuffer(src_str)
src_tree = Node( src_tree = Node(
JuliaSyntax.parseall(JuliaSyntax.GreenNode, src_str; ignore_warnings = true, version = v"2-"), JuliaSyntax.parseall(JuliaSyntax.GreenNode, src_str; ignore_warnings = true, version = v"2-")
) )
normalize_tree!(src_tree) normalize_tree!(src_tree)
fmt_io = IOBuffer() fmt_io = IOBuffer()
@ -171,7 +171,7 @@ function Context(
return Context( return Context(
src_str, src_tree, src_io, fmt_io, fmt_tree, quiet, verbose, assert, debug, check, src_str, src_tree, src_io, fmt_io, fmt_tree, quiet, verbose, assert, debug, check,
diff, filemode, indent_level, call_depth, format_on, prev_sibling, next_sibling, diff, filemode, indent_level, call_depth, format_on, prev_sibling, next_sibling,
lineage_kinds, lineage_kinds
) )
end end

2
src/debug.jl

@ -23,7 +23,7 @@ function Base.showerror(io::IO, err::AssertionError)
io, io,
"Runic.AssertionError: `", err.msg, "`. This is unexpected, " * "Runic.AssertionError: `", err.msg, "`. This is unexpected, " *
"please file an issue with a reproducible example at " * "please file an issue with a reproducible example at " *
"https://github.com/fredrikekre/Runic.jl/issues/new.", "https://github.com/fredrikekre/Runic.jl/issues/new."
) )
end end

4
src/main.jl

@ -39,7 +39,7 @@ function print_help()
io, """ io, """
`Runic.main` (typically invoked as `julia -m Runic`) formats Julia source `Runic.main` (typically invoked as `julia -m Runic`) formats Julia source
code using the Runic.jl formatter. code using the Runic.jl formatter.
""", """
) )
printstyled(io, "OPTIONS\n", bold = true) printstyled(io, "OPTIONS\n", bold = true)
println( println(
@ -66,7 +66,7 @@ function print_help()
-o <file>, --output=<file> -o <file>, --output=<file>
File to write formatted output to. If no output is given, or if the file File to write formatted output to. If no output is given, or if the file
is `-`, output is written to stdout. is `-`, output is written to stdout.
""", """
) )
return return
end end

30
src/runestone.jl

@ -331,7 +331,7 @@ function spaces_in_listlike(ctx::Context, node::Node)
n_items = count( n_items = count(
x -> !(JuliaSyntax.is_whitespace(x) || kind(x) in KSet", ;"), x -> !(JuliaSyntax.is_whitespace(x) || kind(x) in KSet", ;"),
@view(kids[(opening_leaf_idx + 1):(closing_leaf_idx - 1)]), @view(kids[(opening_leaf_idx + 1):(closing_leaf_idx - 1)])
) )
first_item_idx = findnext(x -> !(JuliaSyntax.is_whitespace(x) || kind(x) in KSet", ;"), kids, opening_leaf_idx + 1) first_item_idx = findnext(x -> !(JuliaSyntax.is_whitespace(x) || kind(x) in KSet", ;"), kids, opening_leaf_idx + 1)
if first_item_idx !== nothing && first_item_idx >= closing_leaf_idx if first_item_idx !== nothing && first_item_idx >= closing_leaf_idx
@ -380,7 +380,7 @@ function spaces_in_listlike(ctx::Context, node::Node)
require_trailing_comma = true require_trailing_comma = true
elseif n_items > 0 elseif n_items > 0
require_trailing_comma = any( require_trailing_comma = any(
x -> kind(x) === K"NewlineWs", @view(kids[(last_item_idx + 1):(closing_leaf_idx - 1)]), x -> kind(x) === K"NewlineWs", @view(kids[(last_item_idx + 1):(closing_leaf_idx - 1)])
) || has_newline_after_non_whitespace(kids[last_item_idx]) ) || has_newline_after_non_whitespace(kids[last_item_idx])
end end
@ -484,7 +484,7 @@ function spaces_in_listlike(ctx::Context, node::Node)
if kind(kid′) === K"parameters" && !require_trailing_comma && !is_named_tuple && if kind(kid′) === K"parameters" && !require_trailing_comma && !is_named_tuple &&
count( count(
x -> !(JuliaSyntax.is_whitespace(x) || kind(x) in KSet", ;"), x -> !(JuliaSyntax.is_whitespace(x) || kind(x) in KSet", ;"),
verified_kids(kid′), verified_kids(kid′)
) == 0 ) == 0
# If kid is K"parameters" without items and we don't want a trailing # If kid is K"parameters" without items and we don't want a trailing
# comma/semicolon we need to eat any whitespace kids (e.g. comments) # comma/semicolon we need to eat any whitespace kids (e.g. comments)
@ -545,7 +545,7 @@ function spaces_in_listlike(ctx::Context, node::Node)
# - there is a comma coming but it is on the next line (weird) # - there is a comma coming but it is on the next line (weird)
# - there is a comment with no space before it # - there is a comment with no space before it
next_non_ws_idx = findnext( next_non_ws_idx = findnext(
!JuliaSyntax.is_whitespace, @view(kids[1:(closing_leaf_idx - 1)]), i + 1, !JuliaSyntax.is_whitespace, @view(kids[1:(closing_leaf_idx - 1)]), i + 1
) )
next_kind = next_non_ws_idx === nothing ? nothing : kind(kids[next_non_ws_idx]) next_kind = next_non_ws_idx === nothing ? nothing : kind(kids[next_non_ws_idx])
# Insert a comma if there isn't one coming # Insert a comma if there isn't one coming
@ -597,7 +597,7 @@ function spaces_in_listlike(ctx::Context, node::Node)
if !require_trailing_comma && if !require_trailing_comma &&
count( count(
x -> !(JuliaSyntax.is_whitespace(x) || kind(x) in KSet", ;"), x -> !(JuliaSyntax.is_whitespace(x) || kind(x) in KSet", ;"),
verified_kids(kid′), verified_kids(kid′)
) == 0 ) == 0
# If kid is K"parameters" without items and we don't want a trailing # If kid is K"parameters" without items and we don't want a trailing
# comma/semicolon we need to eat any whitespace kids (e.g. comments) # comma/semicolon we need to eat any whitespace kids (e.g. comments)
@ -1378,7 +1378,7 @@ function replace_with_in(ctx::Context, node::Node)
# Construct the replacement # Construct the replacement
nb = replace_bytes!(ctx, "in", span(in_node)) nb = replace_bytes!(ctx, "in", span(in_node))
in_node′ = Node( in_node′ = Node(
JuliaSyntax.SyntaxHead(K"in", JuliaSyntax.TRIVIA_FLAG), nb, JuliaSyntax.SyntaxHead(K"in", JuliaSyntax.TRIVIA_FLAG), nb
) )
accept_node!(ctx, in_node′) accept_node!(ctx, in_node′)
kids′ = copy(kids) kids′ = copy(kids)
@ -1532,7 +1532,7 @@ function braces_around_where_rhs(ctx::Context, node::Node)
closing_brace = Node(JuliaSyntax.SyntaxHead(K"}", 0), 1) closing_brace = Node(JuliaSyntax.SyntaxHead(K"}", 0), 1)
rhs′ = Node( rhs′ = Node(
JuliaSyntax.SyntaxHead(K"braces", 0), JuliaSyntax.SyntaxHead(K"braces", 0),
[opening_brace, rhs, closing_brace], [opening_brace, rhs, closing_brace]
) )
push!(kids′, rhs′) push!(kids′, rhs′)
# Write the new node # Write the new node
@ -1871,7 +1871,7 @@ function indent_begin(ctx::Context, node::Node, block_kind = K"begin")
end end
function indent_block( function indent_block(
ctx::Context, node::Node; allow_empty::Bool = true, do_indent::Bool = true, ctx::Context, node::Node; allow_empty::Bool = true, do_indent::Bool = true
) )
@assert kind(node) === K"block" && !is_leaf(node) @assert kind(node) === K"block" && !is_leaf(node)
@assert !JuliaSyntax.has_flags(node, JuliaSyntax.PARENS_FLAG) @assert !JuliaSyntax.has_flags(node, JuliaSyntax.PARENS_FLAG)
@ -2117,7 +2117,7 @@ function indent_try(ctx::Context, node::Node)
# Check for the other one # Check for the other one
other_kind = kind(kids[catch_idx]) === K"catch" ? K"finally" : K"catch" other_kind = kind(kids[catch_idx]) === K"catch" ? K"finally" : K"catch"
finally_idx = findnext( finally_idx = findnext(
x -> kind(x) === other_kind, kids, something(else_idx, catch_idx) + 1, x -> kind(x) === other_kind, kids, something(else_idx, catch_idx) + 1
) )
if finally_idx !== nothing if finally_idx !== nothing
let p = position(ctx.fmt_io) let p = position(ctx.fmt_io)
@ -2134,7 +2134,7 @@ function indent_try(ctx::Context, node::Node)
end end
# Check for end # Check for end
end_idx = findnext( end_idx = findnext(
x -> kind(x) === K"end", kids, something(finally_idx, else_idx, catch_idx) + 1, x -> kind(x) === K"end", kids, something(finally_idx, else_idx, catch_idx) + 1
)::Int )::Int
@assert is_leaf(kids[end_idx]) && kind(kids[end_idx]) === K"end" @assert is_leaf(kids[end_idx]) && kind(kids[end_idx]) === K"end"
if !has_tag(kids[end_idx], TAG_DEDENT) if !has_tag(kids[end_idx], TAG_DEDENT)
@ -2252,7 +2252,7 @@ end
# TODO: I feel like this function can be removed. It is only used in `indent_op_call` # TODO: I feel like this function can be removed. It is only used in `indent_op_call`
function indent_newlines_between_indices( function indent_newlines_between_indices(
ctx::Context, node::Node, open_idx::Int, close_idx::Int; ctx::Context, node::Node, open_idx::Int, close_idx::Int;
indent_closing_token::Bool = false, indent_closing_token::Bool = false
) )
kids = verified_kids(node) kids = verified_kids(node)
any_kid_changed = false any_kid_changed = false
@ -2302,7 +2302,7 @@ end
# token as pre-dedent # token as pre-dedent
function indent_listlike( function indent_listlike(
ctx::Context, node::Node, open_idx::Int, close_idx::Int; ctx::Context, node::Node, open_idx::Int, close_idx::Int;
indent_closing_token::Bool = false, indent_closing_token::Bool = false
) )
kids = verified_kids(node) kids = verified_kids(node)
kids′ = kids kids′ = kids
@ -2574,7 +2574,7 @@ function indent_op_call(ctx::Context, node::Node)
first_operand_idx = findfirst(!JuliaSyntax.is_whitespace, kids)::Int first_operand_idx = findfirst(!JuliaSyntax.is_whitespace, kids)::Int
last_operand_idx = findlast(!JuliaSyntax.is_whitespace, kids)::Int last_operand_idx = findlast(!JuliaSyntax.is_whitespace, kids)::Int
return indent_newlines_between_indices( return indent_newlines_between_indices(
ctx, node, first_operand_idx, last_operand_idx; indent_closing_token = true, ctx, node, first_operand_idx, last_operand_idx; indent_closing_token = true
) )
end end
@ -2708,7 +2708,7 @@ end
# with a max_depth parameter. # with a max_depth parameter.
function continue_all_newlines( function continue_all_newlines(
ctx::Context, node::Node; skip_last::Bool = true, is_last::Bool = is_leaf(node), ctx::Context, node::Node; skip_last::Bool = true, is_last::Bool = is_leaf(node),
skip_first::Bool = true, is_first::Bool = true, skip_first::Bool = true, is_first::Bool = true
) )
# Not sure these need to arguments since they should always(?) be `true`. # Not sure these need to arguments since they should always(?) be `true`.
@assert skip_last @assert skip_last
@ -2733,7 +2733,7 @@ function continue_all_newlines(
for (i, kid) in pairs(kids) for (i, kid) in pairs(kids)
kid′ = continue_all_newlines( kid′ = continue_all_newlines(
ctx, kid; skip_last = skip_last, is_last = i == lastindex(kids), ctx, kid; skip_last = skip_last, is_last = i == lastindex(kids),
skip_first = skip_first, is_first = is_first && i == firstindex(kids), skip_first = skip_first, is_first = is_first && i == firstindex(kids)
) )
if kid′ !== nothing if kid′ !== nothing
kids[i] = kid′ kids[i] = kid′

32
test/runtests.jl

@ -109,7 +109,7 @@ end
abc′ = replace(abc, "E" => "e") abc′ = replace(abc, "E" => "e")
push!( push!(
test_cases, test_cases,
["1$(abc)", "01$(abc)", "01.$(abc)", "1.$(abc)", "1.000$(abc)", "01.00$(abc)"] => "1.0$(abc′)", ["1$(abc)", "01$(abc)", "01.$(abc)", "1.$(abc)", "1.000$(abc)", "01.00$(abc)"] => "1.0$(abc′)"
) )
end end
mod = Module() mod = Module()
@ -558,16 +558,16 @@ end
"if a\n x\nelseif b\n y\nend" "if a\n x\nelseif b\n y\nend"
# if-elseif-elseif-end # if-elseif-elseif-end
@test format_string( @test format_string(
"if a\n$(sp)x\n$(sp)elseif b\n$(sp)y\n$(sp)elseif c\n$(sp)z\n$(sp)end", "if a\n$(sp)x\n$(sp)elseif b\n$(sp)y\n$(sp)elseif c\n$(sp)z\n$(sp)end"
) == "if a\n x\nelseif b\n y\nelseif c\n z\nend" ) == "if a\n x\nelseif b\n y\nelseif c\n z\nend"
# if-elseif-else-end # if-elseif-else-end
@test format_string( @test format_string(
"if a\n$(sp)x\n$(sp)elseif b\n$(sp)y\n$(sp)else\n$(sp)z\n$(sp)end", "if a\n$(sp)x\n$(sp)elseif b\n$(sp)y\n$(sp)else\n$(sp)z\n$(sp)end"
) == "if a\n x\nelseif b\n y\nelse\n z\nend" ) == "if a\n x\nelseif b\n y\nelse\n z\nend"
# if-elseif-elseif-else-end # if-elseif-elseif-else-end
@test format_string( @test format_string(
"if a\n$(sp)x\n$(sp)elseif b\n$(sp)y\n$(sp)elseif " * "if a\n$(sp)x\n$(sp)elseif b\n$(sp)y\n$(sp)elseif " *
"c\n$(sp)z\n$(sp)else\n$(sp)u\n$(sp)end", "c\n$(sp)z\n$(sp)else\n$(sp)u\n$(sp)end"
) == "if a\n x\nelseif b\n y\nelseif c\n z\nelse\n u\nend" ) == "if a\n x\nelseif b\n y\nelseif c\n z\nelse\n u\nend"
# begin-end # begin-end
@test format_string("begin\n$(sp)x\n$(sp)end") == "begin\n x\nend" @test format_string("begin\n$(sp)x\n$(sp)end") == "begin\n x\nend"
@ -591,36 +591,36 @@ end
"try\n x\ncatch err\n y\nend" "try\n x\ncatch err\n y\nend"
# try-catch-finally-end # try-catch-finally-end
@test format_string( @test format_string(
"try\n$(sp)x\n$(sp)catch\n$(sp)y\n$(sp)finally\n$(sp)z\n$(sp)end", "try\n$(sp)x\n$(sp)catch\n$(sp)y\n$(sp)finally\n$(sp)z\n$(sp)end"
) == "try\n x\ncatch\n y\nfinally\n z\nend" ) == "try\n x\ncatch\n y\nfinally\n z\nend"
# try-catch(err)-finally-end # try-catch(err)-finally-end
@test format_string( @test format_string(
"try\n$(sp)x\n$(sp)catch err\n$(sp)y\n$(sp)finally\n$(sp)z\n$(sp)end", "try\n$(sp)x\n$(sp)catch err\n$(sp)y\n$(sp)finally\n$(sp)z\n$(sp)end"
) == "try\n x\ncatch err\n y\nfinally\n z\nend" ) == "try\n x\ncatch err\n y\nfinally\n z\nend"
# try-finally-catch-end (yes, this is allowed...) # try-finally-catch-end (yes, this is allowed...)
@test format_string( @test format_string(
"try\n$(sp)x\n$(sp)finally\n$(sp)y\n$(sp)catch\n$(sp)z\n$(sp)end", "try\n$(sp)x\n$(sp)finally\n$(sp)y\n$(sp)catch\n$(sp)z\n$(sp)end"
) == "try\n x\nfinally\n y\ncatch\n z\nend" ) == "try\n x\nfinally\n y\ncatch\n z\nend"
# try-finally-catch(err)-end # try-finally-catch(err)-end
@test format_string( @test format_string(
"try\n$(sp)x\n$(sp)finally\n$(sp)y\n$(sp)catch err\n$(sp)z\n$(sp)end", "try\n$(sp)x\n$(sp)finally\n$(sp)y\n$(sp)catch err\n$(sp)z\n$(sp)end"
) == "try\n x\nfinally\n y\ncatch err\n z\nend" ) == "try\n x\nfinally\n y\ncatch err\n z\nend"
if VERSION >= v"1.8" if VERSION >= v"1.8"
# try-catch-else-end # try-catch-else-end
@test format_string( @test format_string(
"try\n$(sp)x\n$(sp)catch\n$(sp)y\n$(sp)else\n$(sp)z\n$(sp)end", "try\n$(sp)x\n$(sp)catch\n$(sp)y\n$(sp)else\n$(sp)z\n$(sp)end"
) == "try\n x\ncatch\n y\nelse\n z\nend" ) == "try\n x\ncatch\n y\nelse\n z\nend"
# try-catch(err)-else-end # try-catch(err)-else-end
@test format_string( @test format_string(
"try\n$(sp)x\n$(sp)catch err\n$(sp)y\n$(sp)else\n$(sp)z\n$(sp)end", "try\n$(sp)x\n$(sp)catch err\n$(sp)y\n$(sp)else\n$(sp)z\n$(sp)end"
) == "try\n x\ncatch err\n y\nelse\n z\nend" ) == "try\n x\ncatch err\n y\nelse\n z\nend"
# try-catch-else-finally-end # try-catch-else-finally-end
@test format_string( @test format_string(
"try\n$(sp)x\n$(sp)catch\n$(sp)y\n$(sp)else\n$(sp)z\n$(sp)finally\n$(sp)z\n$(sp)end", "try\n$(sp)x\n$(sp)catch\n$(sp)y\n$(sp)else\n$(sp)z\n$(sp)finally\n$(sp)z\n$(sp)end"
) == "try\n x\ncatch\n y\nelse\n z\nfinally\n z\nend" ) == "try\n x\ncatch\n y\nelse\n z\nfinally\n z\nend"
# try-catch(err)-else-finally-end # try-catch(err)-else-finally-end
@test format_string( @test format_string(
"try\n$(sp)x\n$(sp)catch err\n$(sp)y\n$(sp)else\n$(sp)z\n$(sp)finally\n$(sp)z\n$(sp)end", "try\n$(sp)x\n$(sp)catch err\n$(sp)y\n$(sp)else\n$(sp)z\n$(sp)finally\n$(sp)z\n$(sp)end"
) == "try\n x\ncatch err\n y\nelse\n z\nfinally\n z\nend" ) == "try\n x\ncatch err\n y\nelse\n z\nfinally\n z\nend"
end end
# do-end # do-end
@ -1189,7 +1189,7 @@ end
@test format_string("$(prefix)\n$(body)\nend") == "$prefix\n$(bodyfmt)\nend" @test format_string("$(prefix)\n$(body)\nend") == "$prefix\n$(bodyfmt)\nend"
end end
@test format_string( @test format_string(
"if cond1\n$(body)\nelseif cond2\n$(body)\nelseif cond3\n$(body)\nelse\n$(body)\nend", "if cond1\n$(body)\nelseif cond2\n$(body)\nelseif cond3\n$(body)\nelse\n$(body)\nend"
) == ) ==
"if cond1\n$(bodyfmt)\nelseif cond2\n$(bodyfmt)\nelseif cond3\n$(bodyfmt)\nelse\n$(bodyfmt)\nend" "if cond1\n$(bodyfmt)\nelseif cond2\n$(bodyfmt)\nelseif cond3\n$(bodyfmt)\nelse\n$(bodyfmt)\nend"
@test format_string("try\n$(body)\ncatch\n$(body)\nend") == @test format_string("try\n$(body)\ncatch\n$(body)\nend") ==
@ -1242,7 +1242,7 @@ end
$on $on
1+1 1+1
end end
""", """
) == """ ) == """
function f() function f()
$off $off
@ -1259,7 +1259,7 @@ end
$bon $bon
1+1 1+1
end end
""", """
) == """ ) == """
function f() function f()
$off $off
@ -1275,7 +1275,7 @@ end
1+1 1+1
1+1 1+1
end end
""", """
) == """ ) == """
function f() function f()
$off $off

Loading…
Cancel
Save