synvert-core 0.54.3 → 0.57.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.
Files changed (34) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +14 -5
  3. data/lib/synvert/core/configuration.rb +5 -1
  4. data/lib/synvert/core/node_ext.rb +25 -4
  5. data/lib/synvert/core/rewriter/action/append_action.rb +3 -16
  6. data/lib/synvert/core/rewriter/action/delete_action.rb +5 -12
  7. data/lib/synvert/core/rewriter/action/insert_action.rb +3 -16
  8. data/lib/synvert/core/rewriter/action/insert_after_action.rb +3 -12
  9. data/lib/synvert/core/rewriter/action/prepend_action.rb +13 -21
  10. data/lib/synvert/core/rewriter/action/remove_action.rb +8 -18
  11. data/lib/synvert/core/rewriter/action/replace_action.rb +3 -12
  12. data/lib/synvert/core/rewriter/action/replace_erb_stmt_with_expr_action.rb +3 -11
  13. data/lib/synvert/core/rewriter/action/replace_with_action.rb +3 -12
  14. data/lib/synvert/core/rewriter/action/wrap_action.rb +3 -12
  15. data/lib/synvert/core/rewriter/action.rb +47 -0
  16. data/lib/synvert/core/rewriter/condition/if_only_exist_condition.rb +1 -1
  17. data/lib/synvert/core/rewriter/instance.rb +12 -11
  18. data/lib/synvert/core/rewriter/ruby_version.rb +10 -2
  19. data/lib/synvert/core/rewriter.rb +1 -1
  20. data/lib/synvert/core/version.rb +1 -1
  21. data/spec/synvert/core/node_ext_spec.rb +25 -0
  22. data/spec/synvert/core/rewriter/action/append_action_spec.rb +2 -2
  23. data/spec/synvert/core/rewriter/action/delete_action_spec.rb +2 -2
  24. data/spec/synvert/core/rewriter/action/insert_action_spec.rb +2 -2
  25. data/spec/synvert/core/rewriter/action/insert_after_action_spec.rb +1 -1
  26. data/spec/synvert/core/rewriter/action/prepend_action_spec.rb +4 -4
  27. data/spec/synvert/core/rewriter/action/remove_action_spec.rb +1 -1
  28. data/spec/synvert/core/rewriter/action/replace_action_spec.rb +1 -1
  29. data/spec/synvert/core/rewriter/action/replace_with_action_spec.rb +2 -2
  30. data/spec/synvert/core/rewriter/action/wrap_action_spec.rb +1 -1
  31. data/spec/synvert/core/rewriter/instance_spec.rb +32 -12
  32. data/spec/synvert/core/rewriter/ruby_version_spec.rb +5 -0
  33. data/spec/synvert/core/rewriter_spec.rb +4 -2
  34. metadata +2 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f668f4f483fc617cfd11bf3e8cc786fc390316a160c8b7f64b9fdb034d639797
4
- data.tar.gz: 8beb643a216285270c886d90e0057cf4b44c3e2b20b1d558dada21700461b84e
3
+ metadata.gz: '01935a8e5222f3058d6bcca0057cbe684ce0a43dabeaeac97dac0aa17c230b79'
4
+ data.tar.gz: 427851e9745c4c960b1f437c397e9332ebf6a8df4126c58652927c9810db7d05
5
5
  SHA512:
6
- metadata.gz: d1a0ec10d76c9dfcc400ee3342504a3b4617d49681eccacf464dab47b5344504f4e5d83161a853f6a96f36187d6b6b9f6d58abbc3deb1de93f42a10b6d8adc29
7
- data.tar.gz: 7308355c918ccb01446fd4d2d74d8a14d9ea3817db2b71fc1745ab6aae6b49f8d9180910e5f786fccaf548a6e4f64d09b5b8c4b033d15c3509cfcba3119f21e3
6
+ metadata.gz: 50a73df1cb5034afeb269776f5e4bf76873b236e490fa54e6bffd91dabfb2726260b99bca95230022314be890454645b8c032c4006c22271a7a460c50b77e3dc
7
+ data.tar.gz: c7ca6e209b229a3951b6846173268d254034e3ff9480e47add2e7649326ab004d806f09ec784fdf86154c8414c7e9e947e6ea72e6fbc5c2d65018f1909928e18
data/CHANGELOG.md CHANGED
@@ -1,15 +1,24 @@
1
1
  # CHANGELOG
2
2
 
3
- ## 0.54.3 (2021-09-09)
3
+ ## 0.57.0 (2021-10-02)
4
4
 
5
- * Fix remove action `begin_pos` and `end_pos`
5
+ * Compare ruby version in `.ruby-version` or `.rvmrc`
6
+ * Support `left_value` and `right_value` for `casgn` node
7
+ * Refactor - `calculate_position` to set `begin_pos` and `end_pos`
8
+ * Abstract `squeeze_spaces` and `squeeze_lines`
9
+ * Remove unused comma after delete/remove action
10
+ * Handle array child node in `childNodeRange`
6
11
 
7
- ## 0.54.2 (2021-09-09)
12
+ ## 0.56.0 (2021-09-14)
8
13
 
9
- * Fix `nil` match
14
+ * Support `name` for `:lvar`, `:ivar`, `:cvar`
15
+ * Delete one more space if two spaces left
10
16
 
11
- ## 0.54.1 (2021-09-08)
17
+ ## 0.55.0 (2021-09-11)
12
18
 
19
+ * Add `Configuration.show_run_process`
20
+ * Fix remove action `begin_pos` and `end_pos`
21
+ * Fix `nil` match
13
22
  * Rewrite `remove` action
14
23
 
15
24
  ## 0.54.0 (2021-08-28)
@@ -4,7 +4,7 @@ module Synvert::Core
4
4
  # Synvert global configuration.
5
5
  class Configuration
6
6
  class << self
7
- attr_writer :path, :skip_files
7
+ attr_writer :path, :skip_files, :show_run_process
8
8
 
9
9
  def path
10
10
  @path || '.'
@@ -13,6 +13,10 @@ module Synvert::Core
13
13
  def skip_files
14
14
  @skip_files || []
15
15
  end
16
+
17
+ def show_run_process
18
+ @show_run_process || false
19
+ end
16
20
  end
17
21
  end
18
22
  end
@@ -9,7 +9,7 @@ module Parser::AST
9
9
  # @raise [Synvert::Core::MethodNotSupported] if calls on other node.
10
10
  def name
11
11
  case type
12
- when :class, :module, :def, :arg, :blockarg, :restarg
12
+ when :class, :module, :def, :arg, :blockarg, :restarg, :lvar, :ivar, :cvar
13
13
  children[0]
14
14
  when :defs, :const
15
15
  children[1]
@@ -215,7 +215,7 @@ module Parser::AST
215
215
  # @return [Parser::AST::Node] variable nodes.
216
216
  # @raise [Synvert::Core::MethodNotSupported] if calls on other node.
217
217
  def left_value
218
- if %i[masgn lvasgn ivasgn].include? type
218
+ if %i[masgn lvasgn ivasgn cvasgn].include? type
219
219
  children[0]
220
220
  elsif :or_asgn == type
221
221
  children[0].children[0]
@@ -229,7 +229,7 @@ module Parser::AST
229
229
  # @return [Array<Parser::AST::Node>] variable nodes.
230
230
  # @raise [Synvert::Core::MethodNotSupported] if calls on other node.
231
231
  def right_value
232
- if %i[masgn lvasgn ivasgn or_asgn].include? type
232
+ if %i[masgn lvasgn ivasgn cvasgn or_asgn].include? type
233
233
  children[1]
234
234
  else
235
235
  raise Synvert::Core::MethodNotSupported, "right_value is not handled for #{debug_info}"
@@ -373,7 +373,28 @@ module Parser::AST
373
373
  if respond_to?(direct_child_name)
374
374
  child_node = send(direct_child_name)
375
375
 
376
- return child_node.child_node_range(nested_child_name) if nested_child_name
376
+ if nested_child_name
377
+ if child_node.is_a?(Array)
378
+ child_direct_child_name, *child_nested_child_name = nested_child_name
379
+ child_direct_child_node = child_direct_child_name =~ /\A\d+\z/ ? child_node[child_direct_child_name] : child_node.send(child_direct_child_name)
380
+ if child_nested_child_name.length > 0
381
+ return child_direct_child_node.child_node_range(child_nested_child_name.join('.'))
382
+ elsif child_direct_child_node
383
+ return (
384
+ Parser::Source::Range.new(
385
+ '(string)',
386
+ child_direct_child_node.loc.expression.begin_pos,
387
+ child_direct_child_node.loc.expression.end_pos
388
+ )
389
+ )
390
+ else
391
+ raise Synvert::Core::MethodNotSupported,
392
+ "child_node_range is not handled for #{debug_info}, child_name: #{child_name}"
393
+ end
394
+ end
395
+
396
+ return child_node.child_node_range(nested_child_name)
397
+ end
377
398
 
378
399
  return nil if child_node.nil?
379
400
 
@@ -5,22 +5,9 @@ module Synvert::Core
5
5
  class Rewriter::AppendAction < Rewriter::Action
6
6
  END_LENGTH = "\nend".length
7
7
 
8
- # Begin position to append code.
9
- #
10
- # @return [Integer] begin position.
11
- def begin_pos
12
- if :begin == @node.type
13
- @node.loc.expression.end_pos
14
- else
15
- @node.loc.expression.end_pos - @node.column - END_LENGTH
16
- end
17
- end
18
-
19
- # End position, always same to begin position.
20
- #
21
- # @return [Integer] end position.
22
- def end_pos
23
- begin_pos
8
+ def calculate_position
9
+ @begin_pos = :begin == @node.type ? @node.loc.expression.end_pos : @node.loc.expression.end_pos - @node.column - END_LENGTH
10
+ @end_pos = @begin_pos
24
11
  end
25
12
 
26
13
  private
@@ -8,18 +8,11 @@ module Synvert::Core
8
8
  @selectors = selectors
9
9
  end
10
10
 
11
- # Begin position of code to delete.
12
- #
13
- # @return [Integer] begin position.
14
- def begin_pos
15
- @selectors.map { |selector| @node.child_node_range(selector) }.compact.map(&:begin_pos).min
16
- end
17
-
18
- # End position of code to delete.
19
- #
20
- # @return [Integer] end position.
21
- def end_pos
22
- @selectors.map { |selector| @node.child_node_range(selector) }.compact.map(&:end_pos).max
11
+ def calculate_position
12
+ @begin_pos = @selectors.map { |selector| @node.child_node_range(selector) }.compact.map(&:begin_pos).min
13
+ @end_pos = @selectors.map { |selector| @node.child_node_range(selector) }.compact.map(&:end_pos).max
14
+ squeeze_spaces
15
+ remove_comma
23
16
  end
24
17
 
25
18
  # The rewritten code, always empty string.
@@ -8,22 +8,9 @@ module Synvert::Core
8
8
  @at = at
9
9
  end
10
10
 
11
- # Begin position to insert code.
12
- #
13
- # @return [Integer] begin position.
14
- def begin_pos
15
- if @at == 'end'
16
- @node.loc.expression.end_pos
17
- else
18
- @node.loc.expression.begin_pos
19
- end
20
- end
21
-
22
- # End position, always same to begin position.
23
- #
24
- # @return [Integer] end position.
25
- def end_pos
26
- begin_pos
11
+ def calculate_position
12
+ @begin_pos = @at == 'end' ? @node.loc.expression.end_pos : @node.loc.expression.begin_pos
13
+ @end_pos = @begin_pos
27
14
  end
28
15
 
29
16
  # The rewritten source code.
@@ -3,18 +3,9 @@
3
3
  module Synvert::Core
4
4
  # InsertAfterAction to insert code next to the node.
5
5
  class Rewriter::InsertAfterAction < Rewriter::Action
6
- # Begin position to insert code.
7
- #
8
- # @return [Integer] begin position.
9
- def begin_pos
10
- @node.loc.expression.end_pos
11
- end
12
-
13
- # End position, always same to begin position.
14
- #
15
- # @return [Integer] end position.
16
- def end_pos
17
- begin_pos
6
+ def calculate_position
7
+ @begin_pos = @node.loc.expression.end_pos
8
+ @end_pos = @begin_pos
18
9
  end
19
10
 
20
11
  private
@@ -5,29 +5,21 @@ module Synvert::Core
5
5
  class Rewriter::PrependAction < Rewriter::Action
6
6
  DO_LENGTH = ' do'.length
7
7
 
8
- # Begin position to prepend code.
9
- #
10
- # @return [Integer] begin position.
11
- def begin_pos
12
- case @node.type
13
- when :block
14
- if @node.children[1].children.empty?
15
- @node.children[0].loc.expression.end_pos + DO_LENGTH
8
+ def calculate_position
9
+ @begin_pos =
10
+ case @node.type
11
+ when :block
12
+ if @node.children[1].children.empty?
13
+ @node.children[0].loc.expression.end_pos + DO_LENGTH
14
+ else
15
+ @node.children[1].loc.expression.end_pos
16
+ end
17
+ when :class
18
+ @node.children[1] ? @node.children[1].loc.expression.end_pos : @node.children[0].loc.expression.end_pos
16
19
  else
17
- @node.children[1].loc.expression.end_pos
20
+ @node.children.last.loc.expression.end_pos
18
21
  end
19
- when :class
20
- @node.children[1] ? @node.children[1].loc.expression.end_pos : @node.children[0].loc.expression.end_pos
21
- else
22
- @node.children.last.loc.expression.end_pos
23
- end
24
- end
25
-
26
- # End position, always same to begin position.
27
- #
28
- # @return [Integer] end position.
29
- def end_pos
30
- begin_pos
22
+ @end_pos = @begin_pos
31
23
  end
32
24
 
33
25
  private
@@ -10,22 +10,16 @@ module Synvert::Core
10
10
  # Begin position of code to replace.
11
11
  #
12
12
  # @return [Integer] begin position.
13
- def begin_pos
13
+ def calculate_position
14
14
  if take_whole_line?
15
- start_index
15
+ @begin_pos = start_index
16
+ @end_pos = end_index
17
+ squeeze_lines
16
18
  else
17
- @node.loc.expression.begin_pos
18
- end
19
- end
20
-
21
- # End position of code to replace.
22
- #
23
- # @return [Integer] end position.
24
- def end_pos
25
- if take_whole_line?
26
- end_index
27
- else
28
- @node.loc.expression.end_pos
19
+ @begin_pos = @node.loc.expression.begin_pos
20
+ @end_pos = @node.loc.expression.end_pos
21
+ squeeze_spaces
22
+ remove_comma
29
23
  end
30
24
  end
31
25
 
@@ -49,9 +43,5 @@ module Synvert::Core
49
43
  index = file_source[@node.loc.expression.end_pos..-1].index("\n")
50
44
  index ? @node.loc.expression.end_pos + index + "\n".length : @node.loc.expression.end_pos
51
45
  end
52
-
53
- def file_source
54
- @file_source ||= @instance.file_source
55
- end
56
46
  end
57
47
  end
@@ -8,18 +8,9 @@ module Synvert::Core
8
8
  @selectors = selectors
9
9
  end
10
10
 
11
- # Begin position of code to replace.
12
- #
13
- # @return [Integer] begin position.
14
- def begin_pos
15
- @selectors.map { |selector| @node.child_node_range(selector).begin_pos }.min
16
- end
17
-
18
- # End position of code to replace.
19
- #
20
- # @return [Integer] end position.
21
- def end_pos
22
- @selectors.map { |selector| @node.child_node_range(selector).end_pos }.max
11
+ def calculate_position
12
+ @begin_pos = @selectors.map { |selector| @node.child_node_range(selector).begin_pos }.min
13
+ @end_pos = @selectors.map { |selector| @node.child_node_range(selector).end_pos }.max
23
14
  end
24
15
 
25
16
  # The rewritten source code.
@@ -8,25 +8,17 @@ module Synvert::Core
8
8
  super
9
9
  end
10
10
 
11
- # Begin position of code to replace.
12
- #
13
- # @return [Integer] begin position.
14
- def begin_pos
11
+ def calculate_position
15
12
  node_begin_pos = @node.loc.expression.begin_pos
16
13
  while @node.loc.expression.source_buffer.source[node_begin_pos -= 1] == ' '
17
14
  end
18
- node_begin_pos - Engine::ERUBY_STMT_SPLITTER.length + 1
19
- end
15
+ @begin_pos = node_begin_pos - Engine::ERUBY_STMT_SPLITTER.length + 1
20
16
 
21
- # End position of code to replace.
22
- #
23
- # @return [Integer] end position.
24
- def end_pos
25
17
  node_begin_pos = @node.loc.expression.begin_pos
26
18
  node_begin_pos += @node.loc.expression.source.index 'do'
27
19
  while @node.loc.expression.source_buffer.source[node_begin_pos += 1] != '@'
28
20
  end
29
- node_begin_pos
21
+ @end_pos = node_begin_pos
30
22
  end
31
23
 
32
24
  # The rewritten erb expr code.
@@ -3,18 +3,9 @@
3
3
  module Synvert::Core
4
4
  # ReplaceWithAction to replace code.
5
5
  class Rewriter::ReplaceWithAction < Rewriter::Action
6
- # Begin position of code to replace.
7
- #
8
- # @return [Integer] begin position.
9
- def begin_pos
10
- @node.loc.expression.begin_pos
11
- end
12
-
13
- # End position of code to replace.
14
- #
15
- # @return [Integer] end position.
16
- def end_pos
17
- @node.loc.expression.end_pos
6
+ def calculate_position
7
+ @begin_pos = @node.loc.expression.begin_pos
8
+ @end_pos = @node.loc.expression.end_pos
18
9
  end
19
10
 
20
11
  # The rewritten source code with proper indent.
@@ -11,18 +11,9 @@ module Synvert::Core
11
11
  @indent = indent || @node.column
12
12
  end
13
13
 
14
- # Begin position of code to wrap.
15
- #
16
- # @return [Integer] begin position.
17
- def begin_pos
18
- @node.loc.expression.begin_pos
19
- end
20
-
21
- # End position of code to wrap.
22
- #
23
- # @return [Integer] end position.
24
- def end_pos
25
- @node.loc.expression.end_pos
14
+ def calculate_position
15
+ @begin_pos = @node.loc.expression.begin_pos
16
+ @end_pos = @node.loc.expression.end_pos
26
17
  end
27
18
 
28
19
  # The rewritten source code.
@@ -5,6 +5,12 @@ module Synvert::Core
5
5
  class Rewriter::Action
6
6
  DEFAULT_INDENT = 2
7
7
 
8
+ # @!attribute [r] begin_pos
9
+ # @return [Integer] begin position
10
+ # @!attribute [r] end_pos
11
+ # @return [Integer] end position
12
+ attr_reader :begin_pos, :end_pos
13
+
8
14
  # Initialize an action.
9
15
  #
10
16
  # @param instance [Synvert::Core::Rewriter::Instance]
@@ -15,6 +21,11 @@ module Synvert::Core
15
21
  @node = @instance.current_node
16
22
  end
17
23
 
24
+ def process
25
+ calculate_position
26
+ self
27
+ end
28
+
18
29
  # Line number of current node.
19
30
  #
20
31
  # @return [Integer] line number.
@@ -33,11 +44,47 @@ module Synvert::Core
33
44
  end
34
45
  end
35
46
 
47
+ protected
48
+
36
49
  # The rewritten source code.
37
50
  #
38
51
  # @return [String] rewritten source code.
39
52
  def rewritten_source
40
53
  @rewritten_source ||= @node.rewritten_source(@code)
41
54
  end
55
+
56
+ def squeeze_spaces
57
+ if file_source[@begin_pos - 1] == ' ' && file_source[@end_pos] == ' '
58
+ @begin_pos = @begin_pos - 1
59
+ end
60
+ end
61
+
62
+ def squeeze_lines
63
+ lines = file_source.split("\n")
64
+ begin_line = @node.loc.expression.first_line
65
+ end_line = @node.loc.expression.last_line
66
+ before_line_is_blank = begin_line == 1 || lines[begin_line - 2] == ''
67
+ after_line_is_blank = lines[end_line] == ''
68
+
69
+ if lines.length > 1 && before_line_is_blank && after_line_is_blank
70
+ @end_pos = @end_pos + "\n".length
71
+ end
72
+ end
73
+
74
+ def remove_comma
75
+ if ',' == file_source[@begin_pos - 1]
76
+ @begin_pos = @begin_pos - 1
77
+ elsif ', ' == file_source[@begin_pos - 2, 2]
78
+ @begin_pos = @begin_pos - 2
79
+ elsif ', ' == file_source[@end_pos, 2]
80
+ @end_pos = @end_pos + 2
81
+ elsif ',' == file_source[@end_pos]
82
+ @end_pos = @end_pos + 1
83
+ end
84
+ end
85
+
86
+ def file_source
87
+ @file_source ||= @instance.file_source
88
+ end
42
89
  end
43
90
  end
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Synvert::Core
4
- # IfExistCondition checks if node has only one child node and the child node matches rules.
4
+ # IfOnlyExistCondition checks if node has only one child node and the child node matches rules.
5
5
  class Rewriter::IfOnlyExistCondition < Rewriter::Condition
6
6
  # check if only have one child node and the child node matches rules.
7
7
  def match?
@@ -46,7 +46,7 @@ module Synvert::Core
46
46
  # @param source [String] file source
47
47
  def write_file(file_path, source)
48
48
  source = Engine::ERB.decode(source) if /\.erb/.match?(file_path)
49
- File.write file_path, source.gsub(/ +\n/, "\n")
49
+ File.write(file_path, source.gsub(/ +\n/, "\n"))
50
50
  @file_source[file_path] = nil
51
51
  @file_ast[file_path] = nil
52
52
  end
@@ -92,6 +92,7 @@ module Synvert::Core
92
92
  next if Configuration.skip_files.include? file_path
93
93
 
94
94
  begin
95
+ puts file_path if Configuration.show_run_process
95
96
  conflict_actions = []
96
97
  source = +self.class.file_source(file_path)
97
98
  ast = self.class.file_ast(file_path)
@@ -220,7 +221,7 @@ module Synvert::Core
220
221
  #
221
222
  # @param code [String] code need to be appended.
222
223
  def append(code)
223
- @actions << Rewriter::AppendAction.new(self, code)
224
+ @actions << Rewriter::AppendAction.new(self, code).process
224
225
  end
225
226
 
226
227
  # Parse prepend dsl, it creates a [Synvert::Core::Rewriter::PrependAction] to
@@ -228,7 +229,7 @@ module Synvert::Core
228
229
  #
229
230
  # @param code [String] code need to be prepended.
230
231
  def prepend(code)
231
- @actions << Rewriter::PrependAction.new(self, code)
232
+ @actions << Rewriter::PrependAction.new(self, code).process
232
233
  end
233
234
 
234
235
  # Parse insert dsl, it creates a [Synvert::Core::Rewriter::InsertAction] to
@@ -237,7 +238,7 @@ module Synvert::Core
237
238
  # @param code [String] code need to be inserted.
238
239
  # @param at [String] insert position, beginning or end, end is the default.
239
240
  def insert(code, at: 'end')
240
- @actions << Rewriter::InsertAction.new(self, code, at: at)
241
+ @actions << Rewriter::InsertAction.new(self, code, at: at).process
241
242
  end
242
243
 
243
244
  # Parse insert_after dsl, it creates a [Synvert::Core::Rewriter::InsertAfterAction] to
@@ -245,7 +246,7 @@ module Synvert::Core
245
246
  #
246
247
  # @param code [String] code need to be inserted.
247
248
  def insert_after(node)
248
- @actions << Rewriter::InsertAfterAction.new(self, node)
249
+ @actions << Rewriter::InsertAfterAction.new(self, node).process
249
250
  end
250
251
 
251
252
  # Parse replace_with dsl, it creates a [Synvert::Core::Rewriter::ReplaceWithAction] to
@@ -253,7 +254,7 @@ module Synvert::Core
253
254
  #
254
255
  # @param code [String] code need to be replaced with.
255
256
  def replace_with(code)
256
- @actions << Rewriter::ReplaceWithAction.new(self, code)
257
+ @actions << Rewriter::ReplaceWithAction.new(self, code).process
257
258
  end
258
259
 
259
260
  # Parse replace with dsl, it creates a [Synvert::Core::Rewriter::ReplaceAction] to
@@ -262,25 +263,25 @@ module Synvert::Core
262
263
  # @param selectors [Array<Symbol>] selector names of child node.
263
264
  # @param with [String] code need to be replaced with.
264
265
  def replace(*selectors, with:)
265
- @actions << Rewriter::ReplaceAction.new(self, *selectors, with: with)
266
+ @actions << Rewriter::ReplaceAction.new(self, *selectors, with: with).process
266
267
  end
267
268
 
268
269
  # Parse replace_erb_stmt_with_expr dsl, it creates a [Synvert::Core::Rewriter::ReplaceErbStmtWithExprAction] to
269
270
  # replace erb stmt code to expr code.
270
271
  def replace_erb_stmt_with_expr
271
- @actions << Rewriter::ReplaceErbStmtWithExprAction.new(self)
272
+ @actions << Rewriter::ReplaceErbStmtWithExprAction.new(self).process
272
273
  end
273
274
 
274
275
  # Parse remove dsl, it creates a [Synvert::Core::Rewriter::RemoveAction] to remove current node.
275
276
  def remove
276
- @actions << Rewriter::RemoveAction.new(self)
277
+ @actions << Rewriter::RemoveAction.new(self).process
277
278
  end
278
279
 
279
280
  # Parse delete dsl, it creates a [Synvert::Core::Rewriter::DeleteAction] to delete child nodes.
280
281
  #
281
282
  # @param selectors [Array<Symbol>] selector names of child node.
282
283
  def delete(*selectors)
283
- @actions << Rewriter::DeleteAction.new(self, *selectors)
284
+ @actions << Rewriter::DeleteAction.new(self, *selectors).process
284
285
  end
285
286
 
286
287
  # Parse wrap with dsl, it creates a [Synvert::Core::Rewriter::WrapAction] to
@@ -289,7 +290,7 @@ module Synvert::Core
289
290
  # @param with [String] code need to be wrapped with.
290
291
  # @param indent [Integer] number of whitespaces.
291
292
  def wrap(with:, indent: nil)
292
- @actions << Rewriter::WrapAction.new(self, with: with, indent: indent)
293
+ @actions << Rewriter::WrapAction.new(self, with: with, indent: indent).process
293
294
  end
294
295
 
295
296
  # Parse warn dsl, it creates a [Synvert::Core::Rewriter::Warning] to save warning message.
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Synvert::Core
4
- # GemSpec checks and compares gem version.
4
+ # GemSpec checks and compares ruby version.
5
5
  class Rewriter::RubyVersion
6
6
  attr_reader :version
7
7
 
@@ -16,7 +16,15 @@ module Synvert::Core
16
16
  #
17
17
  # @return [Boolean] true if matches, otherwise false.
18
18
  def match?
19
- Gem::Version.new(RUBY_VERSION) >= Gem::Version.new(@version)
19
+ if File.exist?(File.join(Configuration.path, '.ruby-version'))
20
+ versionFile = '.ruby-version'
21
+ elsif File.exist?(File.join(Configuration.path, '.rvmrc'))
22
+ versionFile = '.rvmrc'
23
+ end
24
+ return true if !versionFile
25
+
26
+ version = File.read(File.join(Configuration.path, versionFile))
27
+ Gem::Version.new(version) >= Gem::Version.new(@version)
20
28
  end
21
29
  end
22
30
  end
@@ -213,7 +213,7 @@ module Synvert::Core
213
213
  end
214
214
  end
215
215
 
216
- # Parse if_ruby dal, it checks if ruby version if greater than or equal to the specified ruby version.
216
+ # Parse if_ruby dsl, it checks if ruby version if greater than or equal to the specified ruby version.
217
217
  #
218
218
  # @param version, [String] specified ruby version.
219
219
  def if_ruby(version)
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Synvert
4
4
  module Core
5
- VERSION = '0.54.3'
5
+ VERSION = '0.57.0'
6
6
  end
7
7
  end
@@ -42,6 +42,21 @@ describe Parser::AST::Node do
42
42
  expect(node.name).to eq :Synvert
43
43
  end
44
44
 
45
+ it 'gets for lvar node' do
46
+ node = parse("foo = 'bar'\nfoo").children[1]
47
+ expect(node.name).to eq :foo
48
+ end
49
+
50
+ it 'gets for ivar node' do
51
+ node = parse("@foo = 'bar'\n@foo").children[1]
52
+ expect(node.name).to eq :@foo
53
+ end
54
+
55
+ it 'gets for cvar node' do
56
+ node = parse("@@foo = 'bar'\n@@foo").children[1]
57
+ expect(node.name).to eq :@@foo
58
+ end
59
+
45
60
  it 'gets for mlhs node' do
46
61
  node = parse('var.each { |(param1, param2)| }')
47
62
  expect(node.arguments.first.name).to eq node.arguments.first
@@ -267,6 +282,11 @@ describe Parser::AST::Node do
267
282
  expect(node.left_value).to eq :@a
268
283
  end
269
284
 
285
+ it 'gets for cvasgn' do
286
+ node = parse('@@a = 1')
287
+ expect(node.left_value).to eq :@@a
288
+ end
289
+
270
290
  it 'gets for or_asgn' do
271
291
  node = parse('a ||= 1')
272
292
  expect(node.left_value).to eq :a
@@ -294,6 +314,11 @@ describe Parser::AST::Node do
294
314
  expect(node.right_value).to eq parse('1')
295
315
  end
296
316
 
317
+ it 'gets for cvasgn' do
318
+ node = parse('@@a = 1')
319
+ expect(node.right_value).to eq parse('1')
320
+ end
321
+
297
322
  it 'gets for or_asgn' do
298
323
  node = parse('a ||= 1')
299
324
  expect(node.right_value).to eq parse('1')
@@ -9,7 +9,7 @@ module Synvert::Core
9
9
  source = "class User\n has_many :posts\nend"
10
10
  class_node = Parser::CurrentRuby.parse(source)
11
11
  instance = double(current_node: class_node)
12
- Rewriter::AppendAction.new(instance, "def as_json\n super\nend")
12
+ Rewriter::AppendAction.new(instance, "def as_json\n super\nend").process
13
13
  end
14
14
 
15
15
  it 'gets begin_pos' do
@@ -30,7 +30,7 @@ module Synvert::Core
30
30
  source = "gem 'rails'\ngem 'mysql2'"
31
31
  begin_node = Parser::CurrentRuby.parse(source)
32
32
  instance = double(current_node: begin_node)
33
- Rewriter::AppendAction.new(instance, "gem 'twitter'")
33
+ Rewriter::AppendAction.new(instance, "gem 'twitter'").process
34
34
  end
35
35
 
36
36
  it 'gets begin_pos' do
@@ -7,8 +7,8 @@ module Synvert::Core
7
7
  subject {
8
8
  source = 'arr.map {}.flatten'
9
9
  node = Parser::CurrentRuby.parse(source)
10
- instance = double(current_node: node)
11
- Rewriter::DeleteAction.new(instance, :dot, :message)
10
+ instance = double(current_node: node, file_source: source)
11
+ Rewriter::DeleteAction.new(instance, :dot, :message).process
12
12
  }
13
13
 
14
14
  it 'gets begin_pos' do
@@ -9,7 +9,7 @@ module Synvert::Core
9
9
  source = " User.where(username: 'Richard')"
10
10
  node = Parser::CurrentRuby.parse(source)
11
11
  instance = double(current_node: node)
12
- Rewriter::InsertAction.new(instance, '.first', at: 'end')
12
+ Rewriter::InsertAction.new(instance, '.first', at: 'end').process
13
13
  }
14
14
 
15
15
  it 'gets begin_pos' do
@@ -30,7 +30,7 @@ module Synvert::Core
30
30
  source = " open('http://test.com')"
31
31
  node = Parser::CurrentRuby.parse(source)
32
32
  instance = double(current_node: node)
33
- Rewriter::InsertAction.new(instance, 'URI.', at: 'beginning')
33
+ Rewriter::InsertAction.new(instance, 'URI.', at: 'beginning').process
34
34
  }
35
35
 
36
36
  it 'gets begin_pos' do
@@ -8,7 +8,7 @@ module Synvert::Core
8
8
  source = ' include Foo'
9
9
  node = Parser::CurrentRuby.parse(source)
10
10
  instance = double(current_node: node)
11
- Rewriter::InsertAfterAction.new(instance, 'include Bar')
11
+ Rewriter::InsertAfterAction.new(instance, 'include Bar').process
12
12
  }
13
13
 
14
14
  it 'gets begin_pos' do
@@ -9,7 +9,7 @@ module Synvert::Core
9
9
  source = "Synvert::Application.configure do\nend"
10
10
  block_node = Parser::CurrentRuby.parse(source)
11
11
  instance = double(current_node: block_node)
12
- Rewriter::PrependAction.new(instance, 'config.eager_load = true')
12
+ Rewriter::PrependAction.new(instance, 'config.eager_load = true').process
13
13
  }
14
14
 
15
15
  it 'gets begin_pos' do
@@ -30,7 +30,7 @@ module Synvert::Core
30
30
  source = "RSpec.configure do |config|\nend"
31
31
  block_node = Parser::CurrentRuby.parse(source)
32
32
  instance = double(current_node: block_node)
33
- Rewriter::PrependAction.new(instance, '{{arguments.first}}.include FactoryGirl::Syntax::Methods')
33
+ Rewriter::PrependAction.new(instance, '{{arguments.first}}.include FactoryGirl::Syntax::Methods').process
34
34
  }
35
35
 
36
36
  it 'gets begin_pos' do
@@ -51,7 +51,7 @@ module Synvert::Core
51
51
  source = "class User\n has_many :posts\nend"
52
52
  class_node = Parser::CurrentRuby.parse(source)
53
53
  instance = double(current_node: class_node)
54
- Rewriter::PrependAction.new(instance, 'include Deletable')
54
+ Rewriter::PrependAction.new(instance, 'include Deletable').process
55
55
  }
56
56
 
57
57
  it 'gets begin_pos' do
@@ -72,7 +72,7 @@ module Synvert::Core
72
72
  source = "class User < ActiveRecord::Base\n has_many :posts\nend"
73
73
  class_node = Parser::CurrentRuby.parse(source)
74
74
  instance = double(current_node: class_node)
75
- Rewriter::PrependAction.new(instance, 'include Deletable')
75
+ Rewriter::PrependAction.new(instance, 'include Deletable').process
76
76
  }
77
77
 
78
78
  it 'gets begin_pos' do
@@ -8,7 +8,7 @@ module Synvert::Core
8
8
  source = "user = User.new params[:user]\nuser.save\nrender\n"
9
9
  send_node = Parser::CurrentRuby.parse(source).children[1]
10
10
  instance = double(current_node: send_node, file_source: source)
11
- Rewriter::RemoveAction.new(instance)
11
+ Rewriter::RemoveAction.new(instance).process
12
12
  }
13
13
 
14
14
  it 'gets begin_pos' do
@@ -9,7 +9,7 @@ module Synvert::Core
9
9
  source = 'FactoryBot.create(:user)'
10
10
  node = Parser::CurrentRuby.parse(source)
11
11
  instance = double(current_node: node)
12
- Rewriter::ReplaceAction.new(instance, :receiver, :dot, :message, with: 'create')
12
+ Rewriter::ReplaceAction.new(instance, :receiver, :dot, :message, with: 'create').process
13
13
  }
14
14
 
15
15
  it 'gets begin_pos' do
@@ -9,7 +9,7 @@ module Synvert::Core
9
9
  source = 'post = FactoryGirl.create_list :post, 2'
10
10
  send_node = Parser::CurrentRuby.parse(source).children[1]
11
11
  instance = double(current_node: send_node)
12
- Rewriter::ReplaceWithAction.new(instance, 'create_list {{arguments}}')
12
+ Rewriter::ReplaceWithAction.new(instance, 'create_list {{arguments}}').process
13
13
  }
14
14
 
15
15
  it 'gets begin_pos' do
@@ -30,7 +30,7 @@ module Synvert::Core
30
30
  source = ' its(:size) { should == 1 }'
31
31
  send_node = Parser::CurrentRuby.parse(source)
32
32
  instance = double(current_node: send_node)
33
- Rewriter::ReplaceWithAction.new(instance, <<~EOS)
33
+ Rewriter::ReplaceWithAction.new(instance, <<~EOS).process
34
34
  describe '#size' do
35
35
  subject { super().size }
36
36
  it { {{body}} }
@@ -8,7 +8,7 @@ module Synvert::Core
8
8
  source = "class Bar\nend"
9
9
  node = Parser::CurrentRuby.parse(source)
10
10
  instance = double(current_node: node)
11
- Rewriter::WrapAction.new(instance, with: 'module Foo')
11
+ Rewriter::WrapAction.new(instance, with: 'module Foo').process
12
12
  }
13
13
 
14
14
  it 'gets begin_pos' do
@@ -90,58 +90,78 @@ module Synvert::Core
90
90
  end
91
91
 
92
92
  it 'parses append' do
93
- expect(Rewriter::AppendAction).to receive(:new).with(instance, 'include FactoryGirl::Syntax::Methods')
93
+ action = double
94
+ expect(Rewriter::AppendAction).to receive(:new).with(instance, 'include FactoryGirl::Syntax::Methods').and_return(action)
95
+ expect(action).to receive(:process)
94
96
  instance.append 'include FactoryGirl::Syntax::Methods'
95
97
  end
96
98
 
97
99
  it 'parses prepend' do
100
+ action = double
98
101
  expect(Rewriter::PrependAction).to receive(:new).with(
99
102
  instance,
100
103
  '{{arguments.first}}.include FactoryGirl::Syntax::Methods'
101
- )
104
+ ).and_return(action)
105
+ expect(action).to receive(:process)
102
106
  instance.prepend '{{arguments.first}}.include FactoryGirl::Syntax::Methods'
103
107
  end
104
108
 
105
- it 'parses insert' do
106
- expect(Rewriter::InsertAction).to receive(:new).with(instance, '.first', at: 'end')
109
+ it 'parses insert at end' do
110
+ action = double
111
+ expect(Rewriter::InsertAction).to receive(:new).with(instance, '.first', at: 'end').and_return(action)
112
+ expect(action).to receive(:process)
107
113
  instance.insert '.first'
108
114
  end
109
115
 
110
- it 'parses insert' do
111
- expect(Rewriter::InsertAction).to receive(:new).with(instance, 'URI.', at: 'beginning')
116
+ it 'parses insert at beginning' do
117
+ action = double
118
+ expect(Rewriter::InsertAction).to receive(:new).with(instance, 'URI.', at: 'beginning').and_return(action)
119
+ expect(action).to receive(:process)
112
120
  instance.insert 'URI.', at: 'beginning'
113
121
  end
114
122
 
115
123
  it 'parses insert_after' do
124
+ action = double
116
125
  expect(Rewriter::InsertAfterAction).to receive(:new).with(
117
126
  instance,
118
127
  '{{arguments.first}}.include FactoryGirl::Syntax::Methods'
119
- )
128
+ ).and_return(action)
129
+ expect(action).to receive(:process)
120
130
  instance.insert_after '{{arguments.first}}.include FactoryGirl::Syntax::Methods'
121
131
  end
122
132
 
123
133
  it 'parses replace_with' do
124
- expect(Rewriter::ReplaceWithAction).to receive(:new).with(instance, 'create {{arguments}}')
134
+ action = double
135
+ expect(Rewriter::ReplaceWithAction).to receive(:new).with(instance, 'create {{arguments}}').and_return(action)
136
+ expect(action).to receive(:process)
125
137
  instance.replace_with 'create {{arguments}}'
126
138
  end
127
139
 
128
140
  it 'parses replace with' do
129
- expect(Rewriter::ReplaceAction).to receive(:new).with(instance, :message, with: 'test')
141
+ action = double
142
+ expect(Rewriter::ReplaceAction).to receive(:new).with(instance, :message, with: 'test').and_return(action)
143
+ expect(action).to receive(:process)
130
144
  instance.replace :message, with: 'test'
131
145
  end
132
146
 
133
147
  it 'parses remove' do
134
- expect(Rewriter::RemoveAction).to receive(:new).with(instance)
148
+ action = double
149
+ expect(Rewriter::RemoveAction).to receive(:new).with(instance).and_return(action)
150
+ expect(action).to receive(:process)
135
151
  instance.remove
136
152
  end
137
153
 
138
154
  it 'parses remove' do
139
- expect(Rewriter::DeleteAction).to receive(:new).with(instance, :dot, :message)
155
+ action = double
156
+ expect(Rewriter::DeleteAction).to receive(:new).with(instance, :dot, :message).and_return(action)
157
+ expect(action).to receive(:process)
140
158
  instance.delete :dot, :message
141
159
  end
142
160
 
143
161
  it 'parses wrap with' do
144
- expect(Rewriter::WrapAction).to receive(:new).with(instance, with: 'module Foo', indent: nil)
162
+ action = double
163
+ expect(Rewriter::WrapAction).to receive(:new).with(instance, with: 'module Foo', indent: nil).and_return(action)
164
+ expect(action).to receive(:process)
145
165
  instance.wrap with: 'module Foo'
146
166
  end
147
167
 
@@ -4,6 +4,11 @@ require 'spec_helper'
4
4
 
5
5
  module Synvert::Core
6
6
  describe Rewriter::RubyVersion do
7
+ before do
8
+ expect(File).to receive(:exist?).with('./.ruby-version').and_return(true)
9
+ expect(File).to receive(:read).with('./.ruby-version').and_return('3.0.0')
10
+ end
11
+
7
12
  it 'returns true if ruby version is greater than 1.9' do
8
13
  ruby_version = Rewriter::RubyVersion.new('1.9')
9
14
  expect(ruby_version).to be_match
@@ -39,7 +39,8 @@ module Synvert::Core
39
39
 
40
40
  describe 'parses within_file' do
41
41
  it 'does nothing if if_ruby does not match' do
42
- stub_const('RUBY_VERSION', '2.0.0')
42
+ expect(File).to receive(:exist?).with('./.ruby-version').and_return(true)
43
+ expect(File).to receive(:read).with('./.ruby-version').and_return('2.0.0')
43
44
  expect_any_instance_of(Rewriter::Instance).not_to receive(:process)
44
45
  rewriter =
45
46
  Rewriter.new 'group', 'name' do
@@ -51,7 +52,8 @@ module Synvert::Core
51
52
  end
52
53
 
53
54
  it 'delegates process to instances if if_ruby matches' do
54
- stub_const('RUBY_VERSION', '2.0.0')
55
+ expect(File).to receive(:exist?).with('./.ruby-version').and_return(true)
56
+ expect(File).to receive(:read).with('./.ruby-version').and_return('2.0.0')
55
57
  expect_any_instance_of(Rewriter::Instance).to receive(:process)
56
58
  rewriter =
57
59
  Rewriter.new 'group', 'name' do
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.54.3
4
+ version: 0.57.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-09-09 00:00:00.000000000 Z
11
+ date: 2021-10-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport