synvert-core 0.58.0 → 0.60.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: 991e04b61994a2fd44aaaa4cb35564a56d359ffd2b9277fb805f6fb684a2f3ce
4
- data.tar.gz: 0d969850a6915e9861937fa2a4e77ee36d93954b0aa764ffa3a56396d83becba
3
+ metadata.gz: 91e00ecd8d7f5d6ff82a17580d088cc323d0e94b53a1488e6be50cbeb4a44b13
4
+ data.tar.gz: 9e3f9dbb81cb07a27fdb8d0f2888d1c7827270d9b5bf9434ff0f649245de65a5
5
5
  SHA512:
6
- metadata.gz: 4d7a0dfe005762899d89eaede4db3219b1d6d03c94d640b1b2168234402747e658f9e19a537f6f129b8cc1e8741ca45cddfa32ed354d8e8361a08a544b41e99f
7
- data.tar.gz: fe58dedc331361f6cfbf1627e55f677e61073271a40ad7ea62bb57233ab9350f8c99750f5346360511d64e3ba0f35d112683029b377e866f3591a9a3f7ea575c
6
+ metadata.gz: 6c777f93827fa6485a6636571500f8def9cd0c8b7d910f61da7c309a84124e70415d8d86e97037ec4ee574ae783936267e446e6e1b870523fdb0ea4abea09f03
7
+ data.tar.gz: 4fa8ef96adce5932eed3d927d0f878684c1bff3896829c9297df8cb20eda98f4324aed12a066e8c5b2b60996f87929cd31d911b2961414dc2e8c0356edfb3f35
data/CHANGELOG.md CHANGED
@@ -1,5 +1,17 @@
1
1
  # CHANGELOG
2
2
 
3
+ ## 0.60.0 (2021-12-02)
4
+
5
+ * Add `to_string` to `sym` node
6
+
7
+ ## 0.59.0 (2021-11-17)
8
+
9
+ * Use option `stop_when_match` instead of `recursive`
10
+ * Add file pattern constants
11
+ * Instance supports array of file patterns
12
+ * Return block value by `next`
13
+ * Add `Node#filename` method
14
+
3
15
  ## 0.58.0 (2021-10-23)
4
16
 
5
17
  * Support `left_value` and `right_value` for `and` and `or` node
@@ -315,6 +315,13 @@ module Parser::AST
315
315
  ].join("\n")
316
316
  end
317
317
 
318
+ # Get the file name of the current node.
319
+ #
320
+ # @return [String] file name.
321
+ def filename
322
+ loc.expression&.source_buffer.name
323
+ end
324
+
318
325
  # Get the source code of current node.
319
326
  #
320
327
  # @return [String] source code.
@@ -432,8 +439,8 @@ module Parser::AST
432
439
  def recursive_children(&block)
433
440
  children.each do |child|
434
441
  if child.is_a?(Parser::AST::Node)
435
- result = yield child
436
- child.recursive_children(&block) unless result == :stop
442
+ stop = yield child
443
+ child.recursive_children(&block) unless stop == :stop
437
444
  end
438
445
  end
439
446
  end
@@ -545,6 +552,13 @@ module Parser::AST
545
552
  ":#{to_value}"
546
553
  end
547
554
 
555
+ # convert symbol to string
556
+ def to_string
557
+ return to_source unless type == :sym
558
+
559
+ "#{to_value}"
560
+ end
561
+
548
562
  # convert lambda {} to -> {}
549
563
  def to_lambda_literal
550
564
  if type == :block && caller.type == :send && caller.receiver.nil? && caller.message == :lambda
@@ -55,7 +55,7 @@ module Synvert::Core
55
55
 
56
56
  def squeeze_spaces
57
57
  if file_source[@begin_pos - 1] == ' ' && file_source[@end_pos] == ' '
58
- @begin_pos = @begin_pos - 1
58
+ @begin_pos -= 1
59
59
  end
60
60
  end
61
61
 
@@ -67,19 +67,19 @@ module Synvert::Core
67
67
  after_line_is_blank = lines[end_line] == ''
68
68
 
69
69
  if lines.length > 1 && before_line_is_blank && after_line_is_blank
70
- @end_pos = @end_pos + "\n".length
70
+ @end_pos += "\n".length
71
71
  end
72
72
  end
73
73
 
74
74
  def remove_comma
75
75
  if ',' == file_source[@begin_pos - 1]
76
- @begin_pos = @begin_pos - 1
76
+ @begin_pos -= 1
77
77
  elsif ', ' == file_source[@begin_pos - 2, 2]
78
- @begin_pos = @begin_pos - 2
78
+ @begin_pos -= 2
79
79
  elsif ', ' == file_source[@end_pos, 2]
80
- @end_pos = @end_pos + 2
80
+ @end_pos += 2
81
81
  elsif ',' == file_source[@end_pos]
82
- @end_pos = @end_pos + 1
82
+ @end_pos += 1
83
83
  end
84
84
  end
85
85
 
@@ -72,13 +72,13 @@ module Synvert::Core
72
72
  # Initialize an instance.
73
73
  #
74
74
  # @param rewriter [Synvert::Core::Rewriter]
75
- # @param file_pattern [String] pattern to find files, e.g. spec/**/*_spec.rb
75
+ # @param file_patterns [Array<String>] pattern list to find files, e.g. ['spec/**/*_spec.rb']
76
76
  # @param block [Block] block code to find nodes, match conditions and rewrite code.
77
77
  # @return [Synvert::Core::Rewriter::Instance]
78
- def initialize(rewriter, file_pattern, &block)
78
+ def initialize(rewriter, file_patterns, &block)
79
79
  @rewriter = rewriter
80
80
  @actions = []
81
- @file_pattern = file_pattern
81
+ @file_patterns = file_patterns
82
82
  @block = block
83
83
  rewriter.helpers.each { |helper| singleton_class.send(:define_method, helper[:name], &helper[:block]) }
84
84
  end
@@ -87,41 +87,42 @@ module Synvert::Core
87
87
  # It finds all files, for each file, it executes the block code, gets all rewrite actions,
88
88
  # and rewrite source code back to original file.
89
89
  def process
90
- file_pattern = File.join(Configuration.path, @file_pattern)
91
- Dir.glob(file_pattern).each do |file_path|
92
- next if Configuration.skip_files.include? file_path
93
-
94
- begin
95
- puts file_path if Configuration.show_run_process
96
- conflict_actions = []
97
- source = +self.class.file_source(file_path)
98
- ast = self.class.file_ast(file_path)
99
-
100
- @current_file = file_path
101
-
102
- process_with_node ast do
103
- begin
104
- instance_eval(&@block)
105
- rescue NoMethodError
106
- puts @current_node.debug_info
107
- raise
108
- end
109
- end
90
+ @file_patterns.each do |file_pattern|
91
+ Dir.glob(File.join(Configuration.path, file_pattern)).each do |file_path|
92
+ next if Configuration.skip_files.include? file_path
110
93
 
111
- if @actions.length > 0
112
- @actions.sort_by! { |action| [action.begin_pos, action.end_pos] }
113
- conflict_actions = get_conflict_actions
114
- @actions.reverse_each do |action|
115
- source[action.begin_pos...action.end_pos] = action.rewritten_code
94
+ begin
95
+ puts file_path if Configuration.show_run_process
96
+ conflict_actions = []
97
+ source = +self.class.file_source(file_path)
98
+ ast = self.class.file_ast(file_path)
99
+
100
+ @current_file = file_path
101
+
102
+ process_with_node ast do
103
+ begin
104
+ instance_eval(&@block)
105
+ rescue NoMethodError
106
+ puts @current_node.debug_info
107
+ raise
108
+ end
116
109
  end
117
- @actions = []
118
110
 
119
- update_file(file_path, source)
120
- end
121
- rescue Parser::SyntaxError
122
- puts "[Warn] file #{file_path} was not parsed correctly."
123
- # do nothing, iterate next file
124
- end while !conflict_actions.empty?
111
+ if @actions.length > 0
112
+ @actions.sort_by! { |action| [action.begin_pos, action.end_pos] }
113
+ conflict_actions = get_conflict_actions
114
+ @actions.reverse_each do |action|
115
+ source[action.begin_pos...action.end_pos] = action.rewritten_code
116
+ end
117
+ @actions = []
118
+
119
+ update_file(file_path, source)
120
+ end
121
+ rescue Parser::SyntaxError
122
+ puts "[Warn] file #{file_path} was not parsed correctly."
123
+ # do nothing, iterate next file
124
+ end while !conflict_actions.empty?
125
+ end
125
126
  end
126
127
  end
127
128
 
@@ -161,10 +162,10 @@ module Synvert::Core
161
162
  # then continue operating on each matching ast node.
162
163
  #
163
164
  # @param rules [Hash] rules to find mathing ast nodes.
164
- # @param options [Hash] optional, set if recursive or not.
165
+ # @param options [Hash] optional, set if stop_when_match or not.
165
166
  # @param block [Block] block code to continue operating on the matching nodes.
166
167
  def within_node(rules, options = nil, &block)
167
- options ||= { recursive: true }
168
+ options ||= { stop_when_match: false }
168
169
  Rewriter::WithinScope.new(self, rules, options, &block).process
169
170
  end
170
171
 
@@ -21,7 +21,7 @@ module Synvert::Core
21
21
  elsif File.exist?(File.join(Configuration.path, '.rvmrc'))
22
22
  versionFile = '.rvmrc'
23
23
  end
24
- return true if !versionFile
24
+ return true unless versionFile
25
25
 
26
26
  version = File.read(File.join(Configuration.path, versionFile))
27
27
  Gem::Version.new(version) >= Gem::Version.new(@version)
@@ -26,10 +26,10 @@ module Synvert::Core
26
26
  matching_nodes =
27
27
  if @options[:direct]
28
28
  find_direct_matching_nodes(current_node)
29
- elsif @options[:recursive]
30
- find_recursive_matching_nodes(current_node)
31
- else
29
+ elsif @options[:stop_when_match]
32
30
  find_matching_nodes(current_node)
31
+ else
32
+ find_recursive_matching_nodes(current_node)
33
33
  end
34
34
  @instance.process_with_node current_node do
35
35
  matching_nodes.each do |matching_node|
@@ -91,7 +91,7 @@ module Synvert::Core
91
91
  current_node.recursive_children do |child_node|
92
92
  if child_node.match?(@rules)
93
93
  matching_nodes << child_node
94
- break :stop
94
+ next :stop
95
95
  end
96
96
  end
97
97
  else
@@ -103,7 +103,7 @@ module Synvert::Core
103
103
  node.recursive_children do |child_node|
104
104
  if child_node.match?(@rules)
105
105
  matching_nodes << child_node
106
- break :stop
106
+ next :stop
107
107
  end
108
108
  end
109
109
  end
@@ -231,13 +231,13 @@ module Synvert::Core
231
231
  # Parse within_files dsl, it finds specified files.
232
232
  # It creates a [Synvert::Core::Rewriter::Instance] to rewrite code.
233
233
  #
234
- # @param file_pattern [String] pattern to find files, e.g. spec/**/*_spec.rb
234
+ # @param file_patterns [String|Array<String>] string pattern or list of string pattern to find files, e.g. ['spec/**/*_spec.rb']
235
235
  # @param block [Block] the block to rewrite code in the matching files.
236
- def within_files(file_pattern, &block)
236
+ def within_files(file_patterns, &block)
237
237
  return if @sandbox
238
238
 
239
239
  if (!@ruby_version || @ruby_version.match?) && (!@gem_spec || @gem_spec.match?)
240
- Rewriter::Instance.new(self, file_pattern, &block).process
240
+ Rewriter::Instance.new(self, Array(file_patterns), &block).process
241
241
  end
242
242
  end
243
243
 
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Synvert
4
4
  module Core
5
- VERSION = '0.58.0'
5
+ VERSION = '0.60.0'
6
6
  end
7
7
  end
data/lib/synvert/core.rb CHANGED
@@ -24,4 +24,35 @@ end
24
24
 
25
25
  module Synvert
26
26
  Rewriter = Core::Rewriter
27
+
28
+ ALL_RUBY_FILES = %w[**/*.rb]
29
+ ALL_RAKE_FILES = %w[**/*.rake]
30
+
31
+ RAILS_APP_FILES = %w[app/**/*.rb engines/*/app/**/*.rb]
32
+ RAILS_CONTROLLER_FILES = %w[app/controllers/**/*.rb engines/*/app/controllers/**/*.rb]
33
+ RAILS_JOB_FILES = %w[app/jobs/**/*.rb engines/*/app/jobs/**/*.rb]
34
+ RAILS_OBSERVER_FILES = %w[app/observers/**/*.rb engines/*/app/observers/**/*.rb]
35
+ RAILS_HELPER_FILES = %w[app/helpers/**/*.rb]
36
+ RAILS_LIB_FILES = %w[lib/**/*.rb engines/*/lib/**/*.rb]
37
+ RAILS_MAILER_FILES = %w[app/mailers/**/*.rb engines/*/app/mailers/**/*.rb]
38
+ RAILS_MIGRATION_FILES = %w[db/migrate/**/*.rb engines/*/db/migrate/**/*.rb]
39
+ RAILS_MODEL_FILES = %w[app/models/**/*.rb engines/*/app/models/**/*.rb]
40
+ RAILS_ROUTE_FILES = %w[config/routes.rb config/routes/**/*.rb engines/*/config/routes.rb engines/*/config/routes/**/*.rb]
41
+ RAILS_VIEW_FILES = %w[app/views/**/*.html.{erb,haml,slim}]
42
+
43
+ RAILS_CONTROLLER_TEST_FILES = %w[
44
+ test/functional/**/*.rb test/controllers/**/*.rb engines/*/test/functional/**/*.rb engines/*/test/controllers/**/*.rb
45
+ spec/functional/**/*.rb spec/controllers/**/*.rb engines/*/spec/functional/**/*.rb engines/*/spec/controllers/**/*.rb
46
+ ]
47
+ RAILS_INTEGRATION_TEST_FILES = %w[test/integration/**/*.rb spec/integration/**/*.rb]
48
+ RAILS_MODEL_TEST_FILES = %w[
49
+ test/unit/**/*.rb engines/*/test/unit/**/*.rb test/models/**/*.rb engines/*/test/models/**/*.rb
50
+ spec/models/**/*.rb engines/*/spec/models/**/*.rb
51
+ ]
52
+
53
+ RAILS_FACTORY_FILES = %w[test/factories/**/*.rb spec/factories/**/*.rb]
54
+ RAILS_RSPEC_FILES = %w[spec/**/*.rb engines/*/spec/**/*.rb]
55
+ RAILS_MINITEST_FILES = %w[test/**/*.rb engines/*/test/**/*.rb]
56
+ RAILS_CUCUMBER_FILES = %w[features/**/*.rb]
57
+ RAILS_TEST_FILES = RAILS_MINITEST_FILES + RAILS_RSPEC_FILES + RAILS_CUCUMBER_FILES
27
58
  end
@@ -396,6 +396,14 @@ describe Parser::AST::Node do
396
396
  end
397
397
  end
398
398
 
399
+ describe '#filename' do
400
+ it 'gets file name' do
401
+ source = 'foobar'
402
+ node = parse(source)
403
+ expect(node.filename).to eq '(string)'
404
+ end
405
+ end
406
+
399
407
  describe '#to_source' do
400
408
  it 'gets for node' do
401
409
  source = 'params[:user][:email]'
@@ -819,6 +827,22 @@ describe Parser::AST::Node do
819
827
  end
820
828
  end
821
829
 
830
+ describe '#to_string' do
831
+ context 'sym node' do
832
+ it 'converts symbol to string' do
833
+ node = parse(':foobar')
834
+ expect(node.to_string).to eq 'foobar'
835
+ end
836
+ end
837
+
838
+ context 'other node' do
839
+ it 'does nothing' do
840
+ node = parse("'foobar'")
841
+ expect(node.to_string).to eq "'foobar'"
842
+ end
843
+ end
844
+ end
845
+
822
846
  describe '#to_lambda_literal' do
823
847
  context 'lambda node' do
824
848
  it 'converts to lambda literal without arguments' do
@@ -8,14 +8,14 @@ module Synvert::Core
8
8
 
9
9
  let(:instance) {
10
10
  rewriter = Rewriter.new('foo', 'bar')
11
- Rewriter::Instance.new(rewriter, 'file pattern')
11
+ Rewriter::Instance.new(rewriter, ['file pattern'])
12
12
  }
13
13
 
14
14
  it 'parses within_node' do
15
15
  scope = double
16
16
  block = proc {}
17
17
  expect(Rewriter::WithinScope).to receive(:new)
18
- .with(instance, { type: 'send', message: 'create' }, { recursive: true }, &block)
18
+ .with(instance, { type: 'send', message: 'create' }, { stop_when_match: false }, &block)
19
19
  .and_return(scope)
20
20
  expect(scope).to receive(:process)
21
21
  instance.within_node(type: 'send', message: 'create', &block)
@@ -25,7 +25,7 @@ module Synvert::Core
25
25
  scope = double
26
26
  block = proc {}
27
27
  expect(Rewriter::WithinScope).to receive(:new)
28
- .with(instance, { type: 'send', message: 'create' }, { recursive: true }, &block)
28
+ .with(instance, { type: 'send', message: 'create' }, { stop_when_match: false }, &block)
29
29
  .and_return(scope)
30
30
  expect(scope).to receive(:process)
31
31
  instance.with_node(type: 'send', message: 'create', &block)
@@ -35,10 +35,10 @@ module Synvert::Core
35
35
  scope = double
36
36
  block = proc {}
37
37
  expect(Rewriter::WithinScope).to receive(:new)
38
- .with(instance, { type: 'send', message: 'create' }, { recursive: false }, &block)
38
+ .with(instance, { type: 'send', message: 'create' }, { stop_when_match: true }, &block)
39
39
  .and_return(scope)
40
40
  expect(scope).to receive(:process)
41
- instance.within_node({ type: 'send', message: 'create' }, { recursive: false }, &block)
41
+ instance.within_node({ type: 'send', message: 'create' }, { stop_when_match: true }, &block)
42
42
  end
43
43
 
44
44
  it 'parses within_direct_node' do
@@ -185,7 +185,7 @@ module Synvert::Core
185
185
 
186
186
  it 'writes new code to file' do
187
187
  instance =
188
- Rewriter::Instance.new rewriter, 'spec/**/*_spec.rb' do
188
+ Rewriter::Instance.new rewriter, ['spec/**/*_spec.rb'] do
189
189
  with_node type: 'send', receiver: 'FactoryGirl', message: 'create' do
190
190
  replace_with 'create {{arguments}}'
191
191
  end
@@ -212,7 +212,7 @@ module Synvert::Core
212
212
 
213
213
  it 'does not write if file content is not changed' do
214
214
  instance =
215
- Rewriter::Instance.new rewriter, 'spec/spec_helper.rb' do
215
+ Rewriter::Instance.new rewriter, ['spec/spec_helper.rb'] do
216
216
  with_node type: 'block', caller: { receiver: 'RSpec', message: 'configure' } do
217
217
  unless_exist_node type: 'send', message: 'include', arguments: ['FactoryGirl::Syntax::Methods'] do
218
218
  insert '{{arguments.first}}.include FactoryGirl::Syntax::Methods'
@@ -237,7 +237,7 @@ module Synvert::Core
237
237
 
238
238
  it 'does not read file if already read' do
239
239
  instance =
240
- Rewriter::Instance.new rewriter, 'spec/spec_helper.rb' do
240
+ Rewriter::Instance.new rewriter, ['spec/spec_helper.rb'] do
241
241
  with_node type: 'block', caller: { receiver: 'RSpec', message: 'configure' } do
242
242
  unless_exist_node type: 'send', message: 'include', arguments: ['FactoryGirl::Syntax::Methods'] do
243
243
  insert '{{arguments.first}}.include FactoryGirl::Syntax::Methods'
@@ -263,7 +263,7 @@ module Synvert::Core
263
263
 
264
264
  it 'updates file_source and file_ast when writing a file' do
265
265
  instance =
266
- Rewriter::Instance.new rewriter, 'spec/**/*_spec.rb' do
266
+ Rewriter::Instance.new rewriter, ['spec/**/*_spec.rb'] do
267
267
  with_node type: 'send', receiver: 'FactoryGirl', message: 'create' do
268
268
  replace_with 'create {{arguments}}'
269
269
  end
@@ -299,7 +299,7 @@ module Synvert::Core
299
299
  action1 = double(begin_pos: 10, end_pos: 20)
300
300
  action2 = double(begin_pos: 30, end_pos: 40)
301
301
  action3 = double(begin_pos: 50, end_pos: 60)
302
- instance = Rewriter::Instance.new rewriter, 'spec/spec_helper.rb'
302
+ instance = Rewriter::Instance.new rewriter, ['spec/spec_helper.rb']
303
303
  instance.instance_variable_set :@actions, [action1, action2, action3]
304
304
  conflict_actions = instance.send(:get_conflict_actions)
305
305
  expect(conflict_actions).to eq []
@@ -310,7 +310,7 @@ module Synvert::Core
310
310
  action1 = double(begin_pos: 30, end_pos: 40)
311
311
  action2 = double(begin_pos: 50, end_pos: 60)
312
312
  action3 = double(begin_pos: 10, end_pos: 20)
313
- instance = Rewriter::Instance.new rewriter, 'spec/spec_helper.rb'
313
+ instance = Rewriter::Instance.new rewriter, ['spec/spec_helper.rb']
314
314
  instance.instance_variable_set :@actions, [action1, action2, action3]
315
315
  conflict_actions = instance.send(:get_conflict_actions)
316
316
  expect(conflict_actions).to eq [action2, action1]
@@ -54,7 +54,7 @@ module Synvert::Core
54
54
 
55
55
  it 'matches multiple block nodes' do
56
56
  block_nodes = []
57
- scope = Rewriter::WithinScope.new(instance, { type: 'block' }, { recursive: true }) do
57
+ scope = Rewriter::WithinScope.new(instance, { type: 'block' }, { stop_when_match: false }) do
58
58
  block_nodes << node
59
59
  end
60
60
  scope.process
@@ -63,7 +63,7 @@ module Synvert::Core
63
63
 
64
64
  it 'matches only one block node if no recursive' do
65
65
  block_nodes = []
66
- scope = Rewriter::WithinScope.new(instance, { type: 'block' } , { recursive: false }) do
66
+ scope = Rewriter::WithinScope.new(instance, { type: 'block' } , { stop_when_match: true }) do
67
67
  block_nodes << node
68
68
  end
69
69
  scope.process
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.58.0
4
+ version: 0.60.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-10-22 00:00:00.000000000 Z
11
+ date: 2021-12-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport