synvert-core 0.25.1 → 0.27.2

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: 1aab544b0a434d8d34f445906448203f8ebf670f2e3fc14ac791163c1c059bbb
4
- data.tar.gz: c913b856a8281cbd07ac6ca59fea393a633b3d920b0849b9a9f16dd897989b0f
3
+ metadata.gz: afa25ca6412906c13399aa27967676033670bcbab36910a7bd528e3a9948e61d
4
+ data.tar.gz: f5844fee19d2aec45fd24b50af95decb53b7b33c90e2c83fad4fb62d565d0782
5
5
  SHA512:
6
- metadata.gz: cc0c4ea16085329d3385227885af3fc10fc925be5abe0bf408afa89ee95d5aba048225be488b8624dd0cdb7c6c0b4ed994f9d8c66aa8891c252eaf5784e3f06c
7
- data.tar.gz: d3a6ac011d673c981cc59e34ad0bbcba5c5042a5bc20ea15a46d6c77b775d8f682d212951ec8503432473044e2f58c80342810fe9d4521cf405bf719e845bdd3
6
+ metadata.gz: 2d188889dec4144d5508fc2ff3f9c6356703354cc1d37464a4d59fa406c56095fd1be796c5ffa474263bcb9a232f2ebbf48796de778fe80bbfe0a18137b7d048
7
+ data.tar.gz: 85a83b35f0b9c60682d75647a63eff485eff55cf41e46e12b7849b00d098c1268e615eee9d363e3ce068c8c4239e05bc499a86cb73d4ba70d1c986366e2f96a0
data/CHANGELOG.md CHANGED
@@ -1,8 +1,22 @@
1
1
  # CHANGELOG
2
2
 
3
- ## 0.25.1 (2021-03-24)
3
+ ## 0.27.2 (2021-03-31)
4
+
5
+ * Fix selector with operator in `child_node_range`
6
+
7
+ ## 0.27.1 (2021-03-31)
8
+
9
+ * Fix `delete` action arguments
10
+
11
+ ## 0.27.0 (2021-03-31)
12
+
13
+ * Support `:class` in `child_node_range`
14
+ * Add `delete` action
15
+
16
+ ## 0.26.0 (2021-03-30)
4
17
 
5
18
  * attr_reader ruby_version and gem_spec
19
+ * Add `replace` action
6
20
 
7
21
  ## 0.25.0 (2021-03-23)
8
22
 
@@ -317,6 +317,35 @@ module Parser::AST
317
317
  loc.expression.line
318
318
  end
319
319
 
320
+ # Get the source range of child node.
321
+ #
322
+ # @param [String] name of child node.
323
+ # @return [Parser::Source::Range] source range of child node.
324
+ def child_node_range(child_name)
325
+ case type
326
+ when :class
327
+ case child_name
328
+ when :name
329
+ loc.name
330
+ when :parent_class
331
+ parent_class&.loc&.expression
332
+ end
333
+ when :send
334
+ case child_name
335
+ when :receiver
336
+ receiver&.loc&.expression
337
+ when :dot
338
+ loc.dot
339
+ when :message
340
+ loc.operator ? Parser::Source::Range.new('(string)', loc.selector.begin_pos, loc.operator.end_pos) : loc.selector
341
+ when :arguments
342
+ Parser::Source::Range.new('(string)', arguments.first.loc.expression.begin_pos, arguments.last.loc.expression.end_pos) unless arguments.empty?
343
+ end
344
+ else
345
+ raise Synvert::Core::MethodNotSupported, "child_node_range is not handled for #{evaluated.inspect}, child_name: #{child_name}"
346
+ end
347
+ end
348
+
320
349
  # Recursively iterate all child nodes of current node.
321
350
  #
322
351
  # @yield [child] Gives a child node.
@@ -21,8 +21,10 @@ module Synvert::Core
21
21
  autoload :InsertAction, 'synvert/core/rewriter/action/insert_action'
22
22
  autoload :InsertAfterAction, 'synvert/core/rewriter/action/insert_after_action'
23
23
  autoload :ReplaceWithAction, 'synvert/core/rewriter/action/replace_with_action'
24
+ autoload :ReplaceAction, 'synvert/core/rewriter/action/replace_action'
24
25
  autoload :ReplaceErbStmtWithExprAction, 'synvert/core/rewriter/action/replace_erb_stmt_with_expr_action'
25
26
  autoload :RemoveAction, 'synvert/core/rewriter/action/remove_action'
27
+ autoload :DeleteAction, 'synvert/core/rewriter/action/delete_action'
26
28
 
27
29
  autoload :Warning, 'synvert/core/rewriter/warning'
28
30
 
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Synvert::Core
4
+ # RemoveAction to delete code.
5
+ class Rewriter::DeleteAction < Rewriter::Action
6
+ def initialize(instance, *selectors)
7
+ super(instance, nil)
8
+ @selectors = selectors
9
+ end
10
+
11
+ # Begin position of code to replace.
12
+ #
13
+ # @return [Integer] begin position.
14
+ def begin_pos
15
+ @selectors.map { |selector| @node.child_node_range(selector).begin_pos }.min
16
+ end
17
+
18
+ # End position of code to replace.
19
+ #
20
+ # @return [Integer] end position.
21
+ def end_pos
22
+ @selectors.map { |selector| @node.child_node_range(selector).end_pos }.max
23
+ end
24
+
25
+ # The rewritten code, always empty string.
26
+ def rewritten_code
27
+ ''
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Synvert::Core
4
+ # ReplaceAction to replace child node with code.
5
+ class Rewriter::ReplaceAction < Rewriter::Action
6
+ def initialize(instance, selector, with:)
7
+ @instance = instance
8
+ @selector = selector
9
+ @code = with
10
+ @node = @instance.current_node
11
+ end
12
+
13
+ # Begin position of code to replace.
14
+ #
15
+ # @return [Integer] begin position.
16
+ def begin_pos
17
+ @node.child_node_range(@selector).begin_pos
18
+ end
19
+
20
+ # End position of code to replace.
21
+ #
22
+ # @return [Integer] end position.
23
+ def end_pos
24
+ @node.child_node_range(@selector).end_pos
25
+ end
26
+
27
+ # The rewritten source code.
28
+ #
29
+ # @return [String] rewritten code.
30
+ def rewritten_code
31
+ rewritten_source
32
+ end
33
+ end
34
+ end
@@ -251,17 +251,33 @@ module Synvert::Core
251
251
  @actions << Rewriter::ReplaceWithAction.new(self, code, options)
252
252
  end
253
253
 
254
+ # Parse replace with dsl, it creates a [Synvert::Core::Rewriter::ReplaceAction] to
255
+ # replace child node with code.
256
+ #
257
+ # @param selector [Symbol] selector name of child node.
258
+ # @param with [String] code need to be replaced with.
259
+ def replace(selector, with:)
260
+ @actions << Rewriter::ReplaceAction.new(self, selector, with: with)
261
+ end
262
+
254
263
  # Parse replace_erb_stmt_with_expr dsl, it creates a [Synvert::Core::Rewriter::ReplaceErbStmtWithExprAction] to
255
264
  # replace erb stmt code to expr code.
256
265
  def replace_erb_stmt_with_expr
257
266
  @actions << Rewriter::ReplaceErbStmtWithExprAction.new(self)
258
267
  end
259
268
 
260
- # Parse remove dsl, it creates a [Synvert::Core::Rewriter::RemoveAction] to current node.
269
+ # Parse remove dsl, it creates a [Synvert::Core::Rewriter::RemoveAction] to remove current node.
261
270
  def remove
262
271
  @actions << Rewriter::RemoveAction.new(self)
263
272
  end
264
273
 
274
+ # Parse delete dsl, it creates a [Synvert::Core::Rewriter::DeleteAction] to delete child nodes.
275
+ #
276
+ # @param selectors [Array<Symbol>] selector names of child node.
277
+ def delete(*selectors)
278
+ @actions << Rewriter::DeleteAction.new(self, *selectors)
279
+ end
280
+
265
281
  # Parse warn dsl, it creates a [Synvert::Core::Rewriter::Warning] to save warning message.
266
282
  #
267
283
  # @param message [String] warning message.
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Synvert
4
4
  module Core
5
- VERSION = '0.25.1'
5
+ VERSION = '0.27.2'
6
6
  end
7
7
  end
@@ -394,6 +394,76 @@ describe Parser::AST::Node do
394
394
  end
395
395
  end
396
396
 
397
+ describe '#child_node_range' do
398
+ context 'send node' do
399
+ it 'checks receiver' do
400
+ node = parse('foo.bar(test)')
401
+ range = node.child_node_range(:receiver)
402
+ expect(range.to_range).to eq(0...3)
403
+
404
+ node = parse('foobar(test)')
405
+ range = node.child_node_range(:receiver)
406
+ expect(range).to be_nil
407
+ end
408
+
409
+ it 'checks dot' do
410
+ node = parse('foo.bar(test)')
411
+ range = node.child_node_range(:dot)
412
+ expect(range.to_range).to eq(3...4)
413
+
414
+ node = parse('foobar(test)')
415
+ range = node.child_node_range(:dot)
416
+ expect(range).to be_nil
417
+ end
418
+
419
+ it 'checks message' do
420
+ node = parse('foo.bar(test)')
421
+ range = node.child_node_range(:message)
422
+ expect(range.to_range).to eq(4...7)
423
+
424
+ node = parse('foo.bar = test')
425
+ range = node.child_node_range(:message)
426
+ expect(range.to_range).to eq(4...9)
427
+
428
+ node = parse('foobar(test)')
429
+ range = node.child_node_range(:message)
430
+ expect(range.to_range).to eq(0...6)
431
+ end
432
+
433
+ it 'checks arguments' do
434
+ node = parse('foo.bar(test)')
435
+ range = node.child_node_range(:arguments)
436
+ expect(range.to_range).to eq(8...12)
437
+
438
+ node = parse('foobar(test)')
439
+ range = node.child_node_range(:arguments)
440
+ expect(range.to_range).to eq(7...11)
441
+
442
+ node = parse('foo.bar')
443
+ range = node.child_node_range(:arguments)
444
+ expect(range).to be_nil
445
+ end
446
+ end
447
+
448
+ context 'class node' do
449
+ it 'checks name' do
450
+ node = parse('class Post < ActiveRecord::Base; end')
451
+ range = node.child_node_range(:name)
452
+ expect(range.to_range).to eq(6...10)
453
+ end
454
+
455
+ it 'checks parent_class' do
456
+ node = parse('class Post < ActiveRecord::Base; end')
457
+ range = node.child_node_range(:parent_class)
458
+ expect(range.to_range).to eq(13...31)
459
+
460
+ node = parse('class Post; end')
461
+ range = node.child_node_range(:parent_class)
462
+ expect(range).to be_nil
463
+ end
464
+ end
465
+ end
466
+
397
467
  describe '#rewritten_source' do
398
468
  let(:instance) {
399
469
  rewriter = Synvert::Rewriter.new('foo', 'bar')
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ module Synvert::Core
6
+ describe Rewriter::DeleteAction do
7
+ subject {
8
+ source = "arr.map {}.flatten"
9
+ node = Parser::CurrentRuby.parse(source)
10
+ instance = double(current_node: node)
11
+ Rewriter::DeleteAction.new(instance, :dot, :message)
12
+ }
13
+
14
+ it 'gets begin_pos' do
15
+ expect(subject.begin_pos).to eq "arr.map {}".length
16
+ end
17
+
18
+ it 'gets end_pos' do
19
+ expect(subject.end_pos).to eq "arr.map {}.flatten".length
20
+ end
21
+
22
+ it 'gets rewritten_code' do
23
+ expect(subject.rewritten_code).to eq ''
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ module Synvert::Core
6
+ describe Rewriter::ReplaceAction do
7
+ context 'replace with single line' do
8
+ subject {
9
+ source = "'slug from title'.gsub(' ', '_')"
10
+ node = Parser::CurrentRuby.parse(source)
11
+ instance = double(current_node: node)
12
+ Rewriter::ReplaceAction.new(instance, :message, with: 'tr')
13
+ }
14
+
15
+ it 'gets begin_pos' do
16
+ expect(subject.begin_pos).to eq "'slug from title'.".length
17
+ end
18
+
19
+ it 'gets end_pos' do
20
+ expect(subject.end_pos).to eq "'slug from title'.gsub".length
21
+ end
22
+
23
+ it 'gets rewritten_code' do
24
+ expect(subject.rewritten_code).to eq 'tr'
25
+ end
26
+ end
27
+ end
28
+ end
@@ -117,11 +117,21 @@ module Synvert::Core
117
117
  instance.replace_with 'create {{arguments}}'
118
118
  end
119
119
 
120
+ it 'parses replace with' do
121
+ expect(Rewriter::ReplaceAction).to receive(:new).with(instance, :message, with: 'test')
122
+ instance.replace :message, with: 'test'
123
+ end
124
+
120
125
  it 'parses remove' do
121
126
  expect(Rewriter::RemoveAction).to receive(:new).with(instance)
122
127
  instance.remove
123
128
  end
124
129
 
130
+ it 'parses remove' do
131
+ expect(Rewriter::DeleteAction).to receive(:new).with(instance, :dot, :message)
132
+ instance.delete :dot, :message
133
+ end
134
+
125
135
  it 'parses warn' do
126
136
  expect(Rewriter::Warning).to receive(:new).with(instance, 'foobar')
127
137
  instance.warn 'foobar'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: synvert-core
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.25.1
4
+ version: 0.27.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Richard Huang
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-03-24 00:00:00.000000000 Z
11
+ date: 2021-03-31 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -147,9 +147,11 @@ files:
147
147
  - lib/synvert/core/rewriter.rb
148
148
  - lib/synvert/core/rewriter/action.rb
149
149
  - lib/synvert/core/rewriter/action/append_action.rb
150
+ - lib/synvert/core/rewriter/action/delete_action.rb
150
151
  - lib/synvert/core/rewriter/action/insert_action.rb
151
152
  - lib/synvert/core/rewriter/action/insert_after_action.rb
152
153
  - lib/synvert/core/rewriter/action/remove_action.rb
154
+ - lib/synvert/core/rewriter/action/replace_action.rb
153
155
  - lib/synvert/core/rewriter/action/replace_erb_stmt_with_expr_action.rb
154
156
  - lib/synvert/core/rewriter/action/replace_with_action.rb
155
157
  - lib/synvert/core/rewriter/condition.rb
@@ -170,9 +172,11 @@ files:
170
172
  - spec/synvert/core/engine/erb_spec.rb
171
173
  - spec/synvert/core/node_ext_spec.rb
172
174
  - spec/synvert/core/rewriter/action/append_action_spec.rb
175
+ - spec/synvert/core/rewriter/action/delete_action_spec.rb
173
176
  - spec/synvert/core/rewriter/action/insert_action_spec.rb
174
177
  - spec/synvert/core/rewriter/action/insert_after_action_spec.rb
175
178
  - spec/synvert/core/rewriter/action/remove_action_spec.rb
179
+ - spec/synvert/core/rewriter/action/replace_action_spec.rb
176
180
  - spec/synvert/core/rewriter/action/replace_erb_stmt_with_expr_action_spec.rb
177
181
  - spec/synvert/core/rewriter/action/replace_with_action_spec.rb
178
182
  - spec/synvert/core/rewriter/action_spec.rb
@@ -219,9 +223,11 @@ test_files:
219
223
  - spec/synvert/core/engine/erb_spec.rb
220
224
  - spec/synvert/core/node_ext_spec.rb
221
225
  - spec/synvert/core/rewriter/action/append_action_spec.rb
226
+ - spec/synvert/core/rewriter/action/delete_action_spec.rb
222
227
  - spec/synvert/core/rewriter/action/insert_action_spec.rb
223
228
  - spec/synvert/core/rewriter/action/insert_after_action_spec.rb
224
229
  - spec/synvert/core/rewriter/action/remove_action_spec.rb
230
+ - spec/synvert/core/rewriter/action/replace_action_spec.rb
225
231
  - spec/synvert/core/rewriter/action/replace_erb_stmt_with_expr_action_spec.rb
226
232
  - spec/synvert/core/rewriter/action/replace_with_action_spec.rb
227
233
  - spec/synvert/core/rewriter/action_spec.rb