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 +4 -4
- data/.github/workflows/main.yml +2 -2
- data/CHANGELOG.md +11 -0
- data/lib/synvert/core/node_ext.rb +7 -7
- data/lib/synvert/core/rewriter/action/append_action.rb +1 -1
- data/lib/synvert/core/rewriter/action/insert_action.rb +4 -2
- data/lib/synvert/core/rewriter/action/prepend_action.rb +5 -1
- data/lib/synvert/core/rewriter/instance.rb +3 -2
- data/lib/synvert/core/rewriter.rb +10 -11
- data/lib/synvert/core/version.rb +1 -1
- data/lib/synvert/core.rb +1 -0
- data/spec/synvert/core/node_ext_spec.rb +59 -0
- data/spec/synvert/core/rewriter/action/append_action_spec.rb +21 -0
- data/spec/synvert/core/rewriter/action/insert_action_spec.rb +21 -0
- data/spec/synvert/core/rewriter/action/prepend_action_spec.rb +84 -0
- data/spec/synvert/core/rewriter/instance_spec.rb +3 -3
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 79777679e6001f32c8b4bc587e2f007f396eeecd9c0c7e29926e01a3628b4244
|
4
|
+
data.tar.gz: df4d3eda62e9b2f49ec1cf8da96bd98952d7d5af70fd4d6861b206bbc923cca9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c9744e62dc972253304018ac041aa1f4cd01efd8a80a207a77145e088d4d69713ef4ec10ade9fe4d251811b6a8166d8e33b575ea91265fbec4f989a9e29ac376
|
7
|
+
data.tar.gz: cad73e2d256e25370b535a0f623fee47c02f4d5a56e3feaed50f81a798cf3c1dbb0ffd4d6ad04ab167be78fc390703a2a01f0377b79ea621f1674399aa2c7534
|
data/.github/workflows/main.yml
CHANGED
@@ -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
|
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
|
-
|
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
|
-
|
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?
|
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
|
-
|
244
|
-
|
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
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
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
|
-
|
170
|
-
|
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
|
240
|
-
|
241
|
-
|
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.
|
data/lib/synvert/core/version.rb
CHANGED
data/lib/synvert/core.rb
CHANGED
@@ -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.
|
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:
|
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.
|
221
|
+
rubygems_version: 3.3.3
|
222
222
|
signing_key:
|
223
223
|
specification_version: 4
|
224
224
|
summary: convert ruby code to better syntax.
|