Browse Source

Fix formatting of mixed generator/cartesian nodes

pull/30/head
Fredrik Ekre 1 year ago
parent
commit
c76c60801f
No known key found for this signature in database
GPG Key ID: DE82E6D5E364C0A2
  1. 27
      src/runestone.jl
  2. 2
      test/runtests.jl

27
src/runestone.jl

@ -1374,10 +1374,10 @@ function spaces_around_keywords(ctx::Context, node::Node)
end end
# Replace the K"=" operator with `in` # Replace the K"=" operator with `in`
# TODO: This method doesn't reset the stream so callers should not accept_node??
function replace_with_in(ctx::Context, node::Node) function replace_with_in(ctx::Context, node::Node)
@assert kind(node) === K"=" && !is_leaf(node) && meta_nargs(node) == 3 @assert kind(node) === K"=" && !is_leaf(node) && meta_nargs(node) == 3
kids = verified_kids(node) kids = verified_kids(node)
pos = position(ctx.fmt_io)
vars_index = findfirst(!JuliaSyntax.is_whitespace, kids) vars_index = findfirst(!JuliaSyntax.is_whitespace, kids)
# TODO: Need to insert whitespaces around `in` when replacing e.g. `i=I` with `iinI`. # TODO: Need to insert whitespaces around `in` when replacing e.g. `i=I` with `iinI`.
# However, at the moment it looks like the whitespace around operator pass does it's # However, at the moment it looks like the whitespace around operator pass does it's
@ -1388,6 +1388,7 @@ function replace_with_in(ctx::Context, node::Node)
if kind(in_node) === K"in" if kind(in_node) === K"in"
@assert JuliaSyntax.is_trivia(in_node) @assert JuliaSyntax.is_trivia(in_node)
@assert is_leaf(in_node) @assert is_leaf(in_node)
@assert position(ctx.fmt_io) == pos
return nothing return nothing
end end
@assert kind(in_node) in KSet"∈ =" @assert kind(in_node) in KSet"∈ ="
@ -1405,10 +1406,7 @@ function replace_with_in(ctx::Context, node::Node)
accept_node!(ctx, in_node′) accept_node!(ctx, in_node′)
kids′ = copy(kids) kids′ = copy(kids)
kids′[in_index] = in_node′ kids′[in_index] = in_node′
# Accept remaining kids seek(ctx.fmt_io, pos)
for i in (in_index + 1):length(kids′)
accept_node!(ctx, kids′[i])
end
return make_node(node, kids′) return make_node(node, kids′)
end end
@ -1426,22 +1424,22 @@ function replace_with_in_filter(ctx::Context, node::Node)
else else
kid′ = replace_with_in_cartesian(ctx, kid) kid′ = replace_with_in_cartesian(ctx, kid)
end end
if kid′ === nothing # Reset stream
seek(ctx.fmt_io, pos) seek(ctx.fmt_io, pos)
if kid′ === nothing
return nothing return nothing
end else
kids = copy(kids) kids = copy(kids)
kids[idx] = kid′ kids[idx] = kid′
for i in (idx + 1):length(kids)
accept_node!(ctx, kids[i])
end
return make_node(node, kids) return make_node(node, kids)
end end
end
function replace_with_in_cartesian(ctx::Context, node::Node) function replace_with_in_cartesian(ctx::Context, node::Node)
@assert kind(node) === K"cartesian_iterator" && !is_leaf(node) @assert kind(node) === K"cartesian_iterator" && !is_leaf(node)
kids = verified_kids(node) kids = verified_kids(node)
kids′ = kids kids′ = kids
pos = position(ctx.fmt_io)
for (i, kid) in pairs(kids) for (i, kid) in pairs(kids)
if kind(kid) === K"=" if kind(kid) === K"="
kid′ = replace_with_in(ctx, kid) kid′ = replace_with_in(ctx, kid)
@ -1450,6 +1448,7 @@ function replace_with_in_cartesian(ctx::Context, node::Node)
kids′ = copy(kids) kids′ = copy(kids)
end end
kids′[i] = kid′ kids′[i] = kid′
accept_node!(ctx, kid′)
else else
kids′[i] = kid kids′[i] = kid
accept_node!(ctx, kid) accept_node!(ctx, kid)
@ -1459,6 +1458,8 @@ function replace_with_in_cartesian(ctx::Context, node::Node)
accept_node!(ctx, kid) accept_node!(ctx, kid)
end end
end end
# Reset stream
seek(ctx.fmt_io, pos)
if kids === kids′ if kids === kids′
return nothing return nothing
end end
@ -1487,7 +1488,6 @@ function for_loop_use_in(ctx::Context, node::Node)
for i in next_index:for_index for i in next_index:for_index
accept_node!(ctx, kids[i]) accept_node!(ctx, kids[i])
end end
while_pos = position(ctx.fmt_io)
# The for loop specification node can be either K"=" or K"cartesian_iterator" # The for loop specification node can be either K"=" or K"cartesian_iterator"
for_spec_index = for_index + 1 for_spec_index = for_index + 1
for_spec_node = kids[for_spec_index] for_spec_node = kids[for_spec_index]
@ -1501,13 +1501,15 @@ function for_loop_use_in(ctx::Context, node::Node)
for_spec_node′ = replace_with_in_cartesian(ctx, for_spec_node) for_spec_node′ = replace_with_in_cartesian(ctx, for_spec_node)
end end
if for_spec_node′ !== nothing if for_spec_node′ !== nothing
@assert position(ctx.fmt_io) == while_pos + span(for_spec_node′)
any_for_changed = true any_for_changed = true
# Insert the new for spec node # Insert the new for spec node
if kids′ === kids if kids′ === kids
kids′ = copy(kids) kids′ = copy(kids)
end end
kids′[for_spec_index] = for_spec_node′ kids′[for_spec_index] = for_spec_node′
accept_node!(ctx, for_spec_node′)
else
accept_node!(ctx, for_spec_node)
end end
for_index = findnext(c -> kind(c) === K"for" && is_leaf(c), kids, for_spec_index + 1) for_index = findnext(c -> kind(c) === K"for" && is_leaf(c), kids, for_spec_index + 1)
if for_index !== nothing if for_index !== nothing
@ -1526,7 +1528,6 @@ function for_loop_use_in(ctx::Context, node::Node)
end end
# Construct the full node and return # Construct the full node and return
node′ = make_node(node, kids′) node′ = make_node(node, kids′)
@assert position(ctx.fmt_io) == pos + span(node′)
seek(ctx.fmt_io, pos) # reset seek(ctx.fmt_io, pos) # reset
return node′ return node′
end end

2
test/runtests.jl

@ -478,6 +478,8 @@ end
"$(l)(i, j) for i in I, j in J$(r)" "$(l)(i, j) for i in I, j in J$(r)"
@test format_string("$(l)(i, j, k) for i$(sp)$(op)$(sp)I, j$(sp)$(op)$(sp)J, k$(sp)$(op)$(sp)K$(r)") == @test format_string("$(l)(i, j, k) for i$(sp)$(op)$(sp)I, j$(sp)$(op)$(sp)J, k$(sp)$(op)$(sp)K$(r)") ==
"$(l)(i, j, k) for i in I, j in J, k in K$(r)" "$(l)(i, j, k) for i in I, j in J, k in K$(r)"
@test format_string("$(l)(i, j, k) for i$(sp)$(op)$(sp)I for j$(sp)$(op)$(sp)J, k$(sp)$(op)$(sp)K$(r)") ==
"$(l)(i, j, k) for i in I for j in J, k in K$(r)"
# multiple for # multiple for
@test format_string("$(l)(i, j) for i$(sp)$(op)$(sp)I for j$(sp)$(op)$(sp)J$(r)") == @test format_string("$(l)(i, j) for i$(sp)$(op)$(sp)I for j$(sp)$(op)$(sp)J$(r)") ==
"$(l)(i, j) for i in I for j in J$(r)" "$(l)(i, j) for i in I for j in J$(r)"

Loading…
Cancel
Save