synvert-core 0.27.0 → 0.28.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: 49f00515f034212fb244c270b4d9815e51e5a4d2eb1e91c1cd8c3ddc402fca28
4
- data.tar.gz: 8de939c1e2834259e1aa8af2b17e540221a5e7d0d3f936ad526081db408e994f
3
+ metadata.gz: f8c211d681b7aa05969c2a167eff0f78c27803f354eff7550571b0a5b6ed735a
4
+ data.tar.gz: e66a98377c36ec9931a5e6afb7eb27adb9c52b97e877d442a807c24629729f8f
5
5
  SHA512:
6
- metadata.gz: 12236d2c862b82798e3865755394362e50773ff27505b1ddf08e7308dd51ca0a791b604e8e3cafd768e8d3b957c76bb18ff5d5bd8daded14eef0e2a788c51c36
7
- data.tar.gz: 42b67fd980a096a5d8bffe78ba023c47b18bca34ac3957a631da16bd722b979e8cb9523eaf97e8ca42b870091e4ec81922b866ff8359325f0144766cb9ceb3db
6
+ metadata.gz: a4d24957bb9719dc7ad41ff7a194c199d96a43ffcb539d86000fdcab36754f83ad5da47ecd54d76cbb6e3755c3816c0b59a2b3debcb87896fdb10079535782d1
7
+ data.tar.gz: f489d2cfbaea89bed0349283ced59fd69b9f993336069ec8a711b43fb7c3f82ae4c698c5e9e15eed473dfd0dd3fa34c433ee5af2e9719e5b17a09d84ef808838
data/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # CHANGELOG
2
2
 
3
+ ## 0.28.0 (2021-04-07)
4
+
5
+ * Make `child_name_range` support all dsl nodes
6
+ * Make `replace` action support multi child names
7
+ * Fix `delete` action arguments
8
+
3
9
  ## 0.27.0 (2021-03-31)
4
10
 
5
11
  * Support `:class` in `child_node_range`
@@ -101,9 +101,9 @@ module Parser::AST
101
101
  def arguments
102
102
  case type
103
103
  when :def, :block
104
- ArgumentsNode.new children[1]
104
+ ArgumentsNode.new(children[1])
105
105
  when :defs
106
- ArgumentsNode.new children[2]
106
+ ArgumentsNode.new(children[2])
107
107
  when :send
108
108
  children[2..-1]
109
109
  when :defined?
@@ -322,26 +322,33 @@ module Parser::AST
322
322
  # @param [String] name of child node.
323
323
  # @return [Parser::Source::Range] source range of child node.
324
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.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
325
+ case [type, child_name]
326
+ when [:class, :name]
327
+ loc.name
328
+ when [:def, :name]
329
+ loc.name
330
+ when [:defs, :name]
331
+ loc.name
332
+ when [:defs, :dot]
333
+ loc.operator
334
+ when [:defs, :self]
335
+ Parser::Source::Range.new('(string)', loc.operator.begin_pos - 4, loc.operator.begin_pos)
336
+ when [:send, :dot]
337
+ loc.dot
338
+ when [:send, :message]
339
+ loc.operator ? Parser::Source::Range.new('(string)', loc.selector.begin_pos, loc.operator.end_pos) : loc.selector
344
340
  else
341
+ if respond_to?(child_name)
342
+ child_node = send(child_name)
343
+ return nil if child_node.nil?
344
+ if child_node.is_a?(Parser::AST::Node)
345
+ return Parser::Source::Range.new('(string)', child_node.loc.expression.begin_pos, child_node.loc.expression.end_pos)
346
+ end
347
+ # arguments
348
+ return nil if child_node.empty?
349
+ return Parser::Source::Range.new('(string)', child_node.first.loc.expression.begin_pos, child_node.last.loc.expression.end_pos)
350
+ end
351
+
345
352
  raise Synvert::Core::MethodNotSupported, "child_node_range is not handled for #{evaluated.inspect}, child_name: #{child_name}"
346
353
  end
347
354
  end
@@ -3,9 +3,9 @@
3
3
  module Synvert::Core
4
4
  # ReplaceAction to replace child node with code.
5
5
  class Rewriter::ReplaceAction < Rewriter::Action
6
- def initialize(instance, selector, with:)
6
+ def initialize(instance, *selectors, with:)
7
7
  @instance = instance
8
- @selector = selector
8
+ @selectors = selectors
9
9
  @code = with
10
10
  @node = @instance.current_node
11
11
  end
@@ -14,14 +14,14 @@ module Synvert::Core
14
14
  #
15
15
  # @return [Integer] begin position.
16
16
  def begin_pos
17
- @node.child_node_range(@selector).begin_pos
17
+ @selectors.map { |selector| @node.child_node_range(selector).begin_pos }.min
18
18
  end
19
19
 
20
20
  # End position of code to replace.
21
21
  #
22
22
  # @return [Integer] end position.
23
23
  def end_pos
24
- @node.child_node_range(@selector).end_pos
24
+ @selectors.map { |selector| @node.child_node_range(selector).end_pos }.max
25
25
  end
26
26
 
27
27
  # The rewritten source code.
@@ -252,12 +252,12 @@ module Synvert::Core
252
252
  end
253
253
 
254
254
  # Parse replace with dsl, it creates a [Synvert::Core::Rewriter::ReplaceAction] to
255
- # replace child node with code.
255
+ # replace child nodes with code.
256
256
  #
257
- # @param selector [Symbol] selector name of child name.
257
+ # @param selectors [Array<Symbol>] selector names of child node.
258
258
  # @param with [String] code need to be replaced with.
259
- def replace(selector, with:)
260
- @actions << Rewriter::ReplaceAction.new(self, selector, with: with)
259
+ def replace(*selectors, with:)
260
+ @actions << Rewriter::ReplaceAction.new(self, *selectors, with: with)
261
261
  end
262
262
 
263
263
  # Parse replace_erb_stmt_with_expr dsl, it creates a [Synvert::Core::Rewriter::ReplaceErbStmtWithExprAction] to
@@ -272,7 +272,9 @@ module Synvert::Core
272
272
  end
273
273
 
274
274
  # Parse delete dsl, it creates a [Synvert::Core::Rewriter::DeleteAction] to delete child nodes.
275
- def delete
275
+ #
276
+ # @param selectors [Array<Symbol>] selector names of child node.
277
+ def delete(*selectors)
276
278
  @actions << Rewriter::DeleteAction.new(self, *selectors)
277
279
  end
278
280
 
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Synvert
4
4
  module Core
5
- VERSION = '0.27.0'
5
+ VERSION = '0.28.0'
6
6
  end
7
7
  end
@@ -395,6 +395,78 @@ describe Parser::AST::Node do
395
395
  end
396
396
 
397
397
  describe '#child_node_range' do
398
+ context 'block node' do
399
+ it 'checks caller' do
400
+ node = parse('Factory.define :user do |user|; end')
401
+ range = node.child_node_range(:caller)
402
+ expect(range.to_range).to eq(0...20)
403
+ end
404
+
405
+ it 'checks arguments' do
406
+ node = parse('Factory.define :user do |user|; end')
407
+ range = node.child_node_range(:arguments)
408
+ expect(range.to_range).to eq(25...29)
409
+ end
410
+ end
411
+
412
+ context 'class node' do
413
+ it 'checks name' do
414
+ node = parse('class Post < ActiveRecord::Base; end')
415
+ range = node.child_node_range(:name)
416
+ expect(range.to_range).to eq(6...10)
417
+ end
418
+
419
+ it 'checks parent_class' do
420
+ node = parse('class Post < ActiveRecord::Base; end')
421
+ range = node.child_node_range(:parent_class)
422
+ expect(range.to_range).to eq(13...31)
423
+
424
+ node = parse('class Post; end')
425
+ range = node.child_node_range(:parent_class)
426
+ expect(range).to be_nil
427
+ end
428
+ end
429
+
430
+ context 'def node' do
431
+ it 'checks name' do
432
+ node = parse('def foo(bar); end')
433
+ range = node.child_node_range(:name)
434
+ expect(range.to_range).to eq(4...7)
435
+ end
436
+
437
+ it 'checks arguments' do
438
+ node = parse('def foo(bar); end')
439
+ range = node.child_node_range(:arguments)
440
+ expect(range.to_range).to eq(8...11)
441
+ end
442
+ end
443
+
444
+ context 'defs node' do
445
+ it 'checks self' do
446
+ node = parse('def self.foo(bar); end')
447
+ range = node.child_node_range(:self)
448
+ expect(range.to_range).to eq(4...8)
449
+ end
450
+
451
+ it 'checks dot' do
452
+ node = parse('def self.foo(bar); end')
453
+ range = node.child_node_range(:dot)
454
+ expect(range.to_range).to eq(8...9)
455
+ end
456
+
457
+ it 'checks name' do
458
+ node = parse('def self.foo(bar); end')
459
+ range = node.child_node_range(:name)
460
+ expect(range.to_range).to eq(9...12)
461
+ end
462
+
463
+ it 'checks arguments' do
464
+ node = parse('def self.foo(bar); end')
465
+ range = node.child_node_range(:arguments)
466
+ expect(range.to_range).to eq(13...16)
467
+ end
468
+ end
469
+
398
470
  context 'send node' do
399
471
  it 'checks receiver' do
400
472
  node = parse('foo.bar(test)')
@@ -421,6 +493,10 @@ describe Parser::AST::Node do
421
493
  range = node.child_node_range(:message)
422
494
  expect(range.to_range).to eq(4...7)
423
495
 
496
+ node = parse('foo.bar = test')
497
+ range = node.child_node_range(:message)
498
+ expect(range.to_range).to eq(4...9)
499
+
424
500
  node = parse('foobar(test)')
425
501
  range = node.child_node_range(:message)
426
502
  expect(range.to_range).to eq(0...6)
@@ -440,24 +516,6 @@ describe Parser::AST::Node do
440
516
  expect(range).to be_nil
441
517
  end
442
518
  end
443
-
444
- context 'class node' do
445
- it 'checks name' do
446
- node = parse('class Post < ActiveRecord::Base; end')
447
- range = node.child_node_range(:name)
448
- expect(range.to_range).to eq(6...10)
449
- end
450
-
451
- it 'checks parent_class' do
452
- node = parse('class Post < ActiveRecord::Base; end')
453
- range = node.child_node_range(:parent_class)
454
- expect(range.to_range).to eq(13...31)
455
-
456
- node = parse('class Post; end')
457
- range = node.child_node_range(:parent_class)
458
- expect(range).to be_nil
459
- end
460
- end
461
519
  end
462
520
 
463
521
  describe '#rewritten_source' do
@@ -6,22 +6,22 @@ module Synvert::Core
6
6
  describe Rewriter::ReplaceAction do
7
7
  context 'replace with single line' do
8
8
  subject {
9
- source = "'slug from title'.gsub(' ', '_')"
9
+ source = "FactoryBot.create(:user)"
10
10
  node = Parser::CurrentRuby.parse(source)
11
11
  instance = double(current_node: node)
12
- Rewriter::ReplaceAction.new(instance, :message, with: 'tr')
12
+ Rewriter::ReplaceAction.new(instance, :receiver, :dot, :message, with: 'create')
13
13
  }
14
14
 
15
15
  it 'gets begin_pos' do
16
- expect(subject.begin_pos).to eq "'slug from title'.".length
16
+ expect(subject.begin_pos).to eq 0
17
17
  end
18
18
 
19
19
  it 'gets end_pos' do
20
- expect(subject.end_pos).to eq "'slug from title'.gsub".length
20
+ expect(subject.end_pos).to eq "FactoryBot.create".length
21
21
  end
22
22
 
23
23
  it 'gets rewritten_code' do
24
- expect(subject.rewritten_code).to eq 'tr'
24
+ expect(subject.rewritten_code).to eq 'create'
25
25
  end
26
26
  end
27
27
  end
@@ -127,6 +127,11 @@ module Synvert::Core
127
127
  instance.remove
128
128
  end
129
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
+
130
135
  it 'parses warn' do
131
136
  expect(Rewriter::Warning).to receive(:new).with(instance, 'foobar')
132
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.27.0
4
+ version: 0.28.0
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-31 00:00:00.000000000 Z
11
+ date: 2021-04-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport