node_mutation 1.18.2 → 1.19.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +15 -0
- data/Gemfile.lock +1 -1
- data/README.md +13 -0
- data/lib/node_mutation/action/indent_action.rb +2 -1
- data/lib/node_mutation/adapter/parser.rb +104 -21
- data/lib/node_mutation/adapter/syntax_tree.rb +72 -2
- data/lib/node_mutation/result.rb +4 -1
- data/lib/node_mutation/version.rb +1 -1
- data/lib/node_mutation.rb +2 -2
- data/sig/node_mutation/struct.rbs +8 -8
- data/sig/node_mutation.rbs +3 -3
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f0f3e24e2bcc4c8de744080aeccf3b82741534b6d5681c582d4ea91318b156b5
|
4
|
+
data.tar.gz: 33a39316e45592619c5ad3d520c6cb42411e41b6704bc1c52d840e0414c46322
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0064ba628586533f3687a2af1cdbfbd0af32a274bc127e7da97d72c5b4d7517c1f0a8658fba363762ede790b3ee1071fed6b702e75932f5e57719ff0a6f7c023
|
7
|
+
data.tar.gz: 231809db15865e3c260b2aa67edf5335968968299b5e5135571a12631bb90ed563fdd1a9cd59996d909acee42b4770b1ca98c58734fcee26ea1255a2eb525371
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,20 @@
|
|
1
1
|
# NodeMutation
|
2
2
|
|
3
|
+
## 1.19.0 (2023-06-22)
|
4
|
+
|
5
|
+
* Drop support for function in `child_node_by_name`
|
6
|
+
* Add `to_symbol` function
|
7
|
+
* Add `to_single_quote` function
|
8
|
+
* Add `to_double_quote` function
|
9
|
+
* Add `to_lambda_literal` function
|
10
|
+
* Add `strip_curly_braces` function
|
11
|
+
* Add `wrap_curly_braces` function
|
12
|
+
* Add more comments
|
13
|
+
|
14
|
+
## 1.18.3 (2023-06-03)
|
15
|
+
|
16
|
+
* Fix rbs syntax
|
17
|
+
|
3
18
|
## 1.18.2 (2023-05-21)
|
4
19
|
|
5
20
|
* Use `rindex` to calculate "do" index
|
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -65,6 +65,19 @@ result.conflicted
|
|
65
65
|
result.new_source
|
66
66
|
```
|
67
67
|
|
68
|
+
## Evaluated Value
|
69
|
+
|
70
|
+
NodeMutation supports to evaluate the value of the node, and use the evaluated value to rewrite the source code.
|
71
|
+
|
72
|
+
```ruby
|
73
|
+
source = 'after_commit :do_index, on: :create, if: :indexable?'
|
74
|
+
node = Parser::CurrentRuby.parse(source)
|
75
|
+
mutation.replace node, '{{arguments.-1.on_value}}', with: ':update'
|
76
|
+
source # after_commit :do_index, on: :update, if: :indexable?
|
77
|
+
```
|
78
|
+
|
79
|
+
See more in [ParserAdapter](https://xinminlabs.github.io/node-mutation-ruby/NodeMutation/ParserAdapter.html) and [SyntaxTreeAdapter](https://xinminlabs.github.io/node-mutation-ruby/NodeMutation/SyntaxTreeAdapter.html)
|
80
|
+
|
68
81
|
## Configuration
|
69
82
|
|
70
83
|
### adapter
|
@@ -17,7 +17,8 @@ class NodeMutation::IndentAction < NodeMutation::Action
|
|
17
17
|
# @return [String] rewritten code.
|
18
18
|
def new_code
|
19
19
|
source = NodeMutation.adapter.get_source(@node)
|
20
|
-
source.each_line.map { |line| ' ' * NodeMutation.tab_width * @tab_size + line }
|
20
|
+
source.each_line.map { |line| (' ' * NodeMutation.tab_width * @tab_size) + line }
|
21
|
+
.join
|
21
22
|
end
|
22
23
|
|
23
24
|
private
|
@@ -15,6 +15,49 @@ class NodeMutation::ParserAdapter < NodeMutation::Adapter
|
|
15
15
|
end
|
16
16
|
end
|
17
17
|
|
18
|
+
# It gets the new source code after evaluating the node.
|
19
|
+
# @param node [Parser::AST::Node] The node to evaluate.
|
20
|
+
# @param code [String] The code to evaluate.
|
21
|
+
# @return [String] The new source code.
|
22
|
+
# @example
|
23
|
+
# node = Parser::CurrentRuby.parse('Factory.define :user do; end')
|
24
|
+
# rewritten_source(node, '{{call.receiver}}').to eq 'Factory'
|
25
|
+
#
|
26
|
+
# # index for node array
|
27
|
+
# node = Parser::CurrentRuby.parse("test(foo, bar)")
|
28
|
+
# rewritten_source(node, '{{arguments.0}}')).to eq 'foo'
|
29
|
+
#
|
30
|
+
# # {key}_pair for hash node
|
31
|
+
# node = Parser::CurrentRuby.parse("after_commit :do_index, on: :create, if: :indexable?")
|
32
|
+
# rewritten_source(node, '{{arguments.-1.on_pair}}')).to eq 'on: :create'
|
33
|
+
#
|
34
|
+
# # {key}_value for hash node
|
35
|
+
# node = Parser::CurrentRuby.parse("after_commit :do_index, on: :create, if: :indexable?")
|
36
|
+
# rewritten_source(node, '{{arguments.-1.on_value}}')).to eq ':create'
|
37
|
+
#
|
38
|
+
# # to_single_quote for str node
|
39
|
+
# node = Parser::CurrentRuby.parse('"foo"')
|
40
|
+
# rewritten_source(node, 'to_single_quote') => "'foo'"
|
41
|
+
#
|
42
|
+
# # to_double_quote for str node
|
43
|
+
# node = Parser::CurrentRuby.parse("'foo'")
|
44
|
+
# rewritten_source(node, 'to_double_quote') => '"foo"'
|
45
|
+
#
|
46
|
+
# # to_symbol for str node
|
47
|
+
# node = Parser::CurrentRuby.parse("'foo'")
|
48
|
+
# rewritten_source(node, 'to_symbol') => ':foo'
|
49
|
+
#
|
50
|
+
# # to_lambda_literal for block node
|
51
|
+
# node = Parser::CurrentRuby.parse('lambda { foobar }')
|
52
|
+
# rewritten_source(node, 'to_lambda_literal') => '-> { foobar }'
|
53
|
+
#
|
54
|
+
# # strip_curly_braces for hash node
|
55
|
+
# node = Parser::CurrentRuby.parse("{ foo: 'bar' }")
|
56
|
+
# rewritten_source(node, 'strip_curly_braces') => "foo: 'bar'"
|
57
|
+
#
|
58
|
+
# # wrap_curly_braces for hash node
|
59
|
+
# node = Parser::CurrentRuby.parse("test(foo: 'bar')")
|
60
|
+
# rewritten_source(node.arguments.first, 'wrap_curly_braces') => "{ foo: 'bar' }"
|
18
61
|
def rewritten_source(node, code)
|
19
62
|
code.gsub(/{{(.+?)}}/m) do
|
20
63
|
old_code = Regexp.last_match(1)
|
@@ -56,6 +99,46 @@ class NodeMutation::ParserAdapter < NodeMutation::Adapter
|
|
56
99
|
node.loc.expression.source_buffer.source
|
57
100
|
end
|
58
101
|
|
102
|
+
# Get the range of the child node.
|
103
|
+
# @param node [Parser::AST::Node] The node.
|
104
|
+
# @param child_name [String] THe name to find child node.
|
105
|
+
# @return {NodeMutation::Struct::Range} The range of the child node.
|
106
|
+
# @example
|
107
|
+
# node = Parser::CurrentRuby.parse('Factory.define :user do; end')
|
108
|
+
# child_node_range(node, 'caller.receiver') => { start: 0, end: 'Factory'.length }
|
109
|
+
#
|
110
|
+
# # node array
|
111
|
+
# node = Parser::CurrentRuby.parse('foobar arg1, arg2)')
|
112
|
+
# child_node_range(node, 'arguments') => { start: 'foobar '.length, end: 'foobar arg1, arg2'.length }
|
113
|
+
#
|
114
|
+
# # index for node array
|
115
|
+
# node = Parser::CurrentRuby.parse('foobar(arg1, arg2)')
|
116
|
+
# child_node_range(node, 'arguments.-1') => { start: 'foobar(arg1, '.length, end: 'foobar(arg1, arg2'.length }
|
117
|
+
#
|
118
|
+
# # pips for block node
|
119
|
+
# node = Parser::CurrentRuby.parse('Factory.define :user do |user|; end')
|
120
|
+
# child_node_range(node, 'pipes') => { start: 'Factory.deine :user do '.length, end: 'Factory.define :user do |user|'.length }
|
121
|
+
#
|
122
|
+
# # parentheses for def and defs node
|
123
|
+
# node = Parser::CurrentRuby.parse('def foo(bar); end')
|
124
|
+
# child_node_range(node, 'parentheses') => { start: 'def foo'.length, end: 'def foo(bar)'.length }
|
125
|
+
#
|
126
|
+
# # double_colon for const node
|
127
|
+
# node = Parser::CurrentRuby.parse('Foo::Bar')
|
128
|
+
# child_node_range(node, 'double_colon') => { start: 'Foo'.length, end: 'Foo::'.length }
|
129
|
+
#
|
130
|
+
# # self and dot for defs node
|
131
|
+
# node = Parser::CurrentRuby.parse('def self.foo(bar); end')
|
132
|
+
# child_node_range(node, 'self') => { start: 'def '.length, end: 'def self'.length }
|
133
|
+
# child_node_range(node, 'dot') => { start: 'def self'.length, end: 'def self.'.length }
|
134
|
+
#
|
135
|
+
# # dot for send and csend node
|
136
|
+
# node = Parser::CurrentRuby.parse('foo.bar(test)')
|
137
|
+
# child_node_range(node, 'self') => { start: 'foo'.length, end: 'foo.'.length }
|
138
|
+
#
|
139
|
+
# # parentheses for send and csend node
|
140
|
+
# node = Parser::CurrentRuby.parse('foo.bar(test)')
|
141
|
+
# child_node_range(node, 'parentheses') => { start: 'foo.bar'.length, end: 'foo.bar(test)'.length }
|
59
142
|
def child_node_range(node, child_name)
|
60
143
|
direct_child_name, nested_child_name = child_name.to_s.split('.', 2)
|
61
144
|
|
@@ -88,25 +171,8 @@ class NodeMutation::ParserAdapter < NodeMutation::Adapter
|
|
88
171
|
node.arguments.last.loc.expression.end_pos + 1
|
89
172
|
)
|
90
173
|
end
|
91
|
-
when %i[
|
92
|
-
|
93
|
-
nil
|
94
|
-
else
|
95
|
-
NodeMutation::Struct::Range.new(
|
96
|
-
node.arguments.first.loc.expression.begin_pos,
|
97
|
-
node.arguments.last.loc.expression.end_pos
|
98
|
-
)
|
99
|
-
end
|
100
|
-
when %i[block body], %i[class body], %i[def body], %i[defs body], %i[module body]
|
101
|
-
if node.body.empty?
|
102
|
-
nil
|
103
|
-
else
|
104
|
-
NodeMutation::Struct::Range.new(
|
105
|
-
node.body.first.loc.expression.begin_pos,
|
106
|
-
node.body.last.loc.expression.end_pos
|
107
|
-
)
|
108
|
-
end
|
109
|
-
when %i[class name], %i[const name], %i[cvar name], %i[def name], %i[defs name], %i[gvar name], %i[ivar name], %i[lvar name]
|
174
|
+
when %i[class name], %i[const name], %i[cvar name], %i[def name], %i[defs name],
|
175
|
+
%i[gvar name], %i[ivar name], %i[lvar name]
|
110
176
|
NodeMutation::Struct::Range.new(node.loc.name.begin_pos, node.loc.name.end_pos)
|
111
177
|
when %i[const double_colon]
|
112
178
|
NodeMutation::Struct::Range.new(node.loc.double_colon.begin_pos, node.loc.double_colon.end_pos)
|
@@ -208,8 +274,25 @@ class NodeMutation::ParserAdapter < NodeMutation::Adapter
|
|
208
274
|
|
209
275
|
if node.respond_to?(direct_child_name)
|
210
276
|
child_node = node.send(direct_child_name)
|
211
|
-
elsif direct_child_name
|
212
|
-
child_node = node.
|
277
|
+
elsif direct_child_name == 'to_symbol' && node.type == :str
|
278
|
+
child_node = ":#{node.to_value}"
|
279
|
+
elsif direct_child_name == 'to_single_quote' && node.type == :str
|
280
|
+
child_node = "'#{node.to_value}'"
|
281
|
+
elsif direct_child_name == 'to_double_quote' && node.type == :str
|
282
|
+
child_node = "\"#{node.to_value}\""
|
283
|
+
elsif direct_child_name == 'to_lambda_literal' && node.type == :block && node.caller.type == :send && node.caller.receiver.nil? && node.caller.message == :lambda
|
284
|
+
new_source = node.to_source
|
285
|
+
if node.arguments.size > 1
|
286
|
+
new_source = new_source[0...node.arguments.first.loc.expression.begin_pos - 2] + new_source[node.arguments.last.loc.expression.end_pos + 1..-1]
|
287
|
+
new_source = new_source.sub('lambda', "->(#{node.arguments.map(&:to_source).join(', ')})")
|
288
|
+
else
|
289
|
+
new_source = new_source.sub('lambda', '->')
|
290
|
+
end
|
291
|
+
child_node = new_source
|
292
|
+
elsif direct_child_name == 'strip_curly_braces' && node.type == :hash
|
293
|
+
child_node = node.to_source.sub(/^{(.*)}$/) { Regexp.last_match(1).strip }
|
294
|
+
elsif direct_child_name == 'wrap_curly_braces' && node.type == :hash
|
295
|
+
child_node = "{ #{node.to_source} }"
|
213
296
|
else
|
214
297
|
raise NodeMutation::MethodNotSupported, "#{direct_child_name} is not supported for #{get_source(node)}"
|
215
298
|
end
|
@@ -12,6 +12,49 @@ class NodeMutation::SyntaxTreeAdapter < NodeMutation::Adapter
|
|
12
12
|
node.source[node.location.start_char...node.location.end_char]
|
13
13
|
end
|
14
14
|
|
15
|
+
# It gets the new source code after evaluating the node.
|
16
|
+
# @param node [SyntaxTree::Node] The node to evaluate.
|
17
|
+
# @param code [String] The code to evaluate.
|
18
|
+
# @return [String] The new source code.
|
19
|
+
# @example
|
20
|
+
# node = SyntaxTree::Parser.new('class Synvert; end').parse.statements.body.first
|
21
|
+
# rewritten_source(node, '{{constant}}').to eq 'Synvert'
|
22
|
+
#
|
23
|
+
# # index for node array
|
24
|
+
# node = SyntaxTree::Parser.new("foo.bar(a, b)").parse.statements.body.first
|
25
|
+
# rewritten_source(node, '{{arguments.arguments.parts.-1}}')).to eq 'b'
|
26
|
+
#
|
27
|
+
# # {key}_assoc for HashLiteral node
|
28
|
+
# node = SyntaxTree::Parser.new("after_commit :do_index, on: :create, if: :indexable?").parse.statements.body.first
|
29
|
+
# rewritten_source(node, '{{arguments.parts.-1.on_assoc}}')).to eq 'on: :create'
|
30
|
+
#
|
31
|
+
# # {key}_value for hash node
|
32
|
+
# node = SyntaxTree::Parser.new("after_commit :do_index, on: :create, if: :indexable?").parse.statements.body.first
|
33
|
+
# rewritten_source(node, '{{arguments.parts.-1.on_value}}')).to eq ':create'
|
34
|
+
#
|
35
|
+
# # to_single_quote for StringLiteral node
|
36
|
+
# node = SyntaxTree::Parser.new('"foo"').parse.statements.body.first
|
37
|
+
# rewritten_source(node, 'to_single_quote') => "'foo'"
|
38
|
+
#
|
39
|
+
# # to_double_quote for StringLiteral node
|
40
|
+
# node = SyntaxTree::Parser.new("'foo'").parse.statements.body.first
|
41
|
+
# rewritten_source(node, 'to_double_quote') => '"foo"'
|
42
|
+
#
|
43
|
+
# # to_symbol for StringLiteral node
|
44
|
+
# node = SyntaxTree::Parser.new("'foo'").parse.statements.body.first
|
45
|
+
# rewritten_source(node, 'to_symbol') => ':foo'
|
46
|
+
#
|
47
|
+
# # to_lambda_literal for MethodAddBlock node
|
48
|
+
# node = SyntaxTree::Parser.new('lambda { foobar }').parse.statements.body.first
|
49
|
+
# rewritten_source(node, 'to_lambda_literal') => '-> { foobar }'
|
50
|
+
#
|
51
|
+
# # strip_curly_braces for HashLiteral node
|
52
|
+
# node = SyntaxTree::Parser.new("{ foo: 'bar' }").parse.statements.body.first
|
53
|
+
# rewritten_source(node, 'strip_curly_braces') => "foo: 'bar'"
|
54
|
+
#
|
55
|
+
# # wrap_curly_braces for BareAssocHash node
|
56
|
+
# node = SyntaxTree::Parser.new("test(foo: 'bar')").parse.statements.body.first
|
57
|
+
# rewritten_source(node.arguments.arguments.parts.first, 'wrap_curly_braces') => "{ foo: 'bar' }"
|
15
58
|
def rewritten_source(node, code)
|
16
59
|
code.gsub(/{{(.+?)}}/m) do
|
17
60
|
old_code = Regexp.last_match(1)
|
@@ -48,6 +91,19 @@ class NodeMutation::SyntaxTreeAdapter < NodeMutation::Adapter
|
|
48
91
|
node.source
|
49
92
|
end
|
50
93
|
|
94
|
+
# Get the range of the child node.
|
95
|
+
# @param node [Parser::AST::Node] The node.
|
96
|
+
# @param child_name [String] THe name to find child node.
|
97
|
+
# @return {NodeMutation::Struct::Range} The range of the child node.
|
98
|
+
# @example
|
99
|
+
# node = SyntaxTree::Parser.new('foo.bar(test)').parse.statements.body.first
|
100
|
+
# child_node_range(node, 'receiver') => { start: 0, end: 'foo'.length }
|
101
|
+
# node array
|
102
|
+
# node = SyntaxTree::Parser.new('foo.bar(a, b)').parse.statements.body.first
|
103
|
+
# child_node_range(node, 'arguments.arguments') => { start: 'foo.bar('.length, end: 'foo.bar(a, b'.length }
|
104
|
+
# index for node array
|
105
|
+
# node = SyntaxTree::Parser.new('foo.bar(a, b)').parse.statements.body.first
|
106
|
+
# child_node_range(node, 'arguments.arguments.parts.-1') => { start: 'foo.bar(a, '.length, end: 'foo.bar(a, b'.length }
|
51
107
|
def child_node_range(node, child_name)
|
52
108
|
child_node = child_node_by_name(node, child_name)
|
53
109
|
return nil if child_node.nil?
|
@@ -109,8 +165,22 @@ class NodeMutation::SyntaxTreeAdapter < NodeMutation::Adapter
|
|
109
165
|
|
110
166
|
if node.respond_to?(direct_child_name)
|
111
167
|
child_node = node.send(direct_child_name)
|
112
|
-
elsif direct_child_name
|
113
|
-
child_node = node.
|
168
|
+
elsif direct_child_name == 'to_symbol' && node.is_a?(SyntaxTree::StringLiteral)
|
169
|
+
child_node = ":#{node.to_value}"
|
170
|
+
elsif direct_child_name == 'to_single_quote' && node.is_a?(SyntaxTree::StringLiteral)
|
171
|
+
child_node = "'#{node.to_value}'"
|
172
|
+
elsif direct_child_name == 'to_double_quote' && node.is_a?(SyntaxTree::StringLiteral)
|
173
|
+
child_node = "\"#{node.to_value}\""
|
174
|
+
elsif direct_child_name == 'to_lambda_literal' && node.is_a?(SyntaxTree::MethodAddBlock) && node.call.message.value == 'lambda'
|
175
|
+
if node.block.block_var
|
176
|
+
child_node = "->(#{node.block.block_var.params.to_source}) {#{node.block.bodystmt.to_source}}"
|
177
|
+
else
|
178
|
+
child_node = "-> {#{node.block.bodystmt.to_source }}"
|
179
|
+
end
|
180
|
+
elsif direct_child_name == 'strip_curly_braces' && node.is_a?(SyntaxTree::HashLiteral)
|
181
|
+
child_node = node.to_source.sub(/^{(.*)}$/) { Regexp.last_match(1).strip }
|
182
|
+
elsif direct_child_name == 'wrap_curly_braces' && node.is_a?(SyntaxTree::BareAssocHash)
|
183
|
+
child_node = "{ #{node.to_source} }"
|
114
184
|
else
|
115
185
|
raise NodeMutation::MethodNotSupported, "#{direct_child_name} is not supported for #{get_source(node)}"
|
116
186
|
end
|
data/lib/node_mutation/result.rb
CHANGED
@@ -19,7 +19,10 @@ class NodeMutation::Result
|
|
19
19
|
end
|
20
20
|
|
21
21
|
def actions=(actions)
|
22
|
-
@actions =
|
22
|
+
@actions =
|
23
|
+
actions.map { |action|
|
24
|
+
NodeMutation::Struct::Action.new(action.type, action.start, action.end, action.new_code)
|
25
|
+
}
|
23
26
|
end
|
24
27
|
|
25
28
|
def to_json(*args)
|
data/lib/node_mutation.rb
CHANGED
@@ -208,8 +208,8 @@ class NodeMutation
|
|
208
208
|
def wrap(node, prefix:, suffix:, newline: false)
|
209
209
|
if newline
|
210
210
|
indentation = NodeMutation.adapter.get_start_loc(node).column
|
211
|
-
@actions << InsertAction.new(node, prefix + "\n" + ' ' * indentation, at: 'beginning').process
|
212
|
-
@actions << InsertAction.new(node, "\n" + ' ' * indentation + suffix, at: 'end').process
|
211
|
+
@actions << InsertAction.new(node, prefix + "\n" + (' ' * indentation), at: 'beginning').process
|
212
|
+
@actions << InsertAction.new(node, "\n" + (' ' * indentation) + suffix, at: 'end').process
|
213
213
|
@actions << IndentAction.new(node).process
|
214
214
|
else
|
215
215
|
@actions << InsertAction.new(node, prefix, at: 'beginning').process
|
@@ -1,18 +1,18 @@
|
|
1
1
|
class NodeMutation::Struct
|
2
2
|
class Action < ::Struct
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
3
|
+
atr_accessor type (): Symbol
|
4
|
+
atr_accessor start (): Integer
|
5
|
+
atr_accessor end (): Integer
|
6
|
+
atr_accessor new_code (): String
|
7
7
|
end
|
8
8
|
|
9
9
|
class Location < ::Struct
|
10
|
-
|
11
|
-
|
10
|
+
atr_accessor line (): Integer
|
11
|
+
atr_accessor column (): Integer
|
12
12
|
end
|
13
13
|
|
14
14
|
class Range < ::Struct
|
15
|
-
|
16
|
-
|
15
|
+
atr_accessor start (): Integer
|
16
|
+
atr_accessor end (): Integer
|
17
17
|
end
|
18
18
|
end
|
data/sig/node_mutation.rbs
CHANGED
@@ -21,7 +21,7 @@ module NodeMutation[T]
|
|
21
21
|
|
22
22
|
def append: (node: T, code: String) -> void
|
23
23
|
|
24
|
-
def delete: (node: T,
|
24
|
+
def delete: (node: T, selectors: Array[String], and_comma: bool) -> void
|
25
25
|
|
26
26
|
def indent: (node: T, ?tab_size: Integer) -> void
|
27
27
|
|
@@ -29,9 +29,9 @@ module NodeMutation[T]
|
|
29
29
|
|
30
30
|
def prepend: (node: T, code: String) -> void
|
31
31
|
|
32
|
-
def remove: (node: T,
|
32
|
+
def remove: (node: T, and_comma: bool) -> void
|
33
33
|
|
34
|
-
def replace: (node: T,
|
34
|
+
def replace: (node: T, selectors: Array[String], with: String) -> void
|
35
35
|
|
36
36
|
def replace_with: (node: T, code: String) -> void
|
37
37
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: node_mutation
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.19.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Richard Huang
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-
|
11
|
+
date: 2023-06-22 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: ast node mutation apis
|
14
14
|
email:
|
@@ -70,7 +70,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
70
70
|
- !ruby/object:Gem::Version
|
71
71
|
version: '0'
|
72
72
|
requirements: []
|
73
|
-
rubygems_version: 3.4.
|
73
|
+
rubygems_version: 3.4.13
|
74
74
|
signing_key:
|
75
75
|
specification_version: 4
|
76
76
|
summary: ast node mutation apis
|