Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit9a49f30

Browse files
committed
AddMutationVisitor#remove API to remove nodes from the tree
1 parent98f4a8b commit9a49f30

File tree

5 files changed

+92
-4
lines changed

5 files changed

+92
-4
lines changed

‎README.md

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -611,14 +611,17 @@ visitor.mutate("IfNode[predicate: Assign | OpAssign]") do |node|
611611
node.copy(predicate: predicate)
612612
end
613613

614-
source="if a = 1; end"
614+
# remove `do_more_work` method call node
615+
visitor.remove("SyntaxTree::VCall[value: SyntaxTree::Ident[value: 'do_more_work']]")
616+
617+
source="if a = 1; perform_work; do_more_work; end"
615618
program=SyntaxTree.parse(source)
616619

617620
SyntaxTree::Formatter.format(source, program)
618-
# => "if a = 1\nend\n"
621+
# => "if a = 1\n perform_work\n do_more_work\nend\n"
619622

620623
SyntaxTree::Formatter.format(source, program.accept(visitor))
621-
# => "if (a = 1)\nend\n"
624+
# => "if (a = 1)\n perform_work\nend\n"
622625
```
623626

624627
###WithScope

‎lib/syntax_tree/mutation_visitor.rb

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,11 @@ module SyntaxTree
44
# This visitor walks through the tree and copies each node as it is being
55
# visited. This is useful for mutating the tree before it is formatted.
66
classMutationVisitor <BasicVisitor
7-
attr_reader:mutations
7+
attr_reader:mutations,:removals
88

99
definitialize
1010
@mutations=[]
11+
@removals=[]
1112
end
1213

1314
# Create a new mutation based on the given query that will mutate the node
@@ -19,13 +20,23 @@ def mutate(query, &block)
1920
mutations <<[Pattern.new(query).compile,block]
2021
end
2122

23+
defremove(query)
24+
@removals <<Pattern.new(query).compile
25+
end
26+
2227
# This is the base visit method for each node in the tree. It first creates
2328
# a copy of the node using the visit_* methods defined below. Then it checks
2429
# each mutation in sequence and calls it if it finds a match.
2530
defvisit(node)
2631
returnunlessnode
2732
result=node.accept(self)
2833

34+
removals.eachdo |removal_pattern|
35+
ifremoval_pattern.call(result)
36+
returnRemovedNode.new(location:result.location)
37+
end
38+
end
39+
2940
mutations.eachdo |(pattern,mutation)|
3041
result=mutation.call(result)ifpattern.call(result)
3142
end

‎lib/syntax_tree/node.rb

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9324,6 +9324,48 @@ def ambiguous?(q)
93249324
end
93259325
end
93269326

9327+
# RemovedNode is a blank node used in places of nodes that have been removed.
9328+
classRemovedNode <Node
9329+
# [Array[ Comment | EmbDoc ]] the comments attached to this node
9330+
attr_reader:comments
9331+
9332+
definitialize(location:)
9333+
@location=location
9334+
@comments=[]
9335+
end
9336+
9337+
defaccept(visitor)
9338+
visitor.visit_removed_node(self)
9339+
end
9340+
9341+
defchild_nodes
9342+
[]
9343+
end
9344+
9345+
defcopy(location:self.location)
9346+
node=RemovedNode.new(
9347+
location:location
9348+
)
9349+
9350+
node.comments.concat(comments.map(&:copy))
9351+
9352+
node
9353+
end
9354+
9355+
aliasdeconstructchild_nodes
9356+
9357+
defdeconstruct_keys(_keys)
9358+
{location:location,comments:comments}
9359+
end
9360+
9361+
defformat(_q)
9362+
end
9363+
9364+
def ===(other)
9365+
other.is_a?(RemovedNode)
9366+
end
9367+
end
9368+
93279369
# RescueEx represents the list of exceptions being rescued in a rescue clause.
93289370
#
93299371
# begin

‎lib/syntax_tree/visitor.rb

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -320,6 +320,9 @@ class Visitor < BasicVisitor
320320
# Visit a RegexpLiteral node.
321321
aliasvisit_regexp_literalvisit_child_nodes
322322

323+
# Visit a RemovedNode node.
324+
aliasvisit_removed_nodevisit_child_nodes
325+
323326
# Visit a Rescue node.
324327
aliasvisit_rescuevisit_child_nodes
325328

‎test/mutation_test.rb

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,35 @@ def test_mutates_based_on_patterns
2121
assert_equal(expected,SyntaxTree::Formatter.format(source,program))
2222
end
2323

24+
deftest_removes_node
25+
source=<<~RUBY
26+
App.configure do |config|
27+
config.config_value_a = 1
28+
config.config_value_b = 2
29+
config.config_value_c = 2
30+
end
31+
RUBY
32+
33+
expected=<<~RUBY
34+
App.configure do |config|
35+
config.config_value_a = 1
36+
37+
config.config_value_c = 2
38+
end
39+
RUBY
40+
41+
mutation_visitor=SyntaxTree.mutationdo |mutation|
42+
mutation.remove("SyntaxTree::Assign[
43+
target: SyntaxTree::Field[
44+
name: SyntaxTree::Ident[value: 'config_value_b']
45+
],
46+
]")
47+
end
48+
49+
program=SyntaxTree.parse(source).accept(mutation_visitor)
50+
assert_equal(expected,SyntaxTree::Formatter.format(source,program))
51+
end
52+
2453
private
2554

2655
defbuild_mutation

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp