node_mutation 1.21.5 → 1.22.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f1148a4464a8b1f52500b09be2581a61c0add079b55052ced0e92297885f7082
4
- data.tar.gz: c8e779f8ab34b515c7c991a0b16c3a4aa85c280841fa65d021a1d4fd6a49ec25
3
+ metadata.gz: d1ced556aff645a4d23e98bc7d544ac8d48d89909112fbd875132a97417a7e2b
4
+ data.tar.gz: 9efd16a9ff97cb146b0b3750a53a57721700377d98a9e8c310a9435d6c42d279
5
5
  SHA512:
6
- metadata.gz: 662faf8ca577ab83503429153c5af550a4a3134a8138e4f36400aa6fcfb40b27de367c5a837af6dd6a139fe63627f3343d11d5573e2ae0501d0cfaf25fb8adb3
7
- data.tar.gz: deda4075371317fd3c5decfda04bb8752b38f37679c21e1d940f1ebb2ef775f945ee38956ebea0e78717eb386e3dccaf5ff3b76fb50f550e616a246a880e43d6
6
+ metadata.gz: 0337aee07465f0c897bf23180b6f114a3e1aa08b580040ab787e7df36f69947d8f68b644235fce64b1ea78db44aae8d2e58d5e9349b783c02a8d1499f7514507
7
+ data.tar.gz: c8fdcf2857e1dfddcf36653dddcf48e6d19a10d7d9f99994a7551c9e146dd034e80576e0bf1b58d3b8aad784a11e1edd858ad9e9dae3b9122723c8242122f768
data/CHANGELOG.md CHANGED
@@ -1,5 +1,15 @@
1
1
  # NodeMutation
2
2
 
3
+ ## 1.22.0 (2023-11-27)
4
+
5
+ * Add `adapter` parameter to `NodeMutation`
6
+ * Add `adapter` parameter to `NodeMutation::Action`
7
+ * Do not allow to configure an `adapter` globally
8
+
9
+ ## 1.21.6 (2023-11-20)
10
+
11
+ * Flat and sort actions after filtering actions when processing
12
+
3
13
  ## 1.21.5 (2023-11-20)
4
14
 
5
15
  * Rewrite the process and test methods
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- node_mutation (1.21.5)
4
+ node_mutation (1.22.0)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
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
- def initialize(node, code)
6
- super(node, code)
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 = NodeMutation.adapter.get_end(@node) - NodeMutation.adapter.get_start_loc(@node).column - END_LENGTH
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
- ' ' * (NodeMutation.adapter.get_start_loc(node).column + NodeMutation.tab_width)
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
- # @option and_comma [Boolean] delete extra comma.
10
- def initialize(node, *selectors, and_comma: false)
11
- super(node, nil)
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| NodeMutation.adapter.child_node_range(@node, selector) }
27
+ @start = @selectors.map { |selector| @adapter.child_node_range(@node, selector) }
27
28
  .compact.map(&:start).min
28
- @end = @selectors.map { |selector| NodeMutation.adapter.child_node_range(@node, 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
@@ -4,6 +4,7 @@
4
4
  class NodeMutation::GroupAction < NodeMutation::Action
5
5
  DEFAULT_START = 2**30
6
6
 
7
+ # Initialize a GroupAction.
7
8
  def initialize
8
9
  @actions = []
9
10
  @type = :group
@@ -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
- def initialize(node, tab_size = 1)
10
- super(node, nil)
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 = NodeMutation.adapter.get_source(@node)
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 = NodeMutation.adapter.get_start(@node)
29
- @end = NodeMutation.adapter.get_end(@node)
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
- def initialize(node, code, at: 'end', to: nil, and_comma: false)
13
- super(node, code)
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
- NodeMutation.adapter.child_node_range(@node, @to).end
39
+ @adapter.child_node_range(@node, @to).end
39
40
  else
40
- NodeMutation.adapter.get_end(@node)
41
+ @adapter.get_end(@node)
41
42
  end
42
43
  else
43
44
  if @to
44
- NodeMutation.adapter.child_node_range(@node, @to).start
45
+ @adapter.child_node_range(@node, @to).start
45
46
  else
46
- NodeMutation.adapter.get_start(@node)
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
- # Create a NoopAction
6
- def initialize(node)
7
- super(node, nil)
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 = NodeMutation.adapter.get_start(@node)
22
- @end = NodeMutation.adapter.get_end(@node)
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
- def initialize(node, code)
6
- super(node, code)
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 = NodeMutation.adapter.get_start(@node)
15
- node_source = NodeMutation.adapter.get_source(@node)
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
- ' ' * (NodeMutation.adapter.get_start_loc(node).column + NodeMutation.tab_width)
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 options [Hash] options.
9
- # @option and_comma [Boolean] delete extra comma.
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 = NodeMutation.adapter.get_start(@node)
26
- @end = NodeMutation.adapter.get_end(@node)
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
- NodeMutation.adapter.get_source(@node) == file_source[@start...@end].strip.chomp(',')
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 = NodeMutation.adapter.get_start_loc(@node).line
77
- end_line = NodeMutation.adapter.get_end_loc(@node).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
- def initialize(node, *selectors, with:)
11
- super(node, with)
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| NodeMutation.adapter.child_node_range(@node, selector).start }
28
+ @start = @selectors.map { |selector| @adapter.child_node_range(@node, selector).start }
28
29
  .min
29
- @end = @selectors.map { |selector| NodeMutation.adapter.child_node_range(@node, selector).end }
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
- def initialize(node, code)
6
- super(node, code)
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 = NodeMutation.adapter.get_start(@node)
30
- @end = NodeMutation.adapter.get_end(@node)
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
- ' ' * NodeMutation.adapter.get_start_loc(@node).column
42
+ ' ' * @adapter.get_start_loc(@node).column
38
43
  end
39
44
  end
@@ -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
- def initialize(node, code)
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 ||= NodeMutation.adapter.rewritten_source(@node, @code)
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 ||= NodeMutation.adapter.file_source(@node)
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[NodeMutation.adapter.get_indent(evaluated.first) - NodeMutation.tab_width..-1])
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
@@ -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[NodeMutation.adapter.get_indent(evaluated.first) - NodeMutation.tab_width..-1])
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
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  class NodeMutation
4
- VERSION = "1.21.5"
4
+ VERSION = "1.22.0"
5
5
  end
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
- def initialize(source)
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 = NodeMutation.adapter.get_start_loc(node).column
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
@@ -277,7 +270,8 @@ class NodeMutation
277
270
  raise ConflictActionError, "mutation actions are conflicted"
278
271
  end
279
272
 
280
- new_source = rewrite_source(source, sort_actions(get_filter_actions(conflict_actions)))
273
+ actions = sort_flatten_actions(flat_actions(get_filter_actions(conflict_actions)))
274
+ new_source = rewrite_source(source, actions)
281
275
  result = NodeMutation::Result.new(affected: true, conflicted: !conflict_actions.empty?)
282
276
  result.new_source = new_source
283
277
  result
@@ -423,4 +417,15 @@ class NodeMutation
423
417
  def strategy?(strategy)
424
418
  NodeMutation.strategy & strategy == strategy
425
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
426
431
  end
@@ -9,15 +9,13 @@ class NodeMutation[T]
9
9
 
10
10
  attr_reader actions: Array[NodeMutation::Action]
11
11
 
12
- def self.configure: (options: { adapter: NodeMutation::Adapter, strategy: Integer, tab_width: Integer }) -> void
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.21.5
4
+ version: 1.22.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-19 00:00:00.000000000 Z
11
+ date: 2023-11-27 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: ast node mutation apis
14
14
  email: