node_mutation 1.21.6 → 1.22.1
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 +10 -0
- data/Gemfile.lock +1 -1
- data/README.md +1 -5
- data/lib/node_mutation/action/append_action.rb +9 -4
- data/lib/node_mutation/action/delete_action.rb +6 -5
- data/lib/node_mutation/action/group_action.rb +1 -0
- data/lib/node_mutation/action/indent_action.rb +6 -5
- data/lib/node_mutation/action/insert_action.rb +7 -6
- data/lib/node_mutation/action/noop_action.rb +8 -5
- data/lib/node_mutation/action/prepend_action.rb +10 -5
- data/lib/node_mutation/action/remove_action.rb +9 -9
- data/lib/node_mutation/action/replace_action.rb +5 -4
- data/lib/node_mutation/action/replace_with_action.rb +10 -5
- data/lib/node_mutation/action.rb +5 -3
- data/lib/node_mutation/adapter/parser.rb +3 -1
- data/lib/node_mutation/adapter/syntax_tree.rb +1 -1
- data/lib/node_mutation/version.rb +1 -1
- data/lib/node_mutation.rb +26 -22
- data/sig/node_mutation.rbs +2 -4
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1039c5eaf805a6938a0470e3dbafd304b9b7c2a84c3f321fc040f030e0314dea
|
4
|
+
data.tar.gz: fd7895425980b04494de197902a84bef9dcdb6153255654ccc2a5c28b31badb7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0ebb7d1aaf7ffd54e8f99bc1064caaa23c3f76e131260acf58dc43eb23de49a3d3d09482e19754b43ab19c699b313370fdd17ae5dfd02c1e3964470df002ffa8
|
7
|
+
data.tar.gz: 674438f94176b2ed7e77283e7238ab96edefc49a4423f9bb967904137a964d2d72228fd7f815fdb102b3ed0823820ef4e99fe54a0863b2144a98d3a240a2ccdb
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,15 @@
|
|
1
1
|
# NodeMutation
|
2
2
|
|
3
|
+
## 1.22.1 (2023-12-04)
|
4
|
+
|
5
|
+
* `child_node_range` supports int/float/str/sym `value`
|
6
|
+
|
7
|
+
## 1.22.0 (2023-11-27)
|
8
|
+
|
9
|
+
* Add `adapter` parameter to `NodeMutation`
|
10
|
+
* Add `adapter` parameter to `NodeMutation::Action`
|
11
|
+
* Do not allow to configure an `adapter` globally
|
12
|
+
|
3
13
|
## 1.21.6 (2023-11-20)
|
4
14
|
|
5
15
|
* Flat and sort actions after filtering actions when processing
|
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -25,7 +25,7 @@ Or install it yourself as:
|
|
25
25
|
```ruby
|
26
26
|
require 'node_mutation'
|
27
27
|
|
28
|
-
mutation = NodeMutation.new(source)
|
28
|
+
mutation = NodeMutation.new(source, adapter: :parser)
|
29
29
|
```
|
30
30
|
|
31
31
|
2. call the rewrite apis:
|
@@ -91,10 +91,6 @@ Different parsers, like parse and ripper, will generate different AST nodes, to
|
|
91
91
|
we define an [Adapter](https://github.com/xinminlabs/node-mutation-ruby/blob/main/lib/node_mutation/adapter.rb) interface,
|
92
92
|
if you implement the Adapter interface, you can set it as NodeMutation's adapter.
|
93
93
|
|
94
|
-
```ruby
|
95
|
-
NodeMutation.configure(adapter: SyntaxTreeAdapter.new) // default is ParserAdapter
|
96
|
-
```
|
97
|
-
|
98
94
|
### strategy
|
99
95
|
|
100
96
|
It provides 3 strategies to handle conflicts when processing actions:
|
@@ -2,8 +2,13 @@
|
|
2
2
|
|
3
3
|
# AppendAction appends code to the bottom of node body.
|
4
4
|
class NodeMutation::AppendAction < NodeMutation::Action
|
5
|
-
|
6
|
-
|
5
|
+
# Initialize an AppendAction.
|
6
|
+
#
|
7
|
+
# @param node [Node]
|
8
|
+
# @param code [String] new code to append.
|
9
|
+
# @param adapter [NodeMutation::Adapter]
|
10
|
+
def initialize(node, code, adapter:)
|
11
|
+
super(node, code, adapter: adapter)
|
7
12
|
@type = :insert
|
8
13
|
end
|
9
14
|
|
@@ -13,7 +18,7 @@ class NodeMutation::AppendAction < NodeMutation::Action
|
|
13
18
|
|
14
19
|
# Calculate the begin the end positions.
|
15
20
|
def calculate_position
|
16
|
-
@start =
|
21
|
+
@start = @adapter.get_end(@node) - @adapter.get_start_loc(@node).column - END_LENGTH
|
17
22
|
@end = @start
|
18
23
|
end
|
19
24
|
|
@@ -22,6 +27,6 @@ class NodeMutation::AppendAction < NodeMutation::Action
|
|
22
27
|
# @param node [Parser::AST::Node]
|
23
28
|
# @return [String] n times whitesphace
|
24
29
|
def indent(node)
|
25
|
-
' ' * (
|
30
|
+
' ' * (@adapter.get_start_loc(node).column + NodeMutation.tab_width)
|
26
31
|
end
|
27
32
|
end
|
@@ -6,9 +6,10 @@ class NodeMutation::DeleteAction < NodeMutation::Action
|
|
6
6
|
#
|
7
7
|
# @param node [Node]
|
8
8
|
# @param selectors [Array<Symbol, String>] used to select child nodes
|
9
|
-
# @
|
10
|
-
|
11
|
-
|
9
|
+
# @param and_comma [Boolean] delete extra comma.
|
10
|
+
# @param adapter [NodeMutation::Adapter]
|
11
|
+
def initialize(node, *selectors, adapter:, and_comma: false)
|
12
|
+
super(node, nil, adapter: adapter)
|
12
13
|
@selectors = selectors
|
13
14
|
@and_comma = and_comma
|
14
15
|
@type = :delete
|
@@ -23,9 +24,9 @@ class NodeMutation::DeleteAction < NodeMutation::Action
|
|
23
24
|
|
24
25
|
# Calculate the begin and end positions.
|
25
26
|
def calculate_position
|
26
|
-
@start = @selectors.map { |selector|
|
27
|
+
@start = @selectors.map { |selector| @adapter.child_node_range(@node, selector) }
|
27
28
|
.compact.map(&:start).min
|
28
|
-
@end = @selectors.map { |selector|
|
29
|
+
@end = @selectors.map { |selector| @adapter.child_node_range(@node, selector) }
|
29
30
|
.compact.map(&:end).max
|
30
31
|
remove_comma if @and_comma
|
31
32
|
remove_whitespace
|
@@ -6,8 +6,9 @@ class NodeMutation::IndentAction < NodeMutation::Action
|
|
6
6
|
#
|
7
7
|
# @param node [Node]
|
8
8
|
# @param tab_size [Integer] tab size
|
9
|
-
|
10
|
-
|
9
|
+
# @param adapter [NodeMutation::Adapter]
|
10
|
+
def initialize(node, tab_size = 1, adapter:)
|
11
|
+
super(node, nil, adapter: adapter)
|
11
12
|
@tab_size = tab_size
|
12
13
|
@type = :replace
|
13
14
|
end
|
@@ -16,7 +17,7 @@ class NodeMutation::IndentAction < NodeMutation::Action
|
|
16
17
|
#
|
17
18
|
# @return [String] rewritten code.
|
18
19
|
def new_code
|
19
|
-
source =
|
20
|
+
source = @adapter.get_source(@node)
|
20
21
|
source.each_line.map { |line| (' ' * NodeMutation.tab_width * @tab_size) + line }
|
21
22
|
.join
|
22
23
|
end
|
@@ -25,7 +26,7 @@ class NodeMutation::IndentAction < NodeMutation::Action
|
|
25
26
|
|
26
27
|
# Calculate the begin the end positions.
|
27
28
|
def calculate_position
|
28
|
-
@start =
|
29
|
-
@end =
|
29
|
+
@start = @adapter.get_start(@node)
|
30
|
+
@end = @adapter.get_end(@node)
|
30
31
|
end
|
31
32
|
end
|
@@ -9,8 +9,9 @@ class NodeMutation::InsertAction < NodeMutation::Action
|
|
9
9
|
# @param at [String] position to insert, beginning or end
|
10
10
|
# @param to [<nil|String>] name of child node
|
11
11
|
# @param and_comma [Boolean] insert extra comma.
|
12
|
-
|
13
|
-
|
12
|
+
# @param adapter [NodeMutation::Adapter]
|
13
|
+
def initialize(node, code, adapter:, at: 'end', to: nil, and_comma: false)
|
14
|
+
super(node, code, adapter: adapter)
|
14
15
|
@at = at
|
15
16
|
@to = to
|
16
17
|
@and_comma = and_comma
|
@@ -35,15 +36,15 @@ class NodeMutation::InsertAction < NodeMutation::Action
|
|
35
36
|
@start =
|
36
37
|
if @at == 'end'
|
37
38
|
if @to
|
38
|
-
|
39
|
+
@adapter.child_node_range(@node, @to).end
|
39
40
|
else
|
40
|
-
|
41
|
+
@adapter.get_end(@node)
|
41
42
|
end
|
42
43
|
else
|
43
44
|
if @to
|
44
|
-
|
45
|
+
@adapter.child_node_range(@node, @to).start
|
45
46
|
else
|
46
|
-
|
47
|
+
@adapter.get_start(@node)
|
47
48
|
end
|
48
49
|
end
|
49
50
|
@end = @start
|
@@ -2,9 +2,12 @@
|
|
2
2
|
|
3
3
|
# NoopAction to do no operation.
|
4
4
|
class NodeMutation::NoopAction < NodeMutation::Action
|
5
|
-
#
|
6
|
-
|
7
|
-
|
5
|
+
# Initialize a NoopAction.
|
6
|
+
#
|
7
|
+
# @param node [Node]
|
8
|
+
# @param adapter [NodeMutation::Adapter]
|
9
|
+
def initialize(node, adapter:)
|
10
|
+
super(node, nil, adapter: adapter)
|
8
11
|
end
|
9
12
|
|
10
13
|
# The rewritten source code with proper indent.
|
@@ -18,7 +21,7 @@ class NodeMutation::NoopAction < NodeMutation::Action
|
|
18
21
|
|
19
22
|
# Calculate the begin the end positions.
|
20
23
|
def calculate_position
|
21
|
-
@start =
|
22
|
-
@end =
|
24
|
+
@start = @adapter.get_start(@node)
|
25
|
+
@end = @adapter.get_end(@node)
|
23
26
|
end
|
24
27
|
end
|
@@ -2,8 +2,13 @@
|
|
2
2
|
|
3
3
|
# PrependAction to prepend code to the top of node body.
|
4
4
|
class NodeMutation::PrependAction < NodeMutation::Action
|
5
|
-
|
6
|
-
|
5
|
+
# Initialize an PrependAction.
|
6
|
+
#
|
7
|
+
# @param node [Node]
|
8
|
+
# @param code [String] new code to prepend.
|
9
|
+
# @param adapter [NodeMutation::Adapter]
|
10
|
+
def initialize(node, code, adapter:)
|
11
|
+
super(node, code, adapter: adapter)
|
7
12
|
@type = :insert
|
8
13
|
end
|
9
14
|
|
@@ -11,8 +16,8 @@ class NodeMutation::PrependAction < NodeMutation::Action
|
|
11
16
|
|
12
17
|
# Calculate the begin and end positions.
|
13
18
|
def calculate_position
|
14
|
-
node_start =
|
15
|
-
node_source =
|
19
|
+
node_start = @adapter.get_start(@node)
|
20
|
+
node_source = @adapter.get_source(@node)
|
16
21
|
first_line = node_source.split("\n").first
|
17
22
|
@start = first_line.end_with?("do") ? node_start + first_line.rindex("do") + "do".length : node_start + first_line.length
|
18
23
|
@end = @start
|
@@ -23,6 +28,6 @@ class NodeMutation::PrependAction < NodeMutation::Action
|
|
23
28
|
# @param node [Parser::AST::Node]
|
24
29
|
# @return [String] n times whitesphace
|
25
30
|
def indent(node)
|
26
|
-
' ' * (
|
31
|
+
' ' * (@adapter.get_start_loc(node).column + NodeMutation.tab_width)
|
27
32
|
end
|
28
33
|
end
|
@@ -5,10 +5,10 @@ class NodeMutation::RemoveAction < NodeMutation::Action
|
|
5
5
|
# Initialize a RemoveAction.
|
6
6
|
#
|
7
7
|
# @param node [Node]
|
8
|
-
# @param
|
9
|
-
# @
|
10
|
-
def initialize(node, and_comma: false)
|
11
|
-
super(node, nil)
|
8
|
+
# @param and_comma [Boolean] delete extra comma.
|
9
|
+
# @param adapter [NodeMutation::Adapter]
|
10
|
+
def initialize(node, adapter:, and_comma: false)
|
11
|
+
super(node, nil, adapter: adapter)
|
12
12
|
@and_comma = and_comma
|
13
13
|
@type = :delete
|
14
14
|
end
|
@@ -22,8 +22,8 @@ class NodeMutation::RemoveAction < NodeMutation::Action
|
|
22
22
|
|
23
23
|
# Calculate the begin the end positions.
|
24
24
|
def calculate_position
|
25
|
-
@start =
|
26
|
-
@end =
|
25
|
+
@start = @adapter.get_start(@node)
|
26
|
+
@end = @adapter.get_end(@node)
|
27
27
|
remove_comma if @and_comma
|
28
28
|
remove_whitespace
|
29
29
|
if take_whole_line?
|
@@ -36,7 +36,7 @@ class NodeMutation::RemoveAction < NodeMutation::Action
|
|
36
36
|
#
|
37
37
|
# @return [Boolean]
|
38
38
|
def take_whole_line?
|
39
|
-
|
39
|
+
@adapter.get_source(@node) == file_source[@start...@end].strip.chomp(',')
|
40
40
|
end
|
41
41
|
|
42
42
|
def remove_newline
|
@@ -73,8 +73,8 @@ class NodeMutation::RemoveAction < NodeMutation::Action
|
|
73
73
|
|
74
74
|
def squeeze_lines
|
75
75
|
lines = file_source.split("\n")
|
76
|
-
begin_line =
|
77
|
-
end_line =
|
76
|
+
begin_line = @adapter.get_start_loc(@node).line
|
77
|
+
end_line = @adapter.get_end_loc(@node).line
|
78
78
|
before_line_is_blank = begin_line == 1 || lines[begin_line - 2] == ''
|
79
79
|
after_line_is_blank = lines[end_line] == ''
|
80
80
|
|
@@ -7,8 +7,9 @@ class NodeMutation::ReplaceAction < NodeMutation::Action
|
|
7
7
|
# @param node [Node]
|
8
8
|
# @param selectors [Array<Symbol|String>] used to select child nodes
|
9
9
|
# @param with [String] the new code
|
10
|
-
|
11
|
-
|
10
|
+
# @param adapter [NodeMutation::Adapter]
|
11
|
+
def initialize(node, *selectors, adapter:, with:)
|
12
|
+
super(node, with, adapter: adapter)
|
12
13
|
@selectors = selectors
|
13
14
|
@type = :replace
|
14
15
|
end
|
@@ -24,9 +25,9 @@ class NodeMutation::ReplaceAction < NodeMutation::Action
|
|
24
25
|
|
25
26
|
# Calculate the begin the end positions.
|
26
27
|
def calculate_position
|
27
|
-
@start = @selectors.map { |selector|
|
28
|
+
@start = @selectors.map { |selector| @adapter.child_node_range(@node, selector).start }
|
28
29
|
.min
|
29
|
-
@end = @selectors.map { |selector|
|
30
|
+
@end = @selectors.map { |selector| @adapter.child_node_range(@node, selector).end }
|
30
31
|
.max
|
31
32
|
end
|
32
33
|
end
|
@@ -2,8 +2,13 @@
|
|
2
2
|
|
3
3
|
# ReplaceWithAction to replace code.
|
4
4
|
class NodeMutation::ReplaceWithAction < NodeMutation::Action
|
5
|
-
|
6
|
-
|
5
|
+
# Initailize a ReplaceWithAction.
|
6
|
+
#
|
7
|
+
# @param node [Node]
|
8
|
+
# @param code [String] the new code.
|
9
|
+
# @param adapter [NodeMutation::Adapter]
|
10
|
+
def initialize(node, code, adapter:)
|
11
|
+
super(node, code, adapter: adapter)
|
7
12
|
@type = :replace
|
8
13
|
end
|
9
14
|
|
@@ -26,14 +31,14 @@ class NodeMutation::ReplaceWithAction < NodeMutation::Action
|
|
26
31
|
|
27
32
|
# Calculate the begin the end positions.
|
28
33
|
def calculate_position
|
29
|
-
@start =
|
30
|
-
@end =
|
34
|
+
@start = @adapter.get_start(@node)
|
35
|
+
@end = @adapter.get_end(@node)
|
31
36
|
end
|
32
37
|
|
33
38
|
# Indent of the node
|
34
39
|
#
|
35
40
|
# @return [String] n times whitesphace
|
36
41
|
def indent
|
37
|
-
' ' *
|
42
|
+
' ' * @adapter.get_start_loc(@node).column
|
38
43
|
end
|
39
44
|
end
|
data/lib/node_mutation/action.rb
CHANGED
@@ -16,9 +16,11 @@ class NodeMutation::Action
|
|
16
16
|
#
|
17
17
|
# @param node [Node]
|
18
18
|
# @param code [String] new code to insert, replace or delete.
|
19
|
-
|
19
|
+
# @param adapter [NodeMutation::Adapter]
|
20
|
+
def initialize(node, code, adapter:)
|
20
21
|
@node = node
|
21
22
|
@code = code
|
23
|
+
@adapter = adapter
|
22
24
|
end
|
23
25
|
|
24
26
|
# Calculate begin and end positions, and return self.
|
@@ -59,7 +61,7 @@ class NodeMutation::Action
|
|
59
61
|
#
|
60
62
|
# @return [String] rewritten source code.
|
61
63
|
def rewritten_source
|
62
|
-
@rewritten_source ||=
|
64
|
+
@rewritten_source ||= @adapter.rewritten_source(@node, @code)
|
63
65
|
end
|
64
66
|
|
65
67
|
# remove unused whitespace.
|
@@ -115,6 +117,6 @@ class NodeMutation::Action
|
|
115
117
|
#
|
116
118
|
# @return [String]
|
117
119
|
def file_source
|
118
|
-
@file_source ||=
|
120
|
+
@file_source ||= @adapter.file_source(@node)
|
119
121
|
end
|
120
122
|
end
|
@@ -82,7 +82,7 @@ class NodeMutation::ParserAdapter < NodeMutation::Adapter
|
|
82
82
|
if lines_count > 1 && lines_count == evaluated.size
|
83
83
|
new_code = []
|
84
84
|
lines.each_with_index { |line, index|
|
85
|
-
new_code << (index == 0 ? line : line[
|
85
|
+
new_code << (index == 0 ? line : line[get_indent(evaluated.first) - NodeMutation.tab_width..-1])
|
86
86
|
}
|
87
87
|
new_code.join("\n")
|
88
88
|
else
|
@@ -185,6 +185,8 @@ class NodeMutation::ParserAdapter < NodeMutation::Adapter
|
|
185
185
|
NodeMutation::Struct::Range.new(node.loc.operator.begin_pos, node.loc.operator.end_pos) if node.loc.operator
|
186
186
|
when %i[defs self]
|
187
187
|
NodeMutation::Struct::Range.new(node.loc.operator.begin_pos - 'self'.length, node.loc.operator.begin_pos)
|
188
|
+
when %i[float value], %i[int value], %i[rational value], %i[str value], %i[sym value]
|
189
|
+
NodeMutation::Struct::Range.new(node.loc.expression.begin_pos, node.loc.expression.end_pos)
|
188
190
|
when %i[lvasgn variable], %i[ivasgn variable], %i[cvasgn variable], %i[gvasgn variable]
|
189
191
|
NodeMutation::Struct::Range.new(node.loc.name.begin_pos, node.loc.name.end_pos)
|
190
192
|
when %i[send dot], %i[csend dot]
|
@@ -74,7 +74,7 @@ class NodeMutation::SyntaxTreeAdapter < NodeMutation::Adapter
|
|
74
74
|
if lines_count > 1 && lines_count == evaluated.size
|
75
75
|
new_code = []
|
76
76
|
lines.each_with_index { |line, index|
|
77
|
-
new_code << (index == 0 ? line : line[
|
77
|
+
new_code << (index == 0 ? line : line[get_indent(evaluated.first) - NodeMutation.tab_width..-1])
|
78
78
|
}
|
79
79
|
new_code.join("\n")
|
80
80
|
else
|
data/lib/node_mutation.rb
CHANGED
@@ -5,6 +5,7 @@ require_relative "node_mutation/version"
|
|
5
5
|
class NodeMutation
|
6
6
|
class MethodNotSupported < StandardError; end
|
7
7
|
class ConflictActionError < StandardError; end
|
8
|
+
class InvalidAdapterError < StandardError; end
|
8
9
|
|
9
10
|
autoload :Adapter, "node_mutation/adapter"
|
10
11
|
autoload :ParserAdapter, "node_mutation/adapter/parser"
|
@@ -27,7 +28,7 @@ class NodeMutation
|
|
27
28
|
|
28
29
|
# @!attribute [r] actions
|
29
30
|
# @return [Array<NodeMutation::Struct::Action>]
|
30
|
-
attr_reader :actions
|
31
|
+
attr_reader :actions, :adapter
|
31
32
|
|
32
33
|
# @!attribute [rw] transform_proc
|
33
34
|
# @return [Proc] proc to transfor the actions
|
@@ -36,13 +37,9 @@ class NodeMutation
|
|
36
37
|
class << self
|
37
38
|
# Configure NodeMutation
|
38
39
|
# @param [Hash] options options to configure
|
39
|
-
# @option options [NodeMutation::Adapter] :adapter the adpater
|
40
40
|
# @option options [NodeMutation::Strategy] :strategy the strategy
|
41
41
|
# @option options [Integer] :tab_width the tab width
|
42
42
|
def configure(options)
|
43
|
-
if options[:adapter]
|
44
|
-
@adapter = options[:adapter]
|
45
|
-
end
|
46
43
|
if options[:strategy]
|
47
44
|
@strategy = options[:strategy]
|
48
45
|
end
|
@@ -51,12 +48,6 @@ class NodeMutation
|
|
51
48
|
end
|
52
49
|
end
|
53
50
|
|
54
|
-
# Get the adapter
|
55
|
-
# @return [NodeMutation::Adapter] current adapter, by default is {NodeMutation::ParserAdapter}
|
56
|
-
def adapter
|
57
|
-
@adapter ||= ParserAdapter.new
|
58
|
-
end
|
59
|
-
|
60
51
|
# Get the strategy
|
61
52
|
# @return [Integer] current strategy, could be {NodeMutation::Strategy::KEEP_RUNNING} or {NodeMutation::Strategy::THROW_ERROR},
|
62
53
|
# by default is {NodeMutation::Strategy::KEEP_RUNNING}
|
@@ -73,9 +64,11 @@ class NodeMutation
|
|
73
64
|
|
74
65
|
# Initialize a NodeMutation.
|
75
66
|
# @param source [String] file source
|
76
|
-
|
67
|
+
# @param adapter [Symbol] :parser or :syntax_tree
|
68
|
+
def initialize(source, adapter:)
|
77
69
|
@source = source
|
78
70
|
@actions = []
|
71
|
+
@adapter = get_adapter_instance(adapter)
|
79
72
|
end
|
80
73
|
|
81
74
|
# Append code to the ast node.
|
@@ -94,7 +87,7 @@ class NodeMutation
|
|
94
87
|
# super
|
95
88
|
# end
|
96
89
|
def append(node, code)
|
97
|
-
@actions << AppendAction.new(node, code).process
|
90
|
+
@actions << AppendAction.new(node, code, adapter: @adapter).process
|
98
91
|
end
|
99
92
|
|
100
93
|
# Delete source code of the child ast node.
|
@@ -109,7 +102,7 @@ class NodeMutation
|
|
109
102
|
# the source code will be rewritten to
|
110
103
|
# create(...)
|
111
104
|
def delete(node, *selectors, and_comma: false)
|
112
|
-
@actions << DeleteAction.new(node, *selectors, and_comma: and_comma).process
|
105
|
+
@actions << DeleteAction.new(node, *selectors, and_comma: and_comma, adapter: @adapter).process
|
113
106
|
end
|
114
107
|
|
115
108
|
# Insert code to the ast node.
|
@@ -126,7 +119,7 @@ class NodeMutation
|
|
126
119
|
# the source code will be rewritten to
|
127
120
|
# URI.open('http://test.com')
|
128
121
|
def insert(node, code, at: 'end', to: nil, and_comma: false)
|
129
|
-
@actions << InsertAction.new(node, code, at: at, to: to, and_comma: and_comma).process
|
122
|
+
@actions << InsertAction.new(node, code, at: at, to: to, and_comma: and_comma, adapter: @adapter).process
|
130
123
|
end
|
131
124
|
|
132
125
|
# Prepend code to the ast node.
|
@@ -145,7 +138,7 @@ class NodeMutation
|
|
145
138
|
# do_something
|
146
139
|
# end
|
147
140
|
def prepend(node, code)
|
148
|
-
@actions << PrependAction.new(node, code).process
|
141
|
+
@actions << PrependAction.new(node, code, adapter: @adapter).process
|
149
142
|
end
|
150
143
|
|
151
144
|
# Remove source code of the ast node.
|
@@ -158,7 +151,7 @@ class NodeMutation
|
|
158
151
|
# mutation.remove(node)
|
159
152
|
# the source code will be removed
|
160
153
|
def remove(node, and_comma: false)
|
161
|
-
@actions << RemoveAction.new(node, and_comma: and_comma).process
|
154
|
+
@actions << RemoveAction.new(node, and_comma: and_comma, adapter: @adapter).process
|
162
155
|
end
|
163
156
|
|
164
157
|
# Replace child node of the ast node with new code.
|
@@ -174,7 +167,7 @@ class NodeMutation
|
|
174
167
|
# the source code will be rewritten to
|
175
168
|
# assert_empty(object)
|
176
169
|
def replace(node, *selectors, with:)
|
177
|
-
@actions << ReplaceAction.new(node, *selectors, with: with).process
|
170
|
+
@actions << ReplaceAction.new(node, *selectors, with: with, adapter: @adapter).process
|
178
171
|
end
|
179
172
|
|
180
173
|
# Replace source code of the ast node with new code.
|
@@ -188,7 +181,7 @@ class NodeMutation
|
|
188
181
|
# the source code will be rewritten to
|
189
182
|
# allow(obj).to receive_messages(:foo => 1, :bar => 2)
|
190
183
|
def replace_with(node, code)
|
191
|
-
@actions << ReplaceWithAction.new(node, code).process
|
184
|
+
@actions << ReplaceWithAction.new(node, code, adapter: @adapter).process
|
192
185
|
end
|
193
186
|
|
194
187
|
# Wrap source code of the ast node with prefix and suffix code.
|
@@ -209,7 +202,7 @@ class NodeMutation
|
|
209
202
|
# end
|
210
203
|
def wrap(node, prefix:, suffix:, newline: false)
|
211
204
|
if newline
|
212
|
-
indentation =
|
205
|
+
indentation = @adapter.get_start_loc(node).column
|
213
206
|
group do
|
214
207
|
insert node, prefix + "\n" + (' ' * indentation), at: 'beginning'
|
215
208
|
insert node, "\n" + (' ' * indentation) + suffix, at: 'end'
|
@@ -235,13 +228,13 @@ class NodeMutation
|
|
235
228
|
# class Foobar
|
236
229
|
# end
|
237
230
|
def indent(node)
|
238
|
-
@actions << IndentAction.new(node).process
|
231
|
+
@actions << IndentAction.new(node, adapter: @adapter).process
|
239
232
|
end
|
240
233
|
|
241
234
|
# No operation.
|
242
235
|
# @param node [Node] ast node
|
243
236
|
def noop(node)
|
244
|
-
@actions << NoopAction.new(node).process
|
237
|
+
@actions << NoopAction.new(node, adapter: @adapter).process
|
245
238
|
end
|
246
239
|
|
247
240
|
# group multiple actions
|
@@ -424,4 +417,15 @@ class NodeMutation
|
|
424
417
|
def strategy?(strategy)
|
425
418
|
NodeMutation.strategy & strategy == strategy
|
426
419
|
end
|
420
|
+
|
421
|
+
def get_adapter_instance(adapter)
|
422
|
+
case adapter.to_sym
|
423
|
+
when :parser
|
424
|
+
ParserAdapter.new
|
425
|
+
when :syntax_tree
|
426
|
+
SyntaxTreeAdapter.new
|
427
|
+
else
|
428
|
+
raise InvalidAdapterError, "adapter #{adapter} is not supported"
|
429
|
+
end
|
430
|
+
end
|
427
431
|
end
|
data/sig/node_mutation.rbs
CHANGED
@@ -9,15 +9,13 @@ class NodeMutation[T]
|
|
9
9
|
|
10
10
|
attr_reader actions: Array[NodeMutation::Action]
|
11
11
|
|
12
|
-
def self.configure: (options: {
|
13
|
-
|
14
|
-
def self.adapter: () -> NodeMutation::Adapter
|
12
|
+
def self.configure: (options: { strategy: Integer, tab_width: Integer }) -> void
|
15
13
|
|
16
14
|
def self.strategy: () -> Integer
|
17
15
|
|
18
16
|
def self.tab_width: () -> Integer
|
19
17
|
|
20
|
-
def initialize: (source: String) -> NodeMutation
|
18
|
+
def initialize: (source: String, adapter: Symbol) -> NodeMutation
|
21
19
|
|
22
20
|
def append: (node: T, code: String) -> void
|
23
21
|
|
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.22.1
|
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-12-04 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: ast node mutation apis
|
14
14
|
email:
|