[ruby/yarp] Add Node#copy and MutationVisitor

https://github.com/ruby/yarp/commit/3693091661
This commit is contained in:
Kevin Newton 2023-08-25 09:57:39 -04:00 committed by git
parent 3b9085ad24
commit 649aba28f4
5 changed files with 31 additions and 0 deletions

View File

@ -507,6 +507,7 @@ module YARP
end
require_relative "yarp/lex_compat"
require_relative "yarp/mutation_visitor"
require_relative "yarp/node"
require_relative "yarp/ripper_compat"
require_relative "yarp/serialize"

View File

@ -61,6 +61,7 @@ Gem::Specification.new do |spec|
"lib/yarp.rb",
"lib/yarp/ffi.rb",
"lib/yarp/lex_compat.rb",
"lib/yarp/mutation_visitor.rb",
"lib/yarp/node.rb",
"lib/yarp/pack.rb",
"lib/yarp/ripper_compat.rb",

View File

@ -0,0 +1,19 @@
module YARP
# This visitor walks through the tree and copies each node as it is being
# visited. This is useful for consumers that want to mutate the tree, as you
# can change subtrees in place without effecting the rest of the tree.
class MutationVisitor < BasicVisitor
<%- nodes.each_with_index do |node, index| -%>
<%= "\n" if index != 0 -%>
# Copy a <%= node.name %> node
def visit_<%= node.human %>(node)
<%- params = node.params.select { |param| [NodeParam, OptionalNodeParam, NodeListParam].include?(param.class) } -%>
<%- if params.any? -%>
node.copy(<%= params.map { |param| "#{param.name}: visit(node.#{param.name})" }.join(", ") %>)
<%- else -%>
node.copy
<%- end -%>
end
<%- end -%>
end
end

View File

@ -48,6 +48,15 @@ module YARP
}.compact.join(", ") %>]
end
# def copy: (**params) -> <%= node.name %>
def copy(**params)
<%= node.name %>.new(
<%- (node.params.map(&:name) + ["location"]).map do |name| -%>
<%= name %>: params.fetch(:<%= name %>) { self.<%= name %> },
<%- end -%>
)
end
# def deconstruct: () -> Array[nil | Node]
alias deconstruct child_nodes

View File

@ -315,6 +315,7 @@ TEMPLATES = [
"java/org/yarp/Loader.java",
"java/org/yarp/Nodes.java",
"java/org/yarp/AbstractNodeVisitor.java",
"lib/yarp/mutation_visitor.rb",
"lib/yarp/node.rb",
"lib/yarp/serialize.rb",
"src/node.c",