node_mutation 1.14.0 → 1.15.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c5f41eba8034d3565eeda68905e0d6f8efff2a5ad56f0523f3aca6e57b334239
4
- data.tar.gz: eb115a375da1d2e17ca62df7089ae22b243fc94e273b1a37378cc8ff215be6e9
3
+ metadata.gz: 382d91776358172b2310f5281edc413bf6066da9e333e150fa14a068219058bf
4
+ data.tar.gz: 5bdeef13cc69a5f4e6b9abef45ed95eeab57b13e95bed01a8fb0f25b02788140
5
5
  SHA512:
6
- metadata.gz: f0bb8b60c6c9a822a883c2219303ba39bc649adade357ea82074cea9c4da8f0a33b6305bd45dc3e8b094a420b7f450dbd90fab80b498331e87c1a5fed8c68404
7
- data.tar.gz: 69eab44d9cc1282ce4c7afb09a3ea80573728562538cbe75fde02458d915c5f8479c87098171d4421e5d157fac92a85f8ecce8b8c61bf29bd63dd6fd44a6128d
6
+ metadata.gz: b35c57db840700ed2a53ea3f0b1713185da7c36b4759537709ce726cf1094f862dcdd9cc2e5a19cdb99b0ef34ebe1436414e17c35915f6694b3c7ee66bf4a163
7
+ data.tar.gz: 2ad6b1ec1f27bad428cc299ffb95f3fce4bd57338365a60707736ae9936aaf15f445d89d8cf339224f4994391907a9df6d3e7ee2dfb2cc394782c2b83261645f
data/CHANGELOG.md CHANGED
@@ -1,5 +1,15 @@
1
1
  # NodeMutation
2
2
 
3
+ ## 1.15.1 (2023-04-17)
4
+
5
+ * Fix `wrap` code for newline
6
+
7
+ ## 1.15.0 (2023-04-17)
8
+
9
+ * Add `indent` action
10
+ * Use two `InsertAction` and one `IndentAction` instead of `WrapAction`
11
+ * Drop `ALLOW_INSERT_AT_SAME_POSITION` strategy
12
+
3
13
  ## 1.14.0 (2023-04-04)
4
14
 
5
15
  * Add `transform_proc` to transform the actions
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- node_mutation (1.14.0)
4
+ node_mutation (1.15.1)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
data/README.md CHANGED
@@ -35,18 +35,20 @@ mutation = NodeMutation.new(source)
35
35
  mutation.append node, 'include FactoryGirl::Syntax::Methods'
36
36
  # delete source code of the child ast node
37
37
  mutation.delete node, :dot, :message, and_comma: true
38
+ # indent code
39
+ mutation.indent node, tab_size: 1
38
40
  # insert code to the ast node.
39
41
  mutation.insert node, 'URI.', at: 'beginning'
40
42
  # prepend code to the ast node.
41
43
  mutation.prepend node, '{{arguments.first}}.include FactoryGirl::Syntax::Methods'
42
44
  # remove source code of the ast node
43
- mutation.remove(node: Node)
45
+ mutation.remove node, and_comma: true
44
46
  # replace child node of the ast node with new code
45
47
  mutation.replace node, :message, with: 'test'
46
48
  # replace the ast node with new code
47
49
  mutation.replace_with node, 'create {{arguments}}'
48
- # wrap node within a block, class or module
49
- mutation.wrap node, with: 'module Foo'
50
+ # wrap node with prefix and suffix code
51
+ mutation.wrap node, prefix: 'module Foo', suffix: 'end', newline: true
50
52
  # no operation
51
53
  mutation.noop
52
54
  ```
@@ -81,10 +83,9 @@ It provides 3 strategies to handle conflicts when processing actions:
81
83
 
82
84
  1. `Strategy.KEEP_RUNNING`: keep running and ignore the conflict action.
83
85
  2. `Strategy.THROW_ERROR`: throw error when conflict action is found.
84
- 3. `Strategy.ALLOW_INSERT_AT_SAME_POSITION`: allow insert action at the same position.
85
86
 
86
87
  ```ruby
87
- NodeMutation.configure(strategy: Strategy.KEEP_RUNNING | Strategy.ALLOW_INSERT_AT_SAME_POSITION); // default is Strategy.THROW_ERROR
88
+ NodeMutation.configure(strategy: Strategy.KEEP_RUNNING); // default is Strategy.THROW_ERROR
88
89
  ```
89
90
 
90
91
  ### tab_width
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ # IndentAction to indent code.
4
+ class NodeMutation::IndentAction < NodeMutation::Action
5
+ # Initialize a IndentAction.
6
+ #
7
+ # @param node [Node]
8
+ # @param tab_size [Integer] tab size
9
+ def initialize(node, tab_size = 1)
10
+ super(node, nil)
11
+ @tab_size = tab_size
12
+ end
13
+
14
+ # The rewritten source code with proper indent.
15
+ #
16
+ # @return [String] rewritten code.
17
+ def new_code
18
+ source = NodeMutation.adapter.get_source(@node)
19
+ source.each_line.map { |line| ' ' * NodeMutation.tab_width * @tab_size + line }.join
20
+ end
21
+
22
+ private
23
+
24
+ # Calculate the begin the end positions.
25
+ def calculate_position
26
+ @start = NodeMutation.adapter.get_start(@node)
27
+ @end = NodeMutation.adapter.get_end(@node)
28
+ end
29
+ end
@@ -3,5 +3,4 @@
3
3
  class NodeMutation::Strategy
4
4
  KEEP_RUNNING = 0b1
5
5
  THROW_ERROR = 0b10
6
- ALLOW_INSERT_AT_SAME_POSITION = 0b100
7
6
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  class NodeMutation
4
- VERSION = "1.14.0"
4
+ VERSION = "1.15.1"
5
5
  end
data/lib/node_mutation.rb CHANGED
@@ -11,12 +11,12 @@ class NodeMutation
11
11
  autoload :Action, 'node_mutation/action'
12
12
  autoload :AppendAction, 'node_mutation/action/append_action'
13
13
  autoload :DeleteAction, 'node_mutation/action/delete_action'
14
+ autoload :IndentAction, 'node_mutation/action/indent_action'
14
15
  autoload :InsertAction, 'node_mutation/action/insert_action'
15
16
  autoload :RemoveAction, 'node_mutation/action/remove_action'
16
17
  autoload :PrependAction, 'node_mutation/action/prepend_action'
17
18
  autoload :ReplaceAction, 'node_mutation/action/replace_action'
18
19
  autoload :ReplaceWithAction, 'node_mutation/action/replace_with_action'
19
- autoload :WrapAction, 'node_mutation/action/wrap_action'
20
20
  autoload :NoopAction, 'node_mutation/action/noop_action'
21
21
  autoload :Result, 'node_mutation/result'
22
22
  autoload :Strategy, 'node_mutation/strategy'
@@ -188,22 +188,32 @@ class NodeMutation
188
188
  @actions << ReplaceWithAction.new(node, code).process
189
189
  end
190
190
 
191
- # Wrap source code of the ast node with new code.
191
+ # Wrap source code of the ast node with prefix and suffix code.
192
192
  # @param node [Node] ast node
193
- # @param with [String] code need to be wrapped with.
193
+ # @param prefix [String] prefix code need to be wrapped with.
194
+ # @param suffix [String] suffix code need to be wrapped with.
195
+ # @param newline [Boolean] add newline after prefix and before suffix.
194
196
  # @example
195
197
  # source code of the ast node is
196
198
  # class Foobar
197
199
  # end
198
200
  # then we call
199
- # wrap(node, with: 'module Synvert')
201
+ # wrap(node, prefix: 'module Synvert', suffix: 'end', newline: true)
200
202
  # the source code will be rewritten to
201
203
  # module Synvert
202
204
  # class Foobar
203
205
  # end
204
206
  # end
205
- def wrap(node, with:)
206
- @actions << WrapAction.new(node, with: with).process
207
+ def wrap(node, prefix:, suffix:, newline: false)
208
+ if newline
209
+ indentation = NodeMutation.adapter.get_start_loc(node).column
210
+ @actions << InsertAction.new(node, prefix + "\n" + ' ' * indentation, at: 'beginning').process
211
+ @actions << InsertAction.new(node, "\n" + ' ' * indentation + suffix, at: 'end').process
212
+ @actions << IndentAction.new(node).process
213
+ else
214
+ @actions << InsertAction.new(node, prefix, at: 'beginning').process
215
+ @actions << InsertAction.new(node, suffix, at: 'end').process
216
+ end
207
217
  end
208
218
 
209
219
  # No operation.
@@ -277,11 +287,8 @@ class NodeMutation
277
287
  begin_pos = @actions[i].start
278
288
  end_pos = @actions[i].end
279
289
  while j > -1
280
- # if we have two insert actions at same position.
281
- same_position = begin_pos == @actions[j].start && begin_pos == end_pos && @actions[j].start == @actions[j].end
282
290
  # if we have two actions with overlapped range.
283
- overlapped_position = begin_pos < @actions[j].end
284
- if (!strategy?(Strategy::ALLOW_INSERT_AT_SAME_POSITION) && same_position) || overlapped_position
291
+ if begin_pos < @actions[j].end
285
292
  conflict_actions << @actions.delete_at(j)
286
293
  else
287
294
  i = j
@@ -2,6 +2,4 @@ class NodeMutation::Strategy
2
2
  KEEP_RUNNING: Integer
3
3
 
4
4
  THROW_ERROR: Integer
5
-
6
- ALLOW_INSERT_AT_SAME_POSITION: Integer
7
5
  end
@@ -33,7 +33,7 @@ module NodeMutation[T]
33
33
 
34
34
  def replace_with: (node: T, code: String) -> void
35
35
 
36
- def wrap: (node: T, with: String) -> void
36
+ def wrap: (node: T, prefix: String, suffix: String, newline: bool) -> void
37
37
 
38
38
  def noop: (node: T) -> void
39
39
 
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.14.0
4
+ version: 1.15.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-04-04 00:00:00.000000000 Z
11
+ date: 2023-04-17 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: ast node mutation apis
14
14
  email:
@@ -29,13 +29,13 @@ files:
29
29
  - lib/node_mutation/action.rb
30
30
  - lib/node_mutation/action/append_action.rb
31
31
  - lib/node_mutation/action/delete_action.rb
32
+ - lib/node_mutation/action/indent_action.rb
32
33
  - lib/node_mutation/action/insert_action.rb
33
34
  - lib/node_mutation/action/noop_action.rb
34
35
  - lib/node_mutation/action/prepend_action.rb
35
36
  - lib/node_mutation/action/remove_action.rb
36
37
  - lib/node_mutation/action/replace_action.rb
37
38
  - lib/node_mutation/action/replace_with_action.rb
38
- - lib/node_mutation/action/wrap_action.rb
39
39
  - lib/node_mutation/adapter.rb
40
40
  - lib/node_mutation/parser_adapter.rb
41
41
  - lib/node_mutation/result.rb
@@ -69,7 +69,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
69
69
  - !ruby/object:Gem::Version
70
70
  version: '0'
71
71
  requirements: []
72
- rubygems_version: 3.4.6
72
+ rubygems_version: 3.4.10
73
73
  signing_key:
74
74
  specification_version: 4
75
75
  summary: ast node mutation apis
@@ -1,34 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- # WrapAction to wrap node within a block, class or module.
4
- #
5
- # Note: if WrapAction is conflicted with another action (start and end are overlapped),
6
- # we have to put those 2 actions into 2 within_file scopes.
7
- class NodeMutation::WrapAction < NodeMutation::Action
8
- # Initialize a WrapAction.
9
- #
10
- # @param node [Node]
11
- # @param with [String] new code to wrap
12
- def initialize(node, with:)
13
- super(node, with)
14
- @indent = NodeMutation.adapter.get_start_loc(@node).column
15
- end
16
-
17
- # The rewritten source code.
18
- #
19
- # @return [String] rewritten code.
20
- def new_code
21
- "#{@code}\n#{' ' * @indent}" +
22
- NodeMutation.adapter.get_source(@node).split("\n").map { |line| " #{line}" }
23
- .join("\n") +
24
- "\n#{' ' * @indent}end"
25
- end
26
-
27
- private
28
-
29
- # Calculate the begin the end positions.
30
- def calculate_position
31
- @start = NodeMutation.adapter.get_start(@node)
32
- @end = NodeMutation.adapter.get_end(@node)
33
- end
34
- end