synvert-core 0.58.0 → 0.60.0

Sign up to get free protection for your applications and to get access to all the features.
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