node_mutation 1.14.0 → 1.15.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c5f41eba8034d3565eeda68905e0d6f8efff2a5ad56f0523f3aca6e57b334239
4
- data.tar.gz: eb115a375da1d2e17ca62df7089ae22b243fc94e273b1a37378cc8ff215be6e9
3
+ metadata.gz: 11054e72fcf35b7caeb2cee67b421206da2f980d4d1f23afa08f9db75f112f75
4
+ data.tar.gz: 4dde234a2f4716b82d042b7d9f094469da04942cdca669c40a7d745f75480b77
5
5
  SHA512:
6
- metadata.gz: f0bb8b60c6c9a822a883c2219303ba39bc649adade357ea82074cea9c4da8f0a33b6305bd45dc3e8b094a420b7f450dbd90fab80b498331e87c1a5fed8c68404
7
- data.tar.gz: 69eab44d9cc1282ce4c7afb09a3ea80573728562538cbe75fde02458d915c5f8479c87098171d4421e5d157fac92a85f8ecce8b8c61bf29bd63dd6fd44a6128d
6
+ metadata.gz: 5bfc255f3b2bf599debc4c8d882999d3083f89ec2e9cdb81aa2eb1d4245e65cafb61c9f9ee7db7286b4efddf66b96cb00742696f5215beab1b3cc847c2025b40
7
+ data.tar.gz: 7c9063056156b1ee4accd50ad204040209c55ca096f543ecccc5f66175b1213a5611a4815263058514d81466e440d6cdf36f65c7208d048c48c3f3736e516706
data/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # NodeMutation
2
2
 
3
+ ## 1.15.0 (2023-04-17)
4
+
5
+ * Add `indent` action
6
+ * Use two `InsertAction` and one `IndentAction` instead of `WrapAction`
7
+ * Drop `ALLOW_INSERT_AT_SAME_POSITION` strategy
8
+
3
9
  ## 1.14.0 (2023-04-04)
4
10
 
5
11
  * 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.0)
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.0"
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,26 @@ 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
+ @actions << InsertAction.new(node, prefix, at: 'beginning').process
209
+ @actions << InsertAction.new(node, suffix, at: 'end').process
210
+ @actions << IndentAction.new(node).process if newline
207
211
  end
208
212
 
209
213
  # No operation.
@@ -277,11 +281,8 @@ class NodeMutation
277
281
  begin_pos = @actions[i].start
278
282
  end_pos = @actions[i].end
279
283
  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
284
  # 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
285
+ if begin_pos < @actions[j].end
285
286
  conflict_actions << @actions.delete_at(j)
286
287
  else
287
288
  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
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.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-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