From b9fbbca5b8fafe5d5f31e24105648af15890c392 Mon Sep 17 00:00:00 2001 From: Fredrik Ekre Date: Thu, 30 May 2024 15:48:41 +0200 Subject: [PATCH] Add `make_node` utility function This patch adds the `make_node(node, children)` method which creates a new node with the same head as `node` but with replaced children. --- src/Runic.jl | 4 +--- src/chisels.jl | 9 +++++++-- src/runestone.jl | 22 +++++++--------------- 3 files changed, 15 insertions(+), 20 deletions(-) diff --git a/src/Runic.jl b/src/Runic.jl index 8676eed..ef3a708 100644 --- a/src/Runic.jl +++ b/src/Runic.jl @@ -106,7 +106,6 @@ function format_node_with_children!(ctx::Context, node::JuliaSyntax.GreenNode) # The new node parts. `children′` aliases `children` and only copied below if any of the # nodes change ("copy-on-write"). - head′ = JuliaSyntax.head(node) children = verified_children(node) children′ = children any_child_changed = false @@ -161,8 +160,7 @@ function format_node_with_children!(ctx::Context, node::JuliaSyntax.GreenNode) ctx.next_sibling = next_sibling # Return a new node if any of the children changed if any_child_changed - span′ = mapreduce(JuliaSyntax.span, +, children′; init = 0) - return JuliaSyntax.GreenNode(head′, span′, children′) + return make_node(node, children′) else return nothing end diff --git a/src/chisels.jl b/src/chisels.jl index bf916ff..f225f13 100644 --- a/src/chisels.jl +++ b/src/chisels.jl @@ -37,6 +37,12 @@ end # JuliaSyntax extensions # ########################## +# Create a new node with the same head but new children +function make_node(node::JuliaSyntax.GreenNode, children′::AbstractVector{<:JuliaSyntax.GreenNode}) + span′ = mapreduce(JuliaSyntax.span, +, children′; init = 0) + return JuliaSyntax.GreenNode(JuliaSyntax.head(node), span′, children′) +end + function is_leaf(node::JuliaSyntax.GreenNode) return !JuliaSyntax.haschildren(node) end @@ -69,8 +75,7 @@ function replace_first_leaf(node::JuliaSyntax.GreenNode, child′::JuliaSyntax.G children′ = copy(verified_children(node)) children′[1] = replace_first_leaf(children′[1], child′) @assert length(children′) > 0 - span′ = mapreduce(JuliaSyntax.span, +, children′; init = 0) - return JuliaSyntax.GreenNode(JuliaSyntax.head(node), span′, children′) + return make_node(node, children′) end end diff --git a/src/runestone.jl b/src/runestone.jl index 1e432e4..4b79b25 100644 --- a/src/runestone.jl +++ b/src/runestone.jl @@ -260,9 +260,7 @@ function spaces_around_x(ctx::Context, node::JuliaSyntax.GreenNode, is_x::F) whe seek(ctx.fmt_io, pos) if any_changes # Create new node and return it - span′ = mapreduce(JuliaSyntax.span, +, children′; init = 0) - node′ = JuliaSyntax.GreenNode(JuliaSyntax.head(node), span′, children′) - return node′ + return make_node(node, children′) else return nothing end @@ -339,9 +337,8 @@ function no_spaces_around_x(ctx::Context, node::JuliaSyntax.GreenNode, is_x::F) seek(ctx.fmt_io, pos) if any_changes # Create new node and return it - span′ = mapreduce(JuliaSyntax.span, +, children′; init = 0) - @assert span′ < JuliaSyntax.span(node) - node′ = JuliaSyntax.GreenNode(JuliaSyntax.head(node), span′, children′) + node′ = make_node(node, children′) + @assert JuliaSyntax.span(node′) < JuliaSyntax.span(node) return node′ else return nothing @@ -397,8 +394,7 @@ function replace_with_in(ctx::Context, node::JuliaSyntax.GreenNode) for i in (in_index + 1):length(children′) accept_node!(ctx, children′[i]) end - node′ = JuliaSyntax.GreenNode(JuliaSyntax.head(node), mapreduce(JuliaSyntax.span, +, children′; init = 0), children′) - return node′ + return make_node(node, children′) end function replace_with_in_cartesian(ctx::Context, node::JuliaSyntax.GreenNode) @@ -422,13 +418,10 @@ function replace_with_in_cartesian(ctx::Context, node::JuliaSyntax.GreenNode) accept_node!(ctx, child) end end - span′ = mapreduce(JuliaSyntax.span, +, children′; init = 0) if children === children′ - # No changes return nothing end - node′ = JuliaSyntax.GreenNode(JuliaSyntax.head(node), span′, children′) - return node′ + return make_node(node, children′) end # replace `=` and `∈` with `in` in for-loops @@ -472,9 +465,8 @@ function for_loop_use_in(ctx::Context, node::JuliaSyntax.GreenNode) accept_node!(ctx, children′[i]) end # Construct the full node and return - span′ = mapreduce(JuliaSyntax.span, +, children′; init = 0) - node′ = JuliaSyntax.GreenNode(JuliaSyntax.head(node), span′, children′) - @assert position(ctx.fmt_io) == pos + span′ + node′ = make_node(node, children′) + @assert position(ctx.fmt_io) == pos + JuliaSyntax.span(node′) seek(ctx.fmt_io, pos) # reset return node′ end