diff --git a/src/runestone.jl b/src/runestone.jl index c1b4956..00dbabc 100644 --- a/src/runestone.jl +++ b/src/runestone.jl @@ -308,6 +308,7 @@ function spaces_in_listlike(ctx::Context, node::Node) if opening_leaf_idx === nothing # Implicit tuple without (), for example arguments in a do-block implicit_tuple = true + @assert kind(node) === K"tuple" opening_leaf_idx = findfirst(!JuliaSyntax.is_whitespace, kids) if opening_leaf_idx === nothing # All whitespace... return? @@ -366,7 +367,13 @@ function spaces_in_listlike(ctx::Context, node::Node) if kind(node) in KSet"call dotcall macrocall" require_trailing_comma = false elseif implicit_tuple - require_trailing_comma = false + # Trailing commas in implicit tuples in the LHS of an assignment, e.g. `x, = 1, 2`, + # is required for single item tuples and allowed for multiple items (to allow e.g. + # `x, y, = z` signaling that z contains more items). + # Note that an implicit single item tuple can never(?) end up on the RHS so there is + # no need to make sure this is the LHS node. + require_trailing_comma = n_items == 1 && ctx.lineage_kinds[end] === K"=" + allow_trailing_comma = ctx.lineage_kinds[end] === K"=" elseif kind(node) === K"tuple" && n_items == 1 && ctx.lineage_kinds[end] !== K"function" && kind(kids[first_item_idx::Int]) !== K"parameters" # TODO: May also have to check for K"where" and K"::" in the lineage above diff --git a/test/runtests.jl b/test/runtests.jl index c32586d..a0943d4 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -824,6 +824,10 @@ end # implicit tuple @test format_string("a,\n$(sp)b") == "a,\n b" @test format_string("a,\n$(sp)b + \nb") == "a,\n b +\n b" + # implicit tuple in destructuring (LHS of K"=") + @test format_string("a,$(sp)=$(sp)z") == "a, = z" + @test format_string("a,$(sp)b$(sp)=$(sp)z") == "a, b = z" + @test format_string("a,$(sp)b$(sp),$(sp)=$(sp)z") == "a, b, = z" # K"cartesian_iterator" @test format_string("for i in I,\n$(sp)j in J\n# body\nend") == "for i in I,\n j in J\n # body\nend"