node_mutation 1.9.3 → 1.10.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: 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