node_mutation 1.14.0 → 1.15.1

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: 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