node_mutation 1.21.6 → 1.22.1
Sign up to get free protection for your applications and to get access to all the features.
- 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:
|