synvert-core 0.21.2 → 0.25.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/CHANGELOG.md +17 -4
- data/lib/synvert/core.rb +1 -0
- data/lib/synvert/core/node_ext.rb +18 -20
- data/lib/synvert/core/rewriter.rb +19 -6
- data/lib/synvert/core/rewriter/action/replace_with_action.rb +3 -5
- data/lib/synvert/core/rewriter/gem_spec.rb +5 -16
- data/lib/synvert/core/rewriter/instance.rb +41 -34
- data/lib/synvert/core/rewriter/ruby_version.rb +2 -0
- data/lib/synvert/core/rewriter/scope/goto_scope.rb +1 -1
- data/lib/synvert/core/rewriter/scope/within_scope.rb +2 -2
- data/lib/synvert/core/version.rb +1 -1
- data/spec/synvert/core/node_ext_spec.rb +3 -3
- data/spec/synvert/core/rewriter/gem_spec_spec.rb +2 -2
- data/spec/synvert/core/rewriter/instance_spec.rb +1 -0
- data/spec/synvert/core/rewriter_spec.rb +2 -2
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1aab544b0a434d8d34f445906448203f8ebf670f2e3fc14ac791163c1c059bbb
|
4
|
+
data.tar.gz: c913b856a8281cbd07ac6ca59fea393a633b3d920b0849b9a9f16dd897989b0f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: cc0c4ea16085329d3385227885af3fc10fc925be5abe0bf408afa89ee95d5aba048225be488b8624dd0cdb7c6c0b4ed994f9d8c66aa8891c252eaf5784e3f06c
|
7
|
+
data.tar.gz: d3a6ac011d673c981cc59e34ad0bbcba5c5042a5bc20ea15a46d6c77b775d8f682d212951ec8503432473044e2f58c80342810fe9d4521cf405bf719e845bdd3
|
data/CHANGELOG.md
CHANGED
@@ -1,12 +1,25 @@
|
|
1
1
|
# CHANGELOG
|
2
2
|
|
3
|
-
## 0.
|
3
|
+
## 0.25.1 (2021-03-24)
|
4
4
|
|
5
|
-
*
|
5
|
+
* attr_reader ruby_version and gem_spec
|
6
6
|
|
7
|
-
## 0.
|
7
|
+
## 0.25.0 (2021-03-23)
|
8
8
|
|
9
|
-
*
|
9
|
+
* Use `Gem::Dependency#match?` to check gem version
|
10
|
+
|
11
|
+
## 0.24.0 (2021-03-17)
|
12
|
+
|
13
|
+
* Rename helper method `has_key?` to `key?`
|
14
|
+
|
15
|
+
## 0.23.0 (2021-03-14)
|
16
|
+
|
17
|
+
* Accept a node as goto_node argument
|
18
|
+
|
19
|
+
## 0.22.0 (2021-03-13)
|
20
|
+
|
21
|
+
* Track `affected_files` for rewriter
|
22
|
+
* Fix `find_matching_nodes` for `current_node`
|
10
23
|
|
11
24
|
## 0.21.0 (2021-02-25)
|
12
25
|
|
data/lib/synvert/core.rb
CHANGED
@@ -187,11 +187,11 @@ module Parser::AST
|
|
187
187
|
# @param [Object] key value.
|
188
188
|
# @return [Boolean] true if specified key exists.
|
189
189
|
# @raise [Synvert::Core::MethodNotSupported] if calls on other node.
|
190
|
-
def
|
190
|
+
def key?(key)
|
191
191
|
if :hash == type
|
192
192
|
children.any? { |pair_node| pair_node.key.to_value == key }
|
193
193
|
else
|
194
|
-
raise Synvert::Core::MethodNotSupported, "
|
194
|
+
raise Synvert::Core::MethodNotSupported, "key? is not handled for #{debug_info}"
|
195
195
|
end
|
196
196
|
end
|
197
197
|
|
@@ -205,7 +205,7 @@ module Parser::AST
|
|
205
205
|
value_node = children.find { |pair_node| pair_node.key.to_value == key }
|
206
206
|
value_node ? value_node.value : nil
|
207
207
|
else
|
208
|
-
raise Synvert::Core::MethodNotSupported, "
|
208
|
+
raise Synvert::Core::MethodNotSupported, "hash_value is not handled for #{debug_info}"
|
209
209
|
end
|
210
210
|
end
|
211
211
|
|
@@ -335,24 +335,22 @@ module Parser::AST
|
|
335
335
|
# @param rules [Hash] rules to match.
|
336
336
|
# @return true if matches.
|
337
337
|
def match?(rules)
|
338
|
-
flat_hash(rules)
|
339
|
-
.
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
|
345
|
-
|
346
|
-
|
347
|
-
|
348
|
-
|
349
|
-
|
350
|
-
|
351
|
-
|
352
|
-
expected = expected_value(rules, multi_keys)
|
353
|
-
match_value?(actual, expected)
|
354
|
-
end
|
338
|
+
flat_hash(rules).keys.all? do |multi_keys|
|
339
|
+
case multi_keys.last
|
340
|
+
when :any
|
341
|
+
actual_values = actual_value(self, multi_keys[0...-1])
|
342
|
+
expected = expected_value(rules, multi_keys)
|
343
|
+
actual_values.any? { |actual| match_value?(actual, expected) }
|
344
|
+
when :not
|
345
|
+
actual = actual_value(self, multi_keys[0...-1])
|
346
|
+
expected = expected_value(rules, multi_keys)
|
347
|
+
!match_value?(actual, expected)
|
348
|
+
else
|
349
|
+
actual = actual_value(self, multi_keys)
|
350
|
+
expected = expected_value(rules, multi_keys)
|
351
|
+
match_value?(actual, expected)
|
355
352
|
end
|
353
|
+
end
|
356
354
|
end
|
357
355
|
|
358
356
|
# Get rewritten source code.
|
@@ -7,7 +7,7 @@ module Synvert::Core
|
|
7
7
|
# which define the behavior what files and what codes to detect and rewrite to what code.
|
8
8
|
#
|
9
9
|
# Synvert::Rewriter.new 'factory_girl_short_syntax', 'use FactoryGirl short syntax' do
|
10
|
-
# if_gem 'factory_girl',
|
10
|
+
# if_gem 'factory_girl', '>= 2.0.0'
|
11
11
|
#
|
12
12
|
# within_files 'spec/**/*.rb' do
|
13
13
|
# with_node type: 'send', receiver: 'FactoryGirl', message: 'create' do
|
@@ -145,7 +145,13 @@ module Synvert::Core
|
|
145
145
|
# @return [Array] helper methods.
|
146
146
|
# @!attribute [r] warnings
|
147
147
|
# @return [Array<Synvert::Core::Rewriter::Warning>] warning messages.
|
148
|
-
|
148
|
+
# @!attribute [r] affected_files
|
149
|
+
# @return [Set] affected fileds
|
150
|
+
# @!attribute [r] ruby_version
|
151
|
+
# @return [Rewriter::RubyVersion] the ruby version
|
152
|
+
# @!attribute [r] gem_spec
|
153
|
+
# @return [Rewriter::GemSpec] the gem spec
|
154
|
+
attr_reader :group, :name, :sub_snippets, :helpers, :warnings, :affected_files, :ruby_version, :gem_spec
|
149
155
|
|
150
156
|
# Initialize a rewriter.
|
151
157
|
# When a rewriter is initialized, it is also registered.
|
@@ -161,6 +167,7 @@ module Synvert::Core
|
|
161
167
|
@helpers = []
|
162
168
|
@sub_snippets = []
|
163
169
|
@warnings = []
|
170
|
+
@affected_files = Set.new
|
164
171
|
self.class.register(@group, @name, self)
|
165
172
|
end
|
166
173
|
|
@@ -188,6 +195,13 @@ module Synvert::Core
|
|
188
195
|
@warnings << warning
|
189
196
|
end
|
190
197
|
|
198
|
+
# Add an affected file.
|
199
|
+
#
|
200
|
+
# @param file_path [String]
|
201
|
+
def add_affected_file(file_path)
|
202
|
+
@affected_files.add(file_path)
|
203
|
+
end
|
204
|
+
|
191
205
|
#######
|
192
206
|
# DSL #
|
193
207
|
#######
|
@@ -215,10 +229,9 @@ module Synvert::Core
|
|
215
229
|
# Parse if_gem dsl, it compares version of the specified gem.
|
216
230
|
#
|
217
231
|
# @param name [String] gem name.
|
218
|
-
# @param
|
219
|
-
|
220
|
-
|
221
|
-
@gem_spec = Rewriter::GemSpec.new(name, comparator)
|
232
|
+
# @param version [String] equal, less than or greater than specified version, e.g. '>= 2.0.0',
|
233
|
+
def if_gem(name, version)
|
234
|
+
@gem_spec = Rewriter::GemSpec.new(name, version)
|
222
235
|
end
|
223
236
|
|
224
237
|
# Parse within_files dsl, it finds specified files.
|
@@ -23,11 +23,9 @@ module Synvert::Core
|
|
23
23
|
def rewritten_code
|
24
24
|
if rewritten_source.split("\n").length > 1
|
25
25
|
new_code = []
|
26
|
-
rewritten_source
|
27
|
-
|
28
|
-
|
29
|
-
new_code << (index == 0 || !@options[:autoindent] ? line : indent(@node) + line)
|
30
|
-
}
|
26
|
+
rewritten_source.split("\n").each_with_index { |line, index|
|
27
|
+
new_code << (index == 0 || !@options[:autoindent] ? line : indent(@node) + line)
|
28
|
+
}
|
31
29
|
new_code.join("\n")
|
32
30
|
else
|
33
31
|
rewritten_source
|
@@ -3,22 +3,15 @@
|
|
3
3
|
module Synvert::Core
|
4
4
|
# GemSpec checks and compares gem version.
|
5
5
|
class Rewriter::GemSpec
|
6
|
-
|
6
|
+
attr_reader :name, :version
|
7
7
|
|
8
8
|
# Initialize a gem_spec.
|
9
9
|
#
|
10
10
|
# @param name [String] gem name
|
11
|
-
# @param
|
12
|
-
|
13
|
-
def initialize(name, comparator)
|
11
|
+
# @param version [String] gem version, e.g. '~> 2.0.0',
|
12
|
+
def initialize(name, version)
|
14
13
|
@name = name
|
15
|
-
|
16
|
-
@operator = comparator.keys.first
|
17
|
-
@version = Gem::Version.new comparator.values.first
|
18
|
-
else
|
19
|
-
@operator = :eq
|
20
|
-
@version = Gem::Version.new comparator
|
21
|
-
end
|
14
|
+
@version = version
|
22
15
|
end
|
23
16
|
|
24
17
|
# Check if the specified gem version in Gemfile.lock matches gem_spec comparator.
|
@@ -33,11 +26,7 @@ module Synvert::Core
|
|
33
26
|
|
34
27
|
ENV['BUNDLE_GEMFILE'] = Configuration.path # make sure bundler reads Gemfile.lock in the correct path
|
35
28
|
parser = Bundler::LockfileParser.new(File.read(gemfile_lock_path))
|
36
|
-
|
37
|
-
Gem::Version.new(spec.version).send(OPERATORS[@operator], @version)
|
38
|
-
else
|
39
|
-
false
|
40
|
-
end
|
29
|
+
parser.specs.any? { |spec| Gem::Dependency.new(@name, @version).match?(spec) }
|
41
30
|
end
|
42
31
|
end
|
43
32
|
end
|
@@ -87,43 +87,41 @@ module Synvert::Core
|
|
87
87
|
# and rewrite source code back to original file.
|
88
88
|
def process
|
89
89
|
file_pattern = File.join(Configuration.path, @file_pattern)
|
90
|
-
Dir
|
91
|
-
.
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
puts @current_node.debug_info
|
107
|
-
raise
|
108
|
-
end
|
90
|
+
Dir.glob(file_pattern).each do |file_path|
|
91
|
+
next if Configuration.skip_files.include? file_path
|
92
|
+
|
93
|
+
begin
|
94
|
+
conflict_actions = []
|
95
|
+
source = +self.class.file_source(file_path)
|
96
|
+
ast = self.class.file_ast(file_path)
|
97
|
+
|
98
|
+
@current_file = file_path
|
99
|
+
|
100
|
+
process_with_node ast do
|
101
|
+
begin
|
102
|
+
instance_eval(&@block)
|
103
|
+
rescue NoMethodError
|
104
|
+
puts @current_node.debug_info
|
105
|
+
raise
|
109
106
|
end
|
107
|
+
end
|
110
108
|
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
end
|
118
|
-
@actions = []
|
119
|
-
|
120
|
-
self.class.write_file(file_path, source)
|
109
|
+
if @actions.length > 0
|
110
|
+
@actions.sort_by! { |action| action.send(@options[:sort_by]) }
|
111
|
+
conflict_actions = get_conflict_actions
|
112
|
+
@actions.reverse_each do |action|
|
113
|
+
source[action.begin_pos...action.end_pos] = action.rewritten_code
|
114
|
+
source = remove_code_or_whole_line(source, action.line)
|
121
115
|
end
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
end
|
126
|
-
|
116
|
+
@actions = []
|
117
|
+
|
118
|
+
update_file(file_path, source)
|
119
|
+
end
|
120
|
+
rescue Parser::SyntaxError
|
121
|
+
puts "[Warn] file #{file_path} was not parsed correctly."
|
122
|
+
# do nothing, iterate next file
|
123
|
+
end while !conflict_actions.empty?
|
124
|
+
end
|
127
125
|
end
|
128
126
|
|
129
127
|
# Gets current node, it allows to get current node in block code.
|
@@ -312,5 +310,14 @@ module Synvert::Core
|
|
312
310
|
source
|
313
311
|
end
|
314
312
|
end
|
313
|
+
|
314
|
+
# It updates a file with new source code.
|
315
|
+
#
|
316
|
+
# @param file_path [String] the file path
|
317
|
+
# @param source [String] the new source code
|
318
|
+
def update_file(file_path, source)
|
319
|
+
self.class.write_file(file_path, source)
|
320
|
+
@rewriter.add_affected_file(file_path)
|
321
|
+
end
|
315
322
|
end
|
316
323
|
end
|
@@ -19,7 +19,7 @@ module Synvert::Core
|
|
19
19
|
current_node = @instance.current_node
|
20
20
|
return unless current_node
|
21
21
|
|
22
|
-
child_node = current_node.send
|
22
|
+
child_node = @child_node_name.is_a?(Parser::AST::Node) ? @child_node_name : current_node.send(@child_node_name)
|
23
23
|
@instance.process_with_other_node child_node do
|
24
24
|
@instance.instance_eval(&@block)
|
25
25
|
end
|
@@ -46,8 +46,8 @@ module Synvert::Core
|
|
46
46
|
current_node.children.each do |child_node|
|
47
47
|
matching_nodes << child_node if child_node.match? @rules
|
48
48
|
end
|
49
|
-
|
50
|
-
matching_nodes << current_node
|
49
|
+
elsif current_node.match? @rules
|
50
|
+
matching_nodes << current_node
|
51
51
|
end
|
52
52
|
else
|
53
53
|
current_node.each do |child_node|
|
data/lib/synvert/core/version.rb
CHANGED
@@ -186,15 +186,15 @@ describe Parser::AST::Node do
|
|
186
186
|
end
|
187
187
|
end
|
188
188
|
|
189
|
-
describe '#
|
189
|
+
describe '#key?' do
|
190
190
|
it 'gets true if key exists' do
|
191
191
|
node = parse('{:foo => :bar}')
|
192
|
-
expect(node.
|
192
|
+
expect(node.key?(:foo)).to be_truthy
|
193
193
|
end
|
194
194
|
|
195
195
|
it 'gets false if key does not exist' do
|
196
196
|
node = parse('{:foo => :bar}')
|
197
|
-
expect(node.
|
197
|
+
expect(node.key?('foo')).to be_falsey
|
198
198
|
end
|
199
199
|
end
|
200
200
|
|
@@ -21,7 +21,7 @@ GEM
|
|
21
21
|
it 'returns true if version in Gemfile.lock is greater than definition' do
|
22
22
|
expect(File).to receive(:exist?).with('./Gemfile.lock').and_return(true)
|
23
23
|
expect(File).to receive(:read).with('./Gemfile.lock').and_return(gemfile_lock_content)
|
24
|
-
gem_spec = Rewriter::GemSpec.new('ast',
|
24
|
+
gem_spec = Rewriter::GemSpec.new('ast', '~> 1.1')
|
25
25
|
expect(gem_spec).to be_match
|
26
26
|
end
|
27
27
|
|
@@ -35,7 +35,7 @@ GEM
|
|
35
35
|
it 'returns false if version in Gemfile.lock is less than definition' do
|
36
36
|
expect(File).to receive(:exist?).with('./Gemfile.lock').and_return(true)
|
37
37
|
expect(File).to receive(:read).with('./Gemfile.lock').and_return(gemfile_lock_content)
|
38
|
-
gem_spec = Rewriter::GemSpec.new('ast',
|
38
|
+
gem_spec = Rewriter::GemSpec.new('ast', '> 1.2.0')
|
39
39
|
expect(gem_spec).not_to be_match
|
40
40
|
end
|
41
41
|
|
@@ -29,10 +29,10 @@ module Synvert::Core
|
|
29
29
|
end
|
30
30
|
|
31
31
|
it 'parses if_gem' do
|
32
|
-
expect(Rewriter::GemSpec).to receive(:new).with('synvert',
|
32
|
+
expect(Rewriter::GemSpec).to receive(:new).with('synvert', '>= 1.0.0')
|
33
33
|
rewriter =
|
34
34
|
Rewriter.new 'group', 'name' do
|
35
|
-
if_gem 'synvert',
|
35
|
+
if_gem 'synvert', '>= 1.0.0'
|
36
36
|
end
|
37
37
|
rewriter.process
|
38
38
|
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.25.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-
|
11
|
+
date: 2021-03-24 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|