node_mutation 1.9.3 → 1.10.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: 1e20b2ab8c6e7c9f01e01b97dfd8b0315d6fb6e474e8176a2f83609ff4e565da
4
- data.tar.gz: cc6bcbb6ddbb098b2dbe9090e20cb6d9b7466eea2041a6ae6a0880470e0f8d01
3
+ metadata.gz: 3f69bebea36b4152c7edb233d2d179bfee796988977c36f6375a12a240a77615
4
+ data.tar.gz: af1a35eb1b9ec9b3c657d976dd9b0b392d24288de6083f5d98c3d00dc036ff61
5
5
  SHA512:
6
- metadata.gz: 22b95e80c34f121736637a069cebc2d8e717e1e6cc9461937a9c00dff9253db473dccb945d6463edaee4a3c54df9392597fe6b65e1825a56425742f1beaf80b2
7
- data.tar.gz: 7134108cd2d15fd4dd6a4ee73a23f31917bfff251f403297be2f636fa0e4ab580482da4971c87815c22e2b3e182ec585b39fc688963b6495f38781e764372bdf
6
+ metadata.gz: b07a1795e19142226bd48215514d67cf0f3428ec1b03dbcfe49ed4f9825c962427943b6a1f633bc7d1627178354c3c30989af1a5e63dcbe125af54c98f280a45
7
+ data.tar.gz: f87aed954b86a4948939528ce1af8bbb779f4673ef8795cd498d015bce84d3abb271db2b44ffd65fdac2f571acbe8d03cfb2ae0cf54a8bd9d97780799e75a521
data/CHANGELOG.md CHANGED
@@ -1,5 +1,14 @@
1
1
  # NodeMutation
2
2
 
3
+ ## 1.10.1 (2023-03-13)
4
+
5
+ * Remove `OpenStruct`, use `Struct` instead
6
+
7
+ ## 1.10.0 (2023-03-01)
8
+
9
+ * Support `variable` of `lvasgn`, `ivasgn`, `cvasgn`, and `gvasgn` node in `child_node_range`
10
+ * Update `parser_node_ext` to 1.0.0
11
+
3
12
  ## 1.9.3 (2023-02-15)
4
13
 
5
14
  * Remove engine
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- node_mutation (1.9.3)
4
+ node_mutation (1.10.1)
5
5
  erubis
6
6
 
7
7
  GEM
@@ -36,9 +36,9 @@ GEM
36
36
  notiffany (0.1.3)
37
37
  nenv (~> 0.1)
38
38
  shellany (~> 0.0)
39
- parser (3.1.2.0)
39
+ parser (3.2.1.0)
40
40
  ast (~> 2.4.1)
41
- parser_node_ext (0.4.0)
41
+ parser_node_ext (1.0.0)
42
42
  parser
43
43
  pry (0.14.1)
44
44
  coderay (~> 1.1)
@@ -23,9 +23,9 @@ class NodeMutation::DeleteAction < NodeMutation::Action
23
23
  # Calculate the begin and end positions.
24
24
  def calculate_position
25
25
  @start = @selectors.map { |selector| NodeMutation.adapter.child_node_range(@node, selector) }
26
- .compact.map(&:start).min
26
+ .compact.map(&:start).min
27
27
  @end = @selectors.map { |selector| NodeMutation.adapter.child_node_range(@node, selector) }
28
- .compact.map(&:end).max
28
+ .compact.map(&:end).max
29
29
  squeeze_spaces
30
30
  remove_comma if @and_comma
31
31
  end
@@ -23,7 +23,9 @@ class NodeMutation::ReplaceAction < NodeMutation::Action
23
23
 
24
24
  # Calculate the begin the end positions.
25
25
  def calculate_position
26
- @start = @selectors.map { |selector| NodeMutation.adapter.child_node_range(@node, selector).start }.min
27
- @end = @selectors.map { |selector| NodeMutation.adapter.child_node_range(@node, selector).end }.max
26
+ @start = @selectors.map { |selector| NodeMutation.adapter.child_node_range(@node, selector).start }
27
+ .min
28
+ @end = @selectors.map { |selector| NodeMutation.adapter.child_node_range(@node, selector).end }
29
+ .max
28
30
  end
29
31
  end
@@ -20,7 +20,7 @@ class NodeMutation::WrapAction < NodeMutation::Action
20
20
  def new_code
21
21
  "#{@code}\n#{' ' * @indent}" +
22
22
  NodeMutation.adapter.get_source(@node).split("\n").map { |line| " #{line}" }
23
- .join("\n") +
23
+ .join("\n") +
24
24
  "\n#{' ' * @indent}end"
25
25
  end
26
26
 
@@ -30,7 +30,8 @@ class NodeMutation::Action
30
30
  # @return [String] rewritten code.
31
31
  def new_code
32
32
  if rewritten_source.split("\n").length > 1
33
- "\n\n" + rewritten_source.split("\n").map { |line| indent(@node) + line }.join("\n")
33
+ "\n\n" + rewritten_source.split("\n").map { |line| indent(@node) + line }
34
+ .join("\n")
34
35
  else
35
36
  "\n" + indent(@node) + rewritten_source
36
37
  end
@@ -0,0 +1,3 @@
1
+ # frozen_string_literal: true
2
+
3
+ NodeMutation::Location = Struct.new(:line, :column)
@@ -64,51 +64,50 @@ class NodeMutation::ParserAdapter < NodeMutation::Adapter
64
64
  if node.is_a?(Array)
65
65
  if direct_child_name =~ INDEX_REGEXP
66
66
  child_node = node[direct_child_name.to_i]
67
- raise NodeMutation::MethodNotSupported, "#{direct_child_name} is not supported for #{get_source(node)}" unless child_node
67
+ raise NodeMutation::MethodNotSupported,
68
+ "#{direct_child_name} is not supported for #{get_source(node)}" unless child_node
68
69
  return child_node_range(child_node, nested_child_name) if nested_child_name
69
- return OpenStruct.new(start: child_node.loc.expression.begin_pos, end: child_node.loc.expression.end_pos)
70
+
71
+ return NodeMutation::Range.new(child_node.loc.expression.begin_pos, child_node.loc.expression.end_pos)
70
72
  end
71
73
 
72
- raise NodeMutation::MethodNotSupported, "#{direct_child_name} is not supported for #{get_source(node)}" unless node.respond_to?(direct_child_name)
74
+ raise NodeMutation::MethodNotSupported,
75
+ "#{direct_child_name} is not supported for #{get_source(node)}" unless node.respond_to?(direct_child_name)
76
+
73
77
  child_node = node.send(direct_child_name)
74
78
  return child_node_range(child_node, nested_child_name) if nested_child_name
75
- return OpenStruct.new(
76
- start: child_node.loc.expression.begin_pos,
77
- end: child_node.loc.expression.end_pos
78
- )
79
+
80
+ return NodeMutation::Range.new(child_node.loc.expression.begin_pos, child_node.loc.expression.end_pos)
79
81
  end
80
82
 
81
83
  case [node.type, child_name.to_sym]
82
84
  when %i[block pipes], %i[def parentheses], %i[defs parentheses]
83
- OpenStruct.new(
84
- start: node.arguments.first.loc.expression.begin_pos - 1,
85
- end: node.arguments.last.loc.expression.end_pos + 1
86
- )
85
+ NodeMutation::Range.new(node.arguments.first.loc.expression.begin_pos - 1, node.arguments.last.loc.expression.end_pos + 1)
87
86
  when %i[block arguments], %i[def arguments], %i[defs arguments]
88
- OpenStruct.new(
89
- start: node.arguments.first.loc.expression.begin_pos,
90
- end: node.arguments.last.loc.expression.end_pos
91
- )
87
+ NodeMutation::Range.new(node.arguments.first.loc.expression.begin_pos, node.arguments.last.loc.expression.end_pos)
92
88
  when %i[class name], %i[const name], %i[def name], %i[defs name]
93
- OpenStruct.new(start: node.loc.name.begin_pos, end: node.loc.name.end_pos)
89
+ NodeMutation::Range.new(node.loc.name.begin_pos, node.loc.name.end_pos)
94
90
  when %i[defs dot]
95
- OpenStruct.new(start: node.loc.operator.begin_pos, end: node.loc.operator.end_pos) if node.loc.operator
91
+ NodeMutation::Range.new(node.loc.operator.begin_pos, node.loc.operator.end_pos) if node.loc.operator
96
92
  when %i[defs self]
97
- OpenStruct.new(start: node.loc.operator.begin_pos - 'self'.length, end: node.loc.operator.begin_pos)
93
+ NodeMutation::Range.new(node.loc.operator.begin_pos - 'self'.length, node.loc.operator.begin_pos)
94
+ when %i[lvasgn variable], %i[ivasgn variable], %i[cvasgn variable], %i[gvasgn variable]
95
+ NodeMutation::Range.new(node.loc.name.begin_pos, node.loc.name.end_pos)
98
96
  when %i[send dot], %i[csend dot]
99
- OpenStruct.new(start: node.loc.dot.begin_pos, end: node.loc.dot.end_pos) if node.loc.dot
97
+ NodeMutation::Range.new(node.loc.dot.begin_pos, node.loc.dot.end_pos) if node.loc.dot
100
98
  when %i[send message], %i[csend message]
101
99
  if node.loc.operator
102
- OpenStruct.new(start: node.loc.selector.begin_pos, end: node.loc.operator.end_pos)
100
+ NodeMutation::Range.new(node.loc.selector.begin_pos, node.loc.operator.end_pos)
103
101
  else
104
- OpenStruct.new(start: node.loc.selector.begin_pos, end: node.loc.selector.end_pos)
102
+ NodeMutation::Range.new(node.loc.selector.begin_pos, node.loc.selector.end_pos)
105
103
  end
106
104
  when %i[send parentheses], %i[csend parentheses]
107
105
  if node.loc.begin && node.loc.end
108
- OpenStruct.new(start: node.loc.begin.begin_pos, end: node.loc.end.end_pos)
106
+ NodeMutation::Range.new(node.loc.begin.begin_pos, node.loc.end.end_pos)
109
107
  end
110
108
  else
111
- raise NodeMutation::MethodNotSupported, "#{direct_child_name} is not supported for #{get_source(node)}" unless node.respond_to?(direct_child_name)
109
+ raise NodeMutation::MethodNotSupported,
110
+ "#{direct_child_name} is not supported for #{get_source(node)}" unless node.respond_to?(direct_child_name)
112
111
 
113
112
  child_node = node.send(direct_child_name)
114
113
 
@@ -118,10 +117,7 @@ class NodeMutation::ParserAdapter < NodeMutation::Adapter
118
117
 
119
118
  if child_node.is_a?(Parser::AST::Node)
120
119
  return(
121
- OpenStruct.new(
122
- start: child_node.loc.expression.begin_pos,
123
- end: child_node.loc.expression.end_pos
124
- )
120
+ NodeMutation::Range.new(child_node.loc.expression.begin_pos, child_node.loc.expression.end_pos)
125
121
  )
126
122
  end
127
123
 
@@ -129,10 +125,7 @@ class NodeMutation::ParserAdapter < NodeMutation::Adapter
129
125
  return nil if child_node.empty?
130
126
 
131
127
  return(
132
- OpenStruct.new(
133
- start: child_node.first.loc.expression.begin_pos,
134
- end: child_node.last.loc.expression.end_pos
135
- )
128
+ NodeMutation::Range.new(child_node.first.loc.expression.begin_pos, child_node.last.loc.expression.end_pos)
136
129
  )
137
130
  end
138
131
  end
@@ -147,12 +140,12 @@ class NodeMutation::ParserAdapter < NodeMutation::Adapter
147
140
 
148
141
  def get_start_loc(node)
149
142
  begin_loc = node.loc.expression.begin
150
- OpenStruct.new(line: begin_loc.line, column: begin_loc.column)
143
+ NodeMutation::Location.new(begin_loc.line, begin_loc.column)
151
144
  end
152
145
 
153
146
  def get_end_loc(node)
154
147
  end_loc = node.loc.expression.end
155
- OpenStruct.new(line: end_loc.line, column: end_loc.column)
148
+ NodeMutation::Location.new(end_loc.line, end_loc.column)
156
149
  end
157
150
 
158
151
  def get_indent(node)
@@ -167,14 +160,19 @@ class NodeMutation::ParserAdapter < NodeMutation::Adapter
167
160
  if node.is_a?(Array)
168
161
  if direct_child_name =~ INDEX_REGEXP
169
162
  child_node = node[direct_child_name.to_i]
170
- raise NodeMutation::MethodNotSupported, "#{direct_child_name} is not supported for #{get_source(node)}" unless child_node
163
+ raise NodeMutation::MethodNotSupported,
164
+ "#{direct_child_name} is not supported for #{get_source(node)}" unless child_node
171
165
  return child_node_by_name(child_node, nested_child_name) if nested_child_name
166
+
172
167
  return child_node
173
168
  end
174
169
 
175
- raise NodeMutation::MethodNotSupported, "#{direct_child_name} is not supported for #{get_source(node)}" unless node.respond_to?(direct_child_name)
170
+ raise NodeMutation::MethodNotSupported,
171
+ "#{direct_child_name} is not supported for #{get_source(node)}" unless node.respond_to?(direct_child_name)
172
+
176
173
  child_node = node.send(direct_child_name)
177
174
  return child_node_by_name(child_node, nested_child_name) if nested_child_name
175
+
178
176
  return child_node
179
177
  end
180
178
 
@@ -0,0 +1,3 @@
1
+ # frozen_string_literal: true
2
+
3
+ NodeMutation::Range = Struct.new(:start, :end)
@@ -30,8 +30,12 @@ class NodeMutation::Result
30
30
  def to_hash
31
31
  hash = { file_path: file_path }
32
32
  @options.each do |key, value|
33
- hash[key] = value.is_a?(Array) ? value.map { |action| action.to_h } : value
33
+ if key == :actions
34
+ hash[:actions] = value.map { |action| { start: action.start, end: action.end, new_code: action.new_code } }
35
+ else
36
+ hash[key] = value
37
+ end
34
38
  end
35
39
  hash
36
40
  end
37
- end
41
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  class NodeMutation
4
- VERSION = "1.9.3"
4
+ VERSION = "1.10.1"
5
5
  end
data/lib/node_mutation.rb CHANGED
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'ostruct'
4
-
5
3
  require_relative "node_mutation/version"
6
4
 
7
5
  class NodeMutation
@@ -20,12 +18,14 @@ class NodeMutation
20
18
  autoload :ReplaceWithAction, 'node_mutation/action/replace_with_action'
21
19
  autoload :WrapAction, 'node_mutation/action/wrap_action'
22
20
  autoload :NoopAction, 'node_mutation/action/noop_action'
21
+ autoload :Range, 'node_mutation/range'
22
+ autoload :Location, 'node_mutation/location'
23
23
  autoload :Result, 'node_mutation/result'
24
24
  autoload :Strategy, 'node_mutation/strategy'
25
25
 
26
26
  attr_reader :actions
27
27
 
28
- class <<self
28
+ class << self
29
29
  # Configure NodeMutation
30
30
  # @param [Hash] options options to configure
31
31
  # @option options [NodeMutation::Adapter] :adapter the adpater
@@ -220,21 +220,17 @@ class NodeMutation
220
220
  return NodeMutation::Result.new(affected: false, conflicted: false)
221
221
  end
222
222
 
223
- conflict_actions = []
224
223
  source = +@source
225
224
  @actions.sort_by! { |action| [action.start, action.end] }
226
225
  conflict_actions = get_conflict_actions
227
226
  if conflict_actions.size > 0 && strategy?(Strategy::THROW_ERROR)
228
227
  raise ConflictActionError, "mutation actions are conflicted"
229
228
  end
229
+
230
230
  @actions.reverse_each do |action|
231
231
  source[action.start...action.end] = action.new_code if action.new_code
232
232
  end
233
- NodeMutation::Result.new(
234
- affected: true,
235
- conflicted: !conflict_actions.empty?,
236
- new_source: source
237
- )
233
+ NodeMutation::Result.new(affected: true, conflicted: !conflict_actions.empty?, new_source: source)
238
234
  end
239
235
 
240
236
  # Test actions and return the actions.
@@ -249,17 +245,13 @@ class NodeMutation
249
245
  return NodeMutation::Result.new(affected: false, conflicted: false, actions: [])
250
246
  end
251
247
 
252
- conflict_actions = []
253
248
  @actions.sort_by! { |action| [action.start, action.end] }
254
249
  conflict_actions = get_conflict_actions
255
250
  if conflict_actions.size > 0 && strategy?(Strategy::THROW_ERROR)
256
251
  raise ConflictActionError, "mutation actions are conflicted"
257
252
  end
258
- NodeMutation::Result.new(
259
- affected: true,
260
- conflicted: !conflict_actions.empty?,
261
- actions: format_actions(@actions)
262
- )
253
+
254
+ NodeMutation::Result.new(affected: true, conflicted: !conflict_actions.empty?, actions: @actions)
263
255
  end
264
256
 
265
257
  private
@@ -294,8 +286,4 @@ class NodeMutation
294
286
  def strategy?(strategy)
295
287
  NodeMutation.strategy & strategy == strategy
296
288
  end
297
-
298
- def format_actions(actions)
299
- actions.map { |action| OpenStruct.new(start: action.start, end: action.end, new_code: action.new_code ) }
300
- end
301
289
  end
@@ -19,11 +19,12 @@ Gem::Specification.new do |spec|
19
19
 
20
20
  # Specify which files should be added to the gem when it is released.
21
21
  # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
22
- spec.files = Dir.chdir(File.expand_path(__dir__)) do
23
- `git ls-files -z`.split("\x0").reject do |f|
24
- (f == __FILE__) || f.match(%r{\A(?:(?:bin|test|spec|features)/|\.(?:git|travis|circleci)|appveyor)})
22
+ spec.files =
23
+ Dir.chdir(File.expand_path(__dir__)) do
24
+ `git ls-files -z`.split("\x0").reject do |f|
25
+ (f == __FILE__) || f.match(%r{\A(?:(?:bin|test|spec|features)/|\.(?:git|travis|circleci)|appveyor)})
26
+ end
25
27
  end
26
- end
27
28
  spec.bindir = "exe"
28
29
  spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
29
30
  spec.require_paths = ["lib"]
@@ -5,15 +5,15 @@ class NodeMutation::Adapter[T]
5
5
 
6
6
  def file_content: (node: T) -> String
7
7
 
8
- def child_node_range: (node: T, child_name: String) -> OpenStruct
8
+ def child_node_range: (node: T, child_name: String) -> NodeMutation::Range
9
9
 
10
10
  def get_start: (node: T) -> Integer
11
11
 
12
12
  def get_end: (node: T) -> Integer
13
13
 
14
- def get_start_loc: (node: T) -> OpenStruct
14
+ def get_start_loc: (node: T) -> NodeMutation::Location
15
15
 
16
- def get_end_loc: (node: T) -> OpenStruct
16
+ def get_end_loc: (node: T) -> NodeMutation::Location
17
17
 
18
18
  def get_indent: (node: T) -> Integer
19
19
  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.9.3
4
+ version: 1.10.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-02-15 00:00:00.000000000 Z
11
+ date: 2023-03-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: erubis
@@ -51,7 +51,9 @@ files:
51
51
  - lib/node_mutation/action/replace_with_action.rb
52
52
  - lib/node_mutation/action/wrap_action.rb
53
53
  - lib/node_mutation/adapter.rb
54
+ - lib/node_mutation/location.rb
54
55
  - lib/node_mutation/parser_adapter.rb
56
+ - lib/node_mutation/range.rb
55
57
  - lib/node_mutation/result.rb
56
58
  - lib/node_mutation/strategy.rb
57
59
  - lib/node_mutation/version.rb
@@ -80,7 +82,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
80
82
  - !ruby/object:Gem::Version
81
83
  version: '0'
82
84
  requirements: []
83
- rubygems_version: 3.4.1
85
+ rubygems_version: 3.4.6
84
86
  signing_key:
85
87
  specification_version: 4
86
88
  summary: ast node mutation apis