synvert-core 0.61.0 → 0.62.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: ff83abb1009ca5d9fe97a1c2e64701c31942a1c235e2b5a9bfe6cec1875f0956
4
- data.tar.gz: b983862aa7a7861801104d43dc19cd794a5b83e4c2be5b137888b2e92a6f8068
3
+ metadata.gz: 79777679e6001f32c8b4bc587e2f007f396eeecd9c0c7e29926e01a3628b4244
4
+ data.tar.gz: df4d3eda62e9b2f49ec1cf8da96bd98952d7d5af70fd4d6861b206bbc923cca9
5
5
  SHA512:
6
- metadata.gz: 6978c684ad91c8a59c9774129c5ab21162b66f4f3b4eb043337a008c2dd5a5df3634b7781442d03147ae8829b250bd73f279b31379f6b3861e852da75209ba26
7
- data.tar.gz: 96299eb5b9b6254a3781abaff6e3d9f2ac6e1da8e1216b17990471558408bf6ceecb439175183819f3aadd860de94754639c4434705910469318e91abd57f124
6
+ metadata.gz: c9744e62dc972253304018ac041aa1f4cd01efd8a80a207a77145e088d4d69713ef4ec10ade9fe4d251811b6a8166d8e33b575ea91265fbec4f989a9e29ac376
7
+ data.tar.gz: cad73e2d256e25370b535a0f623fee47c02f4d5a56e3feaed50f81a798cf3c1dbb0ffd4d6ad04ab167be78fc390703a2a01f0377b79ea621f1674399aa2c7534
@@ -19,7 +19,7 @@ jobs:
19
19
  runs-on: ubuntu-latest
20
20
  strategy:
21
21
  matrix:
22
- ruby-version: ['2.5', '2.6', '2.7', '3.0']
22
+ ruby-version: ['2.5', '2.6', '2.7', '3.0', '3.1']
23
23
 
24
24
  steps:
25
25
  - uses: actions/checkout@v2
@@ -29,4 +29,4 @@ jobs:
29
29
  ruby-version: ${{ matrix.ruby-version }}
30
30
  bundler-cache: true
31
31
  - name: Run tests
32
- run: bundle exec rake
32
+ run: bundle exec rake
data/CHANGELOG.md CHANGED
@@ -1,5 +1,16 @@
1
1
  # CHANGELOG
2
2
 
3
+ ## 0.62.1 (2022-01-14)
4
+
5
+ * Add `to` option to `InsertAction`
6
+
7
+ ## 0.62.0 (2021-12-24)
8
+
9
+ * Support `csend` node
10
+ * Restrict `activesupport` version to `~> 6`
11
+ * Fix `prepend` action for `def` and `defs` nodes
12
+ * Fix `append` action for `def` and `defs` nodes
13
+
3
14
  ## 0.61.0 (2021-12-10)
4
15
 
5
16
  * Add `Node#child_node_by_name`
@@ -49,7 +49,7 @@ module Parser::AST
49
49
  # @return [Parser::AST::Node] receiver node.
50
50
  # @raise [Synvert::Core::MethodNotSupported] if calls on other node.
51
51
  def receiver
52
- if :send == type
52
+ if %i[csend send].include?(type)
53
53
  children[0]
54
54
  else
55
55
  raise Synvert::Core::MethodNotSupported, "receiver is not handled for #{debug_info}"
@@ -64,7 +64,7 @@ module Parser::AST
64
64
  case type
65
65
  when :super, :zsuper
66
66
  :super
67
- when :send
67
+ when :send, :csend
68
68
  children[1]
69
69
  else
70
70
  raise Synvert::Core::MethodNotSupported, "message is not handled for #{debug_info}"
@@ -81,7 +81,7 @@ module Parser::AST
81
81
  children[1]
82
82
  when :defs
83
83
  children[2]
84
- when :send
84
+ when :send, :csend
85
85
  children[2..-1]
86
86
  when :defined?
87
87
  children
@@ -400,15 +400,15 @@ module Parser::AST
400
400
  loc.operator
401
401
  when %i[defs self]
402
402
  Parser::Source::Range.new('(string)', loc.operator.begin_pos - 'self'.length, loc.operator.begin_pos)
403
- when %i[send dot]
403
+ when %i[send dot], %i[csend dot]
404
404
  loc.dot
405
- when %i[send message]
405
+ when %i[send message], %i[csend message]
406
406
  if loc.operator
407
407
  Parser::Source::Range.new('(string)', loc.selector.begin_pos, loc.operator.end_pos)
408
408
  else
409
409
  loc.selector
410
410
  end
411
- when %i[send parentheses]
411
+ when %i[send parentheses], %i[csend parentheses]
412
412
  if loc.begin && loc.end
413
413
  Parser::Source::Range.new('(string)', loc.begin.begin_pos, loc.end.end_pos)
414
414
  end
@@ -593,7 +593,7 @@ module Parser::AST
593
593
  def to_string
594
594
  return to_source unless type == :sym
595
595
 
596
- "#{to_value}"
596
+ to_value.to_s
597
597
  end
598
598
 
599
599
  # convert lambda {} to -> {}
@@ -17,7 +17,7 @@ module Synvert::Core
17
17
  # @param node [Parser::AST::Node]
18
18
  # @return [String] n times whitesphace
19
19
  def indent(node)
20
- if %i[block class].include? node.type
20
+ if %i[block class def defs].include? node.type
21
21
  ' ' * (node.column + DEFAULT_INDENT)
22
22
  else
23
23
  ' ' * node.column
@@ -3,13 +3,15 @@
3
3
  module Synvert::Core
4
4
  # InsertAction to add code to the node.
5
5
  class Rewriter::InsertAction < Rewriter::Action
6
- def initialize(instance, code, at:)
6
+ def initialize(instance, code, at:, to: nil)
7
7
  super(instance, code)
8
8
  @at = at
9
+ @to = to
9
10
  end
10
11
 
11
12
  def calculate_position
12
- @begin_pos = @at == 'end' ? @node.loc.expression.end_pos : @node.loc.expression.begin_pos
13
+ node_range = @to ? @node.child_node_range(@to) : @node.loc.expression
14
+ @begin_pos = @at == 'end' ? node_range.end_pos : node_range.begin_pos
13
15
  @end_pos = @begin_pos
14
16
  end
15
17
 
@@ -16,6 +16,10 @@ module Synvert::Core
16
16
  end
17
17
  when :class
18
18
  @node.children[1] ? @node.children[1].loc.expression.end_pos : @node.children[0].loc.expression.end_pos
19
+ when :def
20
+ @node.children[1].empty? ? @node.loc.name.end_pos : @node.children[1].loc.expression.end_pos
21
+ when :defs
22
+ @node.children[2].empty? ? @node.loc.name.end_pos : @node.children[2].loc.expression.end_pos
19
23
  else
20
24
  @node.children.last.loc.expression.end_pos
21
25
  end
@@ -29,7 +33,7 @@ module Synvert::Core
29
33
  # @param node [Parser::AST::Node]
30
34
  # @return [String] n times whitesphace
31
35
  def indent(node)
32
- if %i[block class].include? node.type
36
+ if %i[block class def defs].include?(node.type)
33
37
  ' ' * (node.column + DEFAULT_INDENT)
34
38
  else
35
39
  ' ' * node.column
@@ -240,8 +240,9 @@ module Synvert::Core
240
240
  #
241
241
  # @param code [String] code need to be inserted.
242
242
  # @param at [String] insert position, beginning or end, end is the default.
243
- def insert(code, at: 'end')
244
- @actions << Rewriter::InsertAction.new(self, code, at: at).process
243
+ # @param to [String] where to insert, if it is nil, will insert to current node.
244
+ def insert(code, at: 'end', to: nil)
245
+ @actions << Rewriter::InsertAction.new(self, code, at: at, to: to).process
245
246
  end
246
247
 
247
248
  # Parse insert_after dsl, it creates a [Synvert::Core::Rewriter::InsertAfterAction] to
@@ -81,11 +81,10 @@ module Synvert::Core
81
81
  def fetch(group, name)
82
82
  group = group.to_s
83
83
  name = name.to_s
84
- if rewriters[group] && rewriters[group][name]
85
- rewriters[group][name]
86
- else
87
- raise RewriterNotFound, "Rewriter #{group} #{name} not found"
88
- end
84
+ rewriter = rewriters.dig(group, name)
85
+ raise RewriterNotFound, "Rewriter #{group} #{name} not found" unless rewriter
86
+
87
+ rewriter
89
88
  end
90
89
 
91
90
  # Get a registered rewriter by group and name, then process that rewriter.
@@ -166,9 +165,8 @@ module Synvert::Core
166
165
  def process
167
166
  @affected_files = Set.new
168
167
  instance_eval(&@block)
169
- if !@affected_files.empty? && @redo_until_no_change
170
- process
171
- end
168
+
169
+ process if !@affected_files.empty? && @redo_until_no_change # redo
172
170
  end
173
171
 
174
172
  # Process rewriter with sandbox mode.
@@ -236,9 +234,10 @@ module Synvert::Core
236
234
  def within_files(file_patterns, &block)
237
235
  return if @sandbox
238
236
 
239
- if (!@ruby_version || @ruby_version.match?) && (!@gem_spec || @gem_spec.match?)
240
- Rewriter::Instance.new(self, Array(file_patterns), &block).process
241
- end
237
+ return if @ruby_version && !@ruby_version.match?
238
+ return if @gem_spec && !@gem_spec.match?
239
+
240
+ Rewriter::Instance.new(self, Array(file_patterns), &block).process
242
241
  end
243
242
 
244
243
  # Parse within_file dsl, it finds a specifiled file.
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Synvert
4
4
  module Core
5
- VERSION = '0.61.0'
5
+ VERSION = '0.62.1'
6
6
  end
7
7
  end
data/lib/synvert/core.rb CHANGED
@@ -5,6 +5,7 @@ require 'bundler'
5
5
  require 'parser'
6
6
  require 'parser/current'
7
7
  require 'ast'
8
+ require 'active_support'
8
9
  require 'active_support/core_ext/object'
9
10
  require 'active_support/core_ext/array'
10
11
  require 'erubis'
@@ -80,6 +80,11 @@ describe Parser::AST::Node do
80
80
  node = parse('FactoryGirl.create :post')
81
81
  expect(node.receiver).to eq parse('FactoryGirl')
82
82
  end
83
+
84
+ it 'gets for csend node' do
85
+ node = parse('user&.update(name: name)')
86
+ expect(node.receiver).to eq parse('user')
87
+ end
83
88
  end
84
89
 
85
90
  describe '#message' do
@@ -88,6 +93,11 @@ describe Parser::AST::Node do
88
93
  expect(node.message).to eq :create
89
94
  end
90
95
 
96
+ it 'gets for csend node' do
97
+ node = parse('user&.update(name: name)')
98
+ expect(node.message).to eq :update
99
+ end
100
+
91
101
  it 'gets for super node' do
92
102
  node = parse('super(params)')
93
103
  expect(node.message).to eq :super
@@ -137,6 +147,11 @@ describe Parser::AST::Node do
137
147
  expect(node.arguments).to eq parse("[:post, title: 'post']").children
138
148
  end
139
149
 
150
+ it 'gets for csend node' do
151
+ node = parse('user&.update(name: name)')
152
+ expect(node.arguments).to eq parse('[name: name]').children
153
+ end
154
+
140
155
  it 'gets for defined? node' do
141
156
  node = parse('defined?(Bundler)')
142
157
  expect(node.arguments).to eq [parse('Bundler')]
@@ -653,6 +668,50 @@ describe Parser::AST::Node do
653
668
  end
654
669
  end
655
670
 
671
+ context 'csend node' do
672
+ it 'checks receiver' do
673
+ node = parse('foo&.bar(test)')
674
+ range = node.child_node_range(:receiver)
675
+ expect(range.to_range).to eq(0...3)
676
+ end
677
+
678
+ it 'checks dot' do
679
+ node = parse('foo&.bar(test)')
680
+ range = node.child_node_range(:dot)
681
+ expect(range.to_range).to eq(3...5)
682
+ end
683
+
684
+ it 'checks message' do
685
+ node = parse('foo&.bar(test)')
686
+ range = node.child_node_range(:message)
687
+ expect(range.to_range).to eq(5...8)
688
+
689
+ node = parse('foo&.bar = test')
690
+ range = node.child_node_range(:message)
691
+ expect(range.to_range).to eq(5...10)
692
+ end
693
+
694
+ it 'checks arguments' do
695
+ node = parse('foo&.bar(test)')
696
+ range = node.child_node_range(:arguments)
697
+ expect(range.to_range).to eq(9...13)
698
+
699
+ node = parse('foo&.bar')
700
+ range = node.child_node_range(:arguments)
701
+ expect(range).to be_nil
702
+ end
703
+
704
+ it 'checks parentheses' do
705
+ node = parse('foo&.bar(test)')
706
+ range = node.child_node_range(:parentheses)
707
+ expect(range.to_range).to eq(8...14)
708
+
709
+ node = parse('foo&.bar')
710
+ range = node.child_node_range(:parentheses)
711
+ expect(range).to be_nil
712
+ end
713
+ end
714
+
656
715
  context 'def node' do
657
716
  it 'checks name' do
658
717
  node = parse('def foo(bar); end')
@@ -45,5 +45,26 @@ module Synvert::Core
45
45
  expect(subject.rewritten_code).to eq "\ngem 'twitter'"
46
46
  end
47
47
  end
48
+
49
+ describe 'def node' do
50
+ subject do
51
+ source = "def teardown\n do_something\nend"
52
+ class_node = Parser::CurrentRuby.parse(source)
53
+ instance = double(current_node: class_node)
54
+ Rewriter::AppendAction.new(instance, 'super').process
55
+ end
56
+
57
+ it 'gets begin_pos' do
58
+ expect(subject.begin_pos).to eq "def teardown\n do_something".length
59
+ end
60
+
61
+ it 'gets end_pos' do
62
+ expect(subject.end_pos).to eq "def teardown\n do_something".length
63
+ end
64
+
65
+ it 'gets rewritten_code' do
66
+ expect(subject.rewritten_code).to eq "\n super"
67
+ end
68
+ end
48
69
  end
49
70
  end
@@ -45,5 +45,26 @@ module Synvert::Core
45
45
  expect(subject.rewritten_code).to eq 'URI.'
46
46
  end
47
47
  end
48
+
49
+ context 'to receiver' do
50
+ subject {
51
+ source = "User.where(username: 'Richard')"
52
+ node = Parser::CurrentRuby.parse(source)
53
+ instance = double(current_node: node)
54
+ Rewriter::InsertAction.new(instance, '.active', to: 'receiver', at: 'end').process
55
+ }
56
+
57
+ it 'gets begin_pos' do
58
+ expect(subject.begin_pos).to eq "User".length
59
+ end
60
+
61
+ it 'gets end_pos' do
62
+ expect(subject.end_pos).to eq "User".length
63
+ end
64
+
65
+ it 'gets rewritten_code' do
66
+ expect(subject.rewritten_code).to eq '.active'
67
+ end
68
+ end
48
69
  end
49
70
  end
@@ -87,5 +87,89 @@ module Synvert::Core
87
87
  expect(subject.rewritten_code).to eq "\n include Deletable"
88
88
  end
89
89
  end
90
+
91
+ describe 'def node without args' do
92
+ subject do
93
+ source = "def setup\n do_something\nend"
94
+ def_node = Parser::CurrentRuby.parse(source)
95
+ instance = double(current_node: def_node)
96
+ Rewriter::PrependAction.new(instance, 'super').process
97
+ end
98
+
99
+ it 'gets begin_pos' do
100
+ expect(subject.begin_pos).to eq 'def setup'.length
101
+ end
102
+
103
+ it 'gets end_pos' do
104
+ expect(subject.end_pos).to eq 'def setup'.length
105
+ end
106
+
107
+ it 'gets rewritten_code' do
108
+ expect(subject.rewritten_code).to eq "\n super"
109
+ end
110
+ end
111
+
112
+ describe 'def node with args' do
113
+ subject do
114
+ source = "def setup(foobar)\n do_something\nend"
115
+ def_node = Parser::CurrentRuby.parse(source)
116
+ instance = double(current_node: def_node)
117
+ Rewriter::PrependAction.new(instance, 'super').process
118
+ end
119
+
120
+ it 'gets begin_pos' do
121
+ expect(subject.begin_pos).to eq 'def setup(foobar)'.length
122
+ end
123
+
124
+ it 'gets end_pos' do
125
+ expect(subject.end_pos).to eq 'def setup(foobar)'.length
126
+ end
127
+
128
+ it 'gets rewritten_code' do
129
+ expect(subject.rewritten_code).to eq "\n super"
130
+ end
131
+ end
132
+
133
+ describe 'defs node without args' do
134
+ subject do
135
+ source = "def self.foo\n do_something\nend"
136
+ def_node = Parser::CurrentRuby.parse(source)
137
+ instance = double(current_node: def_node)
138
+ Rewriter::PrependAction.new(instance, 'do_something_first').process
139
+ end
140
+
141
+ it 'gets begin_pos' do
142
+ expect(subject.begin_pos).to eq 'def self.foo'.length
143
+ end
144
+
145
+ it 'gets end_pos' do
146
+ expect(subject.end_pos).to eq 'def self.foo'.length
147
+ end
148
+
149
+ it 'gets rewritten_code' do
150
+ expect(subject.rewritten_code).to eq "\n do_something_first"
151
+ end
152
+ end
153
+
154
+ describe 'defs node with args' do
155
+ subject do
156
+ source = "def self.foo(bar)\n do_something\nend"
157
+ def_node = Parser::CurrentRuby.parse(source)
158
+ instance = double(current_node: def_node)
159
+ Rewriter::PrependAction.new(instance, 'do_something_first').process
160
+ end
161
+
162
+ it 'gets begin_pos' do
163
+ expect(subject.begin_pos).to eq 'def self.foo(bar)'.length
164
+ end
165
+
166
+ it 'gets end_pos' do
167
+ expect(subject.end_pos).to eq 'def self.foo(bar)'.length
168
+ end
169
+
170
+ it 'gets rewritten_code' do
171
+ expect(subject.rewritten_code).to eq "\n do_something_first"
172
+ end
173
+ end
90
174
  end
91
175
  end
@@ -118,14 +118,14 @@ module Synvert::Core
118
118
 
119
119
  it 'parses insert at end' do
120
120
  action = double
121
- expect(Rewriter::InsertAction).to receive(:new).with(instance, '.first', at: 'end').and_return(action)
121
+ expect(Rewriter::InsertAction).to receive(:new).with(instance, '.first', at: 'end', to: 'receiver').and_return(action)
122
122
  expect(action).to receive(:process)
123
- instance.insert '.first'
123
+ instance.insert '.first', to: 'receiver'
124
124
  end
125
125
 
126
126
  it 'parses insert at beginning' do
127
127
  action = double
128
- expect(Rewriter::InsertAction).to receive(:new).with(instance, 'URI.', at: 'beginning').and_return(action)
128
+ expect(Rewriter::InsertAction).to receive(:new).with(instance, 'URI.', at: 'beginning', to: nil).and_return(action)
129
129
  expect(action).to receive(:process)
130
130
  instance.insert 'URI.', at: 'beginning'
131
131
  end
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.61.0
4
+ version: 0.62.1
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-12-10 00:00:00.000000000 Z
11
+ date: 2022-01-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -218,7 +218,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
218
218
  - !ruby/object:Gem::Version
219
219
  version: '0'
220
220
  requirements: []
221
- rubygems_version: 3.2.22
221
+ rubygems_version: 3.3.3
222
222
  signing_key:
223
223
  specification_version: 4
224
224
  summary: convert ruby code to better syntax.