synvert-core 0.53.0 → 0.54.3

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: a56859d257b024e86f223d076c77d4effd93d6ffef44de99091d49a62a12841e
4
- data.tar.gz: f0b8658b8701417180ae578eb2ba5c7607e634327ced470e2ad0017980a2e0d8
3
+ metadata.gz: f668f4f483fc617cfd11bf3e8cc786fc390316a160c8b7f64b9fdb034d639797
4
+ data.tar.gz: 8beb643a216285270c886d90e0057cf4b44c3e2b20b1d558dada21700461b84e
5
5
  SHA512:
6
- metadata.gz: 320beadaca69f8e9613f1cd15c5c6fd71bf7bd51881af453ade6e99f56e9516b782264b0d63d4398bbd4fe61af8cb3c7df78d517d0e29762f76de2c2d2091255
7
- data.tar.gz: 22a208b06b416f70e191e7215e21016d603a06ff91a0c7ad8795333906179f46b325e0507ffafd65b7fcebc639e99a6aaba5428632ac6f19b87a2b41dedf9e47
6
+ metadata.gz: d1a0ec10d76c9dfcc400ee3342504a3b4617d49681eccacf464dab47b5344504f4e5d83161a853f6a96f36187d6b6b9f6d58abbc3deb1de93f42a10b6d8adc29
7
+ data.tar.gz: 7308355c918ccb01446fd4d2d74d8a14d9ea3817db2b71fc1745ab6aae6b49f8d9180910e5f786fccaf548a6e4f64d09b5b8c4b033d15c3509cfcba3119f21e3
data/CHANGELOG.md CHANGED
@@ -1,5 +1,21 @@
1
1
  # CHANGELOG
2
2
 
3
+ ## 0.54.3 (2021-09-09)
4
+
5
+ * Fix remove action `begin_pos` and `end_pos`
6
+
7
+ ## 0.54.2 (2021-09-09)
8
+
9
+ * Fix `nil` match
10
+
11
+ ## 0.54.1 (2021-09-08)
12
+
13
+ * Rewrite `remove` action
14
+
15
+ ## 0.54.0 (2021-08-28)
16
+
17
+ * Change `goto_scope` param from array to string
18
+
3
19
  ## 0.53.0 (2021-08-22)
4
20
 
5
21
  * Fix nested child in Node#child_node_range
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # synvert-core-ruby
2
2
 
3
- <img src="https://xinminlabs.github.io/synvert/img/logo_96.png" alt="logo" width="32" height="32" />
3
+ <img src="https://synvert.xinminlabs.com/img/logo_96.png" alt="logo" width="32" height="32" />
4
4
 
5
5
  ![Main workflow](https://github.com/xinminlabs/synvert-core-ruby/actions/workflows/main.yml/badge.svg)
6
6
  [![Gem Version](https://badge.fury.io/rb/synvert-core.png)](http://badge.fury.io/rb/synvert-core)
@@ -36,5 +36,5 @@ Or install it yourself as:
36
36
  4. Push to the branch (`git push origin my-new-feature`)
37
37
  5. Create a new Pull Request
38
38
 
39
- [1]: https://xinminlabs.github.io/synvert/
39
+ [1]: https://synvert.xinminlabs.com
40
40
  [2]: https://rubydoc.info/github/xinminlabs/synvert-core-ruby/master/frames
@@ -576,7 +576,11 @@ module Parser::AST
576
576
 
577
577
  actual.zip(expected).all? { |a, e| match_value?(a, e) }
578
578
  when NilClass
579
- actual.nil?
579
+ if actual.is_a?(Parser::AST::Node)
580
+ :nil == actual.type
581
+ else
582
+ actual.nil?
583
+ end
580
584
  when Numeric
581
585
  if actual.is_a?(Parser::AST::Node)
582
586
  actual.children[0] == expected
@@ -1,21 +1,21 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Synvert::Core
4
- # RemoveAction to delete code.
4
+ # DeleteAction to delete child nodes.
5
5
  class Rewriter::DeleteAction < Rewriter::Action
6
6
  def initialize(instance, *selectors)
7
7
  super(instance, nil)
8
8
  @selectors = selectors
9
9
  end
10
10
 
11
- # Begin position of code to replace.
11
+ # Begin position of code to delete.
12
12
  #
13
13
  # @return [Integer] begin position.
14
14
  def begin_pos
15
15
  @selectors.map { |selector| @node.child_node_range(selector) }.compact.map(&:begin_pos).min
16
16
  end
17
17
 
18
- # End position of code to replace.
18
+ # End position of code to delete.
19
19
  #
20
20
  # @return [Integer] end position.
21
21
  def end_pos
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Synvert::Core
4
- # AddAction to add code to the node.
4
+ # InsertAction to add code to the node.
5
5
  class Rewriter::InsertAction < Rewriter::Action
6
6
  def initialize(instance, code, at:)
7
7
  super(instance, code)
@@ -1,29 +1,57 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Synvert::Core
4
- # RemoveAction to remove code.
4
+ # RemoveAction to remove current node.
5
5
  class Rewriter::RemoveAction < Rewriter::Action
6
- def initialize(instance, code = nil)
7
- super
6
+ def initialize(instance)
7
+ super(instance, nil)
8
8
  end
9
9
 
10
10
  # Begin position of code to replace.
11
11
  #
12
12
  # @return [Integer] begin position.
13
13
  def begin_pos
14
- @node.loc.expression.begin_pos
14
+ if take_whole_line?
15
+ start_index
16
+ else
17
+ @node.loc.expression.begin_pos
18
+ end
15
19
  end
16
20
 
17
21
  # End position of code to replace.
18
22
  #
19
23
  # @return [Integer] end position.
20
24
  def end_pos
21
- @node.loc.expression.end_pos
25
+ if take_whole_line?
26
+ end_index
27
+ else
28
+ @node.loc.expression.end_pos
29
+ end
22
30
  end
23
31
 
24
32
  # The rewritten code, always empty string.
25
33
  def rewritten_code
26
34
  ''
27
35
  end
36
+
37
+ private
38
+
39
+ def take_whole_line?
40
+ @node.to_source == file_source[start_index...end_index].strip
41
+ end
42
+
43
+ def start_index
44
+ index = file_source[0..@node.loc.expression.begin_pos].rindex("\n")
45
+ index ? index + "\n".length : @node.loc.expression.begin_pos
46
+ end
47
+
48
+ def end_index
49
+ index = file_source[@node.loc.expression.end_pos..-1].index("\n")
50
+ index ? @node.loc.expression.end_pos + index + "\n".length : @node.loc.expression.end_pos
51
+ end
52
+
53
+ def file_source
54
+ @file_source ||= @instance.file_source
55
+ end
28
56
  end
29
57
  end
@@ -64,6 +64,11 @@ module Synvert::Core
64
64
  # @return current filename
65
65
  attr_accessor :current_node, :current_file
66
66
 
67
+ # Current file source
68
+ def file_source
69
+ self.class.file_source(current_file)
70
+ end
71
+
67
72
  # Initialize an instance.
68
73
  #
69
74
  # @param rewriter [Synvert::Core::Rewriter]
@@ -107,7 +112,6 @@ module Synvert::Core
107
112
  conflict_actions = get_conflict_actions
108
113
  @actions.reverse_each do |action|
109
114
  source[action.begin_pos...action.end_pos] = action.rewritten_code
110
- source = remove_code_or_whole_line(source, action.line)
111
115
  end
112
116
  @actions = []
113
117
 
@@ -139,7 +143,7 @@ module Synvert::Core
139
143
 
140
144
  # Set current_node properly, process and set current_node back to original current_node.
141
145
  #
142
- # @param node [Parser::AST::Node] node set to current_node
146
+ # @param node [Parser::AST::Node] node set to other_node
143
147
  # @yield process
144
148
  def process_with_other_node(node)
145
149
  original_node = current_node
@@ -177,10 +181,10 @@ module Synvert::Core
177
181
  # Parse goto_node dsl, it creates a [Synvert::Core::Rewriter::GotoScope] to go to a child node,
178
182
  # then continue operating on the child node.
179
183
  #
180
- # @param *child_node_names [Array] the name of the child nodes.
184
+ # @param child_node_name [Symbol|String] the name of the child nodes.
181
185
  # @param block [Block] block code to continue operating on the matching nodes.
182
- def goto_node(*child_node_names, &block)
183
- Rewriter::GotoScope.new(self, *child_node_names, &block).process
186
+ def goto_node(child_node_name, &block)
187
+ Rewriter::GotoScope.new(self, child_node_name, &block).process
184
188
  end
185
189
 
186
190
  # Parse if_exist_node dsl, it creates a [Synvert::Core::Rewriter::IfExistCondition] to check
@@ -323,25 +327,6 @@ module Synvert::Core
323
327
  conflict_actions
324
328
  end
325
329
 
326
- # It checks if code is removed and that line is empty.
327
- #
328
- # @param source [String] source code of file
329
- # @param line [String] the line number
330
- def remove_code_or_whole_line(source, line)
331
- newline_at_end_of_line = source[-1] == "\n"
332
- source_arr = source.split("\n")
333
- if source_arr[line - 1] && source_arr[line - 1].strip.empty?
334
- source_arr.delete_at(line - 1)
335
- if source_arr[line - 2] && source_arr[line - 2].strip.empty? && source_arr[line - 1] &&
336
- source_arr[line - 1].strip.empty?
337
- source_arr.delete_at(line - 1)
338
- end
339
- source_arr.join("\n") + (newline_at_end_of_line ? "\n" : '')
340
- else
341
- source
342
- end
343
- end
344
-
345
330
  # It updates a file with new source code.
346
331
  #
347
332
  # @param file_path [String] the file path
@@ -6,11 +6,11 @@ module Synvert::Core
6
6
  # Initialize a scope
7
7
  #
8
8
  # @param instance [Synvert::Core::Rewriter::Instance]
9
- # @param *child_node_names [Array]
9
+ # @param child_node_name [Symbol|string]
10
10
  # @param block [Block]
11
- def initialize(instance, *child_node_names, &block)
11
+ def initialize(instance, child_node_name, &block)
12
12
  @instance = instance
13
- @child_node_names = child_node_names
13
+ @child_node_name = child_node_name
14
14
  @block = block
15
15
  end
16
16
 
@@ -20,7 +20,7 @@ module Synvert::Core
20
20
  return unless current_node
21
21
 
22
22
  child_node = current_node
23
- @child_node_names.each do |child_node_name|
23
+ @child_node_name.to_s.split('.').each do |child_node_name|
24
24
  child_node = child_node_name.is_a?(Parser::AST::Node) ? child_node_name : child_node.send(child_node_name)
25
25
  end
26
26
  @instance.process_with_other_node child_node do
@@ -81,7 +81,7 @@ module Synvert::Core
81
81
  def fetch(group, name)
82
82
  group = group.to_s
83
83
  name = name.to_s
84
- if exist? group, name
84
+ if rewriters[group] && rewriters[group][name]
85
85
  rewriters[group][name]
86
86
  else
87
87
  raise RewriterNotFound, "Rewriter #{group} #{name} not found"
@@ -96,34 +96,13 @@ module Synvert::Core
96
96
  # @return [Synvert::Core::Rewriter] the registered rewriter.
97
97
  # @raise [Synvert::Core::RewriterNotFound] if the registered rewriter is not found.
98
98
  def call(group, name, sandbox = false)
99
- group = group.to_s
100
- name = name.to_s
101
- if exist? group, name
102
- rewriter = rewriters[group][name]
103
- if sandbox
104
- rewriter.process_with_sandbox
105
- else
106
- rewriter.process
107
- end
108
- rewriter
109
- else
110
- raise RewriterNotFound, "Rewriter #{group}/#{name} not found"
111
- end
112
- end
113
-
114
- # Check if one rewriter exist.
115
- #
116
- # @param group [String] the rewriter group.
117
- # @param name [String] the rewriter name.
118
- # @return [Boolean] true if the rewriter exist.
119
- def exist?(group, name)
120
- group = group.to_s
121
- name = name.to_s
122
- if rewriters[group] && rewriters[group][name]
123
- true
99
+ rewriter = fetch(group, name)
100
+ if sandbox
101
+ rewriter.process_with_sandbox
124
102
  else
125
- false
103
+ rewriter.process
126
104
  end
105
+ rewriter
127
106
  end
128
107
 
129
108
  # Get all available rewriters
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Synvert
4
4
  module Core
5
- VERSION = '0.53.0'
5
+ VERSION = '0.54.3'
6
6
  end
7
7
  end
@@ -7,7 +7,7 @@ module Synvert::Core
7
7
  subject {
8
8
  source = "user = User.new params[:user]\nuser.save\nrender\n"
9
9
  send_node = Parser::CurrentRuby.parse(source).children[1]
10
- instance = double(current_node: send_node)
10
+ instance = double(current_node: send_node, file_source: source)
11
11
  Rewriter::RemoveAction.new(instance)
12
12
  }
13
13
 
@@ -16,7 +16,7 @@ module Synvert::Core
16
16
  end
17
17
 
18
18
  it 'gets end_pos' do
19
- expect(subject.end_pos).to eq "user = User.new params[:user]\nuser.save".length
19
+ expect(subject.end_pos).to eq "user = User.new params[:user]\nuser.save\n".length
20
20
  end
21
21
 
22
22
  it 'gets rewritten_code' do
@@ -54,9 +54,9 @@ module Synvert::Core
54
54
  it 'parses goto_node' do
55
55
  scope = double
56
56
  block = proc {}
57
- expect(Rewriter::GotoScope).to receive(:new).with(instance, :caller, :receiver, &block).and_return(scope)
57
+ expect(Rewriter::GotoScope).to receive(:new).with(instance, 'caller.receiver', &block).and_return(scope)
58
58
  expect(scope).to receive(:process)
59
- instance.goto_node(:caller, :receiver, &block)
59
+ instance.goto_node('caller.receiver', &block)
60
60
  end
61
61
 
62
62
  it 'parses if_exist_node' do
@@ -24,7 +24,7 @@ module Synvert::Core
24
24
  run = false
25
25
  type_in_scope = nil
26
26
  scope =
27
- Rewriter::GotoScope.new instance, :caller, :receiver do
27
+ Rewriter::GotoScope.new instance, 'caller.receiver' do
28
28
  run = true
29
29
  type_in_scope = node.type
30
30
  end
@@ -249,17 +249,6 @@ module Synvert::Core
249
249
  expect { Rewriter.call 'group', 'rewriter' }.to raise_error(RewriterNotFound)
250
250
  end
251
251
 
252
- context 'exist?' do
253
- it 'returns true if rewriter exists' do
254
- Rewriter.new 'group', 'rewriter'
255
- expect(Rewriter.exist?('group', 'rewriter')).to be_truthy
256
- end
257
-
258
- it 'returns false if rewriter does not exist' do
259
- expect(Rewriter.exist?('group', 'rewriter')).to be_falsey
260
- end
261
- end
262
-
263
252
  context 'available' do
264
253
  it 'lists empty rewriters' do
265
254
  expect(Rewriter.availables).to eq({})
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.53.0
4
+ version: 0.54.3
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-08-22 00:00:00.000000000 Z
11
+ date: 2021-09-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport