synvert-core 0.23.0 → 0.26.1

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: 03fc53b8833a45acfc449689b313108daf0e98c93dfd8e197fc9b3940e68816b
4
- data.tar.gz: e9563c1fe7e358c748be50638a37ecfb7d155c8c4f4ed6dbcde1cac29ed74b99
3
+ metadata.gz: e3f85c5eb0a82ffb3447ad72ac9f901883a074b1f16c244176008a333b3e90cc
4
+ data.tar.gz: c13b895edc3ef7f9d126795933e2bf01267b0b912e2904a4481baff175eebca4
5
5
  SHA512:
6
- metadata.gz: d053963cb0dfb4e92e515d965a7651d35d60d2d929e2dce1f46c8a32fc4a6101414cd8b47f185c0b43a10470a340614c2d6048184fb869c5e9e6b60a2f16ff27
7
- data.tar.gz: 24307e135f10127b48403cfae69c89c4d71d112a513a83570ae7fd16c625882437e2efadefbd4b683fae6d9ce990ae0c1b104e7da3dbfe5f52a893e6f025df63
6
+ metadata.gz: 16ceb23eaf30909e4950cefbaae20b650f90320a496fee4a095a054dc7996fe91bfbcb79fc6252caa38f09b5998c687d4171bee050fc605cf2c8ee8ddac93c61
7
+ data.tar.gz: fc0202a47909b7bcffdd0e235c198419afcf2653f89bcd9abce626b412ab3c4a92a0bfbc71be8971873d15aeac85e4e2d0f80575ee44f75374d7c755af281c12
data/CHANGELOG.md CHANGED
@@ -1,5 +1,22 @@
1
1
  # CHANGELOG
2
2
 
3
+ ## 0.26.1 (2021-03-31)
4
+
5
+ * Support `:class` in `child_node_range`
6
+
7
+ ## 0.26.0 (2021-03-30)
8
+
9
+ * attr_reader ruby_version and gem_spec
10
+ * Add `replace` action
11
+
12
+ ## 0.25.0 (2021-03-23)
13
+
14
+ * Use `Gem::Dependency#match?` to check gem version
15
+
16
+ ## 0.24.0 (2021-03-17)
17
+
18
+ * Rename helper method `has_key?` to `key?`
19
+
3
20
  ## 0.23.0 (2021-03-14)
4
21
 
5
22
  * Accept a node as goto_node argument
@@ -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 has_key?(key)
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, "has_key? is not handled for #{debug_info}"
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, "has_key? is not handled for #{debug_info}"
208
+ raise Synvert::Core::MethodNotSupported, "hash_value is not handled for #{debug_info}"
209
209
  end
210
210
  end
211
211
 
@@ -317,6 +317,33 @@ module Parser::AST
317
317
  loc.expression.line
318
318
  end
319
319
 
320
+ # Get the source range of child node.
321
+ #
322
+ # @param [String] name of child node.
323
+ # @return [Parser::Source::Range] source range of child node.
324
+ def child_node_range(child_name)
325
+ case type
326
+ when :class
327
+ case child_name
328
+ when :name
329
+ loc.name
330
+ when :parent_class
331
+ parent_class&.loc&.expression
332
+ end
333
+ when :send
334
+ case child_name
335
+ when :receiver
336
+ receiver&.loc&.expression
337
+ when :message
338
+ loc.selector
339
+ when :arguments
340
+ Parser::Source::Range.new('(string)', arguments.first.loc.expression.begin_pos, arguments.last.loc.expression.end_pos) unless arguments.empty?
341
+ end
342
+ else
343
+ raise Synvert::Core::MethodNotSupported, "child_node_range is not handled for #{evaluated.inspect}, child_name: #{child_name}"
344
+ end
345
+ end
346
+
320
347
  # Recursively iterate all child nodes of current node.
321
348
  #
322
349
  # @yield [child] Gives a child node.
@@ -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', {gte: '2.0.0'}
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
@@ -21,6 +21,7 @@ module Synvert::Core
21
21
  autoload :InsertAction, 'synvert/core/rewriter/action/insert_action'
22
22
  autoload :InsertAfterAction, 'synvert/core/rewriter/action/insert_after_action'
23
23
  autoload :ReplaceWithAction, 'synvert/core/rewriter/action/replace_with_action'
24
+ autoload :ReplaceAction, 'synvert/core/rewriter/action/replace_action'
24
25
  autoload :ReplaceErbStmtWithExprAction, 'synvert/core/rewriter/action/replace_erb_stmt_with_expr_action'
25
26
  autoload :RemoveAction, 'synvert/core/rewriter/action/remove_action'
26
27
 
@@ -147,7 +148,11 @@ module Synvert::Core
147
148
  # @return [Array<Synvert::Core::Rewriter::Warning>] warning messages.
148
149
  # @!attribute [r] affected_files
149
150
  # @return [Set] affected fileds
150
- attr_reader :group, :name, :sub_snippets, :helpers, :warnings, :affected_files
151
+ # @!attribute [r] ruby_version
152
+ # @return [Rewriter::RubyVersion] the ruby version
153
+ # @!attribute [r] gem_spec
154
+ # @return [Rewriter::GemSpec] the gem spec
155
+ attr_reader :group, :name, :sub_snippets, :helpers, :warnings, :affected_files, :ruby_version, :gem_spec
151
156
 
152
157
  # Initialize a rewriter.
153
158
  # When a rewriter is initialized, it is also registered.
@@ -225,10 +230,9 @@ module Synvert::Core
225
230
  # Parse if_gem dsl, it compares version of the specified gem.
226
231
  #
227
232
  # @param name [String] gem name.
228
- # @param comparator [Hash] equal, less than or greater than specified version, e.g. {gte: '2.0.0'},
229
- # key can be eq, lt, gt, lte, gte or ne.
230
- def if_gem(name, comparator)
231
- @gem_spec = Rewriter::GemSpec.new(name, comparator)
233
+ # @param version [String] equal, less than or greater than specified version, e.g. '>= 2.0.0',
234
+ def if_gem(name, version)
235
+ @gem_spec = Rewriter::GemSpec.new(name, version)
232
236
  end
233
237
 
234
238
  # Parse within_files dsl, it finds specified files.
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Synvert::Core
4
+ # ReplaceAction to replace child node with code.
5
+ class Rewriter::ReplaceAction < Rewriter::Action
6
+ def initialize(instance, selector, with:)
7
+ @instance = instance
8
+ @selector = selector
9
+ @code = with
10
+ @node = @instance.current_node
11
+ end
12
+
13
+ # Begin position of code to replace.
14
+ #
15
+ # @return [Integer] begin position.
16
+ def begin_pos
17
+ @node.child_node_range(@selector).begin_pos
18
+ end
19
+
20
+ # End position of code to replace.
21
+ #
22
+ # @return [Integer] end position.
23
+ def end_pos
24
+ @node.child_node_range(@selector).end_pos
25
+ end
26
+
27
+ # The rewritten source code.
28
+ #
29
+ # @return [String] rewritten code.
30
+ def rewritten_code
31
+ rewritten_source
32
+ end
33
+ end
34
+ end
@@ -3,22 +3,15 @@
3
3
  module Synvert::Core
4
4
  # GemSpec checks and compares gem version.
5
5
  class Rewriter::GemSpec
6
- OPERATORS = { eq: '==', lt: '<', gt: '>', lte: '<=', gte: '>=', ne: '!=' }.freeze
6
+ attr_reader :name, :version
7
7
 
8
8
  # Initialize a gem_spec.
9
9
  #
10
10
  # @param name [String] gem name
11
- # @param comparator [Hash] comparator to gem version, e.g. {eq: '2.0.0'},
12
- # comparator key can be eq, lt, gt, lte, gte or ne.
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
- if comparator.is_a?(Hash)
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
- if spec = parser.specs.find { |spec| spec.name == @name }
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
@@ -251,6 +251,15 @@ module Synvert::Core
251
251
  @actions << Rewriter::ReplaceWithAction.new(self, code, options)
252
252
  end
253
253
 
254
+ # Parse replace with dsl, it creates a [Synvert::Core::Rewriter::ReplaceAction] to
255
+ # replace child node with code.
256
+ #
257
+ # @param selector [Symbol] selector name of child name.
258
+ # @param with [String] code need to be replaced with.
259
+ def replace(selector, with:)
260
+ @actions << Rewriter::ReplaceAction.new(self, selector, with: with)
261
+ end
262
+
254
263
  # Parse replace_erb_stmt_with_expr dsl, it creates a [Synvert::Core::Rewriter::ReplaceErbStmtWithExprAction] to
255
264
  # replace erb stmt code to expr code.
256
265
  def replace_erb_stmt_with_expr
@@ -3,6 +3,8 @@
3
3
  module Synvert::Core
4
4
  # GemSpec checks and compares gem version.
5
5
  class Rewriter::RubyVersion
6
+ attr_reader :version
7
+
6
8
  # Initialize a ruby_version.
7
9
  #
8
10
  # @param version [String] ruby version
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Synvert
4
4
  module Core
5
- VERSION = '0.23.0'
5
+ VERSION = '0.26.1'
6
6
  end
7
7
  end
@@ -186,15 +186,15 @@ describe Parser::AST::Node do
186
186
  end
187
187
  end
188
188
 
189
- describe '#has_key?' do
189
+ describe '#key?' do
190
190
  it 'gets true if key exists' do
191
191
  node = parse('{:foo => :bar}')
192
- expect(node.has_key?(:foo)).to be_truthy
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.has_key?('foo')).to be_falsey
197
+ expect(node.key?('foo')).to be_falsey
198
198
  end
199
199
  end
200
200
 
@@ -394,6 +394,62 @@ describe Parser::AST::Node do
394
394
  end
395
395
  end
396
396
 
397
+ describe '#child_node_range' do
398
+ context 'send node' do
399
+ it 'checks receiver' do
400
+ node = parse('foo.bar(test)')
401
+ range = node.child_node_range(:receiver)
402
+ expect(range.to_range).to eq(0...3)
403
+
404
+ node = parse('foobar(test)')
405
+ range = node.child_node_range(:receiver)
406
+ expect(range).to be_nil
407
+ end
408
+
409
+ it 'checks message' do
410
+ node = parse('foo.bar(test)')
411
+ range = node.child_node_range(:message)
412
+ expect(range.to_range).to eq(4...7)
413
+
414
+ node = parse('foobar(test)')
415
+ range = node.child_node_range(:message)
416
+ expect(range.to_range).to eq(0...6)
417
+ end
418
+
419
+ it 'checks arguments' do
420
+ node = parse('foo.bar(test)')
421
+ range = node.child_node_range(:arguments)
422
+ expect(range.to_range).to eq(8...12)
423
+
424
+ node = parse('foobar(test)')
425
+ range = node.child_node_range(:arguments)
426
+ expect(range.to_range).to eq(7...11)
427
+
428
+ node = parse('foo.bar')
429
+ range = node.child_node_range(:arguments)
430
+ expect(range).to be_nil
431
+ end
432
+ end
433
+
434
+ context 'class node' do
435
+ it 'checks name' do
436
+ node = parse('class Post < ActiveRecord::Base; end')
437
+ range = node.child_node_range(:name)
438
+ expect(range.to_range).to eq(6...10)
439
+ end
440
+
441
+ it 'checks parent_class' do
442
+ node = parse('class Post < ActiveRecord::Base; end')
443
+ range = node.child_node_range(:parent_class)
444
+ expect(range.to_range).to eq(13...31)
445
+
446
+ node = parse('class Post; end')
447
+ range = node.child_node_range(:parent_class)
448
+ expect(range).to be_nil
449
+ end
450
+ end
451
+ end
452
+
397
453
  describe '#rewritten_source' do
398
454
  let(:instance) {
399
455
  rewriter = Synvert::Rewriter.new('foo', 'bar')
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ module Synvert::Core
6
+ describe Rewriter::ReplaceAction do
7
+ context 'replace with single line' do
8
+ subject {
9
+ source = "'slug from title'.gsub(' ', '_')"
10
+ node = Parser::CurrentRuby.parse(source)
11
+ instance = double(current_node: node)
12
+ Rewriter::ReplaceAction.new(instance, :message, with: 'tr')
13
+ }
14
+
15
+ it 'gets begin_pos' do
16
+ expect(subject.begin_pos).to eq "'slug from title'.".length
17
+ end
18
+
19
+ it 'gets end_pos' do
20
+ expect(subject.end_pos).to eq "'slug from title'.gsub".length
21
+ end
22
+
23
+ it 'gets rewritten_code' do
24
+ expect(subject.rewritten_code).to eq 'tr'
25
+ end
26
+ end
27
+ end
28
+ end
@@ -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', { gte: '1.0.0' })
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', { gt: '1.2.0' })
38
+ gem_spec = Rewriter::GemSpec.new('ast', '> 1.2.0')
39
39
  expect(gem_spec).not_to be_match
40
40
  end
41
41
 
@@ -117,6 +117,11 @@ module Synvert::Core
117
117
  instance.replace_with 'create {{arguments}}'
118
118
  end
119
119
 
120
+ it 'parses replace with' do
121
+ expect(Rewriter::ReplaceAction).to receive(:new).with(instance, :message, with: 'test')
122
+ instance.replace :message, with: 'test'
123
+ end
124
+
120
125
  it 'parses remove' do
121
126
  expect(Rewriter::RemoveAction).to receive(:new).with(instance)
122
127
  instance.remove
@@ -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', { gte: '1.0.0' })
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', { gte: '1.0.0' }
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.23.0
4
+ version: 0.26.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-03-14 00:00:00.000000000 Z
11
+ date: 2021-03-31 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -150,6 +150,7 @@ files:
150
150
  - lib/synvert/core/rewriter/action/insert_action.rb
151
151
  - lib/synvert/core/rewriter/action/insert_after_action.rb
152
152
  - lib/synvert/core/rewriter/action/remove_action.rb
153
+ - lib/synvert/core/rewriter/action/replace_action.rb
153
154
  - lib/synvert/core/rewriter/action/replace_erb_stmt_with_expr_action.rb
154
155
  - lib/synvert/core/rewriter/action/replace_with_action.rb
155
156
  - lib/synvert/core/rewriter/condition.rb
@@ -173,6 +174,7 @@ files:
173
174
  - spec/synvert/core/rewriter/action/insert_action_spec.rb
174
175
  - spec/synvert/core/rewriter/action/insert_after_action_spec.rb
175
176
  - spec/synvert/core/rewriter/action/remove_action_spec.rb
177
+ - spec/synvert/core/rewriter/action/replace_action_spec.rb
176
178
  - spec/synvert/core/rewriter/action/replace_erb_stmt_with_expr_action_spec.rb
177
179
  - spec/synvert/core/rewriter/action/replace_with_action_spec.rb
178
180
  - spec/synvert/core/rewriter/action_spec.rb
@@ -222,6 +224,7 @@ test_files:
222
224
  - spec/synvert/core/rewriter/action/insert_action_spec.rb
223
225
  - spec/synvert/core/rewriter/action/insert_after_action_spec.rb
224
226
  - spec/synvert/core/rewriter/action/remove_action_spec.rb
227
+ - spec/synvert/core/rewriter/action/replace_action_spec.rb
225
228
  - spec/synvert/core/rewriter/action/replace_erb_stmt_with_expr_action_spec.rb
226
229
  - spec/synvert/core/rewriter/action/replace_with_action_spec.rb
227
230
  - spec/synvert/core/rewriter/action_spec.rb