synvert-core 0.22.0 → 0.26.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: 8c112197bf98b5adfe2b5826ea3301f06f66511c111906bfd0c72a8c54a10d33
4
- data.tar.gz: adb56b1ae52dd1b87d84d2861b7433586c96ddc6718fafcd79852775f84b38c4
3
+ metadata.gz: a2dcb08f4af325c83596a4ab4ff8ddf43a11500629e96dbccce9fa070dcf7fbc
4
+ data.tar.gz: 4d428fd96a41f1a31b32d6f301562f093c752d6ec63a1dd5641f6f66a62605b7
5
5
  SHA512:
6
- metadata.gz: e2f79639b669fc7b054ba8e57df70925f7f9bfdf6e40144069d41848bc0d0b3df0d60e73fc078c8e78eb29718bc8f3a181ee7964c63a3dcadd9a8981ce31544b
7
- data.tar.gz: 758e0896064a0c15dbe4e3d3d128bc3f42517c2f2802067cccab20f3b366165d7ef5f3203975e261903573f2989f82f3918b09db925a2d896b9bee5897299a58
6
+ metadata.gz: ae47fbf7a0ce9ddae8e221b9508f981534118e5c303ec1736d391db51477a477d338bbfdc215ecd3af5ba4ff6cd0090995c5a17fab6d249a24d46501f941d3b7
7
+ data.tar.gz: 6cf6396cbd3deb8b1d66a1166caa8a584ef0145ebd719b067d1d705f73f7f1d0177e910e16c16c55f19034995d4b641837149185ee318aefe1303e3d8e7db625
data/CHANGELOG.md CHANGED
@@ -1,5 +1,22 @@
1
1
  # CHANGELOG
2
2
 
3
+ ## 0.26.0 (2021-03-30)
4
+
5
+ * attr_reader ruby_version and gem_spec
6
+ * Add `replace` action
7
+
8
+ ## 0.25.0 (2021-03-23)
9
+
10
+ * Use `Gem::Dependency#match?` to check gem version
11
+
12
+ ## 0.24.0 (2021-03-17)
13
+
14
+ * Rename helper method `has_key?` to `key?`
15
+
16
+ ## 0.23.0 (2021-03-14)
17
+
18
+ * Accept a node as goto_node argument
19
+
3
20
  ## 0.22.0 (2021-03-13)
4
21
 
5
22
  * Track `affected_files` for rewriter
@@ -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,28 @@ 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 :send
327
+ case child_name
328
+ when :receiver
329
+ receiver&.loc&.expression
330
+ when :dot
331
+ loc.dot
332
+ when :message
333
+ loc.selector
334
+ when :arguments
335
+ Parser::Source::Range.new('(string)', arguments.first.loc.expression.begin_pos, arguments.last.loc.expression.end_pos) unless arguments.empty?
336
+ end
337
+ else
338
+ raise Synvert::Core::MethodNotSupported, "child_node_range is not handled for #{evaluated.inspect}, child_name: #{child_name}"
339
+ end
340
+ end
341
+
320
342
  # Recursively iterate all child nodes of current node.
321
343
  #
322
344
  # @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
@@ -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 @child_node_name
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
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Synvert
4
4
  module Core
5
- VERSION = '0.22.0'
5
+ VERSION = '0.26.0'
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,54 @@ 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 dot' do
410
+ node = parse('foo.bar(test)')
411
+ range = node.child_node_range(:dot)
412
+ expect(range.to_range).to eq(3...4)
413
+
414
+ node = parse('foobar(test)')
415
+ range = node.child_node_range(:dot)
416
+ expect(range).to be_nil
417
+ end
418
+
419
+ it 'checks message' do
420
+ node = parse('foo.bar(test)')
421
+ range = node.child_node_range(:message)
422
+ expect(range.to_range).to eq(4...7)
423
+
424
+ node = parse('foobar(test)')
425
+ range = node.child_node_range(:message)
426
+ expect(range.to_range).to eq(0...6)
427
+ end
428
+
429
+ it 'checks arguments' do
430
+ node = parse('foo.bar(test)')
431
+ range = node.child_node_range(:arguments)
432
+ expect(range.to_range).to eq(8...12)
433
+
434
+ node = parse('foobar(test)')
435
+ range = node.child_node_range(:arguments)
436
+ expect(range.to_range).to eq(7...11)
437
+
438
+ node = parse('foo.bar')
439
+ range = node.child_node_range(:arguments)
440
+ expect(range).to be_nil
441
+ end
442
+ end
443
+ end
444
+
397
445
  describe '#rewritten_source' do
398
446
  let(:instance) {
399
447
  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.22.0
4
+ version: 0.26.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-03-13 00:00:00.000000000 Z
11
+ date: 2021-03-30 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
@@ -209,7 +211,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
209
211
  - !ruby/object:Gem::Version
210
212
  version: '0'
211
213
  requirements: []
212
- rubygems_version: 3.0.3
214
+ rubygems_version: 3.1.4
213
215
  signing_key:
214
216
  specification_version: 4
215
217
  summary: convert ruby code to better syntax.
@@ -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