synvert-core 0.63.1 → 1.0.1

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 (77) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/main.yml +1 -1
  3. data/.gitignore +4 -0
  4. data/CHANGELOG.md +9 -1
  5. data/Guardfile +11 -2
  6. data/README.md +74 -34
  7. data/Rakefile +15 -1
  8. data/lib/synvert/core/array_ext.rb +41 -0
  9. data/lib/synvert/core/configuration.rb +12 -0
  10. data/lib/synvert/core/engine/erb.rb +9 -8
  11. data/lib/synvert/core/exceptions.rb +0 -4
  12. data/lib/synvert/core/node_ext.rb +232 -128
  13. data/lib/synvert/core/node_query/compiler/array.rb +34 -0
  14. data/lib/synvert/core/node_query/compiler/attribute.rb +51 -0
  15. data/lib/synvert/core/node_query/compiler/attribute_list.rb +24 -0
  16. data/lib/synvert/core/node_query/compiler/boolean.rb +23 -0
  17. data/lib/synvert/core/node_query/compiler/comparable.rb +79 -0
  18. data/lib/synvert/core/node_query/compiler/dynamic_attribute.rb +51 -0
  19. data/lib/synvert/core/node_query/compiler/expression.rb +88 -0
  20. data/lib/synvert/core/node_query/compiler/float.rb +23 -0
  21. data/lib/synvert/core/node_query/compiler/identifier.rb +41 -0
  22. data/lib/synvert/core/node_query/compiler/integer.rb +23 -0
  23. data/lib/synvert/core/node_query/compiler/invalid_operator_error.rb +7 -0
  24. data/lib/synvert/core/node_query/compiler/nil.rb +23 -0
  25. data/lib/synvert/core/node_query/compiler/parse_error.rb +7 -0
  26. data/lib/synvert/core/node_query/compiler/regexp.rb +37 -0
  27. data/lib/synvert/core/node_query/compiler/selector.rb +51 -0
  28. data/lib/synvert/core/node_query/compiler/string.rb +34 -0
  29. data/lib/synvert/core/node_query/compiler/symbol.rb +23 -0
  30. data/lib/synvert/core/node_query/compiler.rb +24 -0
  31. data/lib/synvert/core/node_query/lexer.rex +96 -0
  32. data/lib/synvert/core/node_query/lexer.rex.rb +293 -0
  33. data/lib/synvert/core/node_query/parser.racc.rb +518 -0
  34. data/lib/synvert/core/node_query/parser.y +84 -0
  35. data/lib/synvert/core/node_query.rb +36 -0
  36. data/lib/synvert/core/rewriter/action/append_action.rb +4 -3
  37. data/lib/synvert/core/rewriter/action/delete_action.rb +17 -8
  38. data/lib/synvert/core/rewriter/action/insert_action.rb +16 -7
  39. data/lib/synvert/core/rewriter/action/insert_after_action.rb +3 -2
  40. data/lib/synvert/core/rewriter/action/prepend_action.rb +3 -2
  41. data/lib/synvert/core/rewriter/action/remove_action.rb +16 -10
  42. data/lib/synvert/core/rewriter/action/replace_action.rb +15 -5
  43. data/lib/synvert/core/rewriter/action/replace_erb_stmt_with_expr_action.rb +18 -11
  44. data/lib/synvert/core/rewriter/action/replace_with_action.rb +6 -5
  45. data/lib/synvert/core/rewriter/action/wrap_action.rb +16 -7
  46. data/lib/synvert/core/rewriter/action.rb +22 -10
  47. data/lib/synvert/core/rewriter/any_value.rb +1 -0
  48. data/lib/synvert/core/rewriter/condition/if_exist_condition.rb +4 -0
  49. data/lib/synvert/core/rewriter/condition/if_only_exist_condition.rb +4 -0
  50. data/lib/synvert/core/rewriter/condition/unless_exist_condition.rb +4 -0
  51. data/lib/synvert/core/rewriter/condition.rb +11 -3
  52. data/lib/synvert/core/rewriter/gem_spec.rb +6 -3
  53. data/lib/synvert/core/rewriter/helper.rb +7 -4
  54. data/lib/synvert/core/rewriter/instance.rb +217 -104
  55. data/lib/synvert/core/rewriter/ruby_version.rb +4 -4
  56. data/lib/synvert/core/rewriter/scope/goto_scope.rb +5 -6
  57. data/lib/synvert/core/rewriter/scope/query_scope.rb +36 -0
  58. data/lib/synvert/core/rewriter/scope/within_scope.rb +10 -5
  59. data/lib/synvert/core/rewriter/scope.rb +8 -0
  60. data/lib/synvert/core/rewriter/warning.rb +1 -1
  61. data/lib/synvert/core/rewriter.rb +91 -43
  62. data/lib/synvert/core/version.rb +1 -1
  63. data/lib/synvert/core.rb +22 -6
  64. data/spec/synvert/core/engine/erb_spec.rb +2 -2
  65. data/spec/synvert/core/node_ext_spec.rb +36 -12
  66. data/spec/synvert/core/node_query/lexer_spec.rb +512 -0
  67. data/spec/synvert/core/node_query/parser_spec.rb +270 -0
  68. data/spec/synvert/core/rewriter/action_spec.rb +0 -4
  69. data/spec/synvert/core/rewriter/condition/if_only_exist_condition_spec.rb +1 -6
  70. data/spec/synvert/core/rewriter/gem_spec_spec.rb +1 -1
  71. data/spec/synvert/core/rewriter/helper_spec.rb +4 -1
  72. data/spec/synvert/core/rewriter/instance_spec.rb +31 -20
  73. data/spec/synvert/core/rewriter/scope/query_scope_spec.rb +74 -0
  74. data/spec/synvert/core/rewriter/scope/within_scope_spec.rb +12 -9
  75. data/spec/synvert/core/rewriter_spec.rb +4 -2
  76. data/synvert-core-ruby.gemspec +7 -2
  77. metadata +91 -4
@@ -3,23 +3,32 @@
3
3
  module Synvert::Core
4
4
  # InsertAction to add code to the node.
5
5
  class Rewriter::InsertAction < Rewriter::Action
6
- def initialize(instance, code, at:, to: nil)
6
+ # Initialize an InsertAction.
7
+ #
8
+ # @param instance [Synvert::Core::Rewriter::Instance]
9
+ # @param code [String] to be inserted
10
+ # @param at [String] position to insert, beginning or end
11
+ # @param to [<Symbol|String>] name of child node
12
+ def initialize(instance, code, at: 'end', to: nil)
7
13
  super(instance, code)
8
14
  @at = at
9
15
  @to = to
10
16
  end
11
17
 
12
- def calculate_position
13
- node_range = @to ? @node.child_node_range(@to) : @node.loc.expression
14
- @begin_pos = @at == 'end' ? node_range.end_pos : node_range.begin_pos
15
- @end_pos = @begin_pos
16
- end
17
-
18
18
  # The rewritten source code.
19
19
  #
20
20
  # @return [String] rewritten code.
21
21
  def rewritten_code
22
22
  rewritten_source
23
23
  end
24
+
25
+ private
26
+
27
+ # Calculate the begin and end positions.
28
+ def calculate_position
29
+ node_range = @to ? @node.child_node_range(@to) : @node.loc.expression
30
+ @begin_pos = @at == 'end' ? node_range.end_pos : node_range.begin_pos
31
+ @end_pos = @begin_pos
32
+ end
24
33
  end
25
34
  end
@@ -3,13 +3,14 @@
3
3
  module Synvert::Core
4
4
  # InsertAfterAction to insert code next to the node.
5
5
  class Rewriter::InsertAfterAction < Rewriter::Action
6
+ private
7
+
8
+ # Calculate the begin and end positions.
6
9
  def calculate_position
7
10
  @begin_pos = @node.loc.expression.end_pos
8
11
  @end_pos = @begin_pos
9
12
  end
10
13
 
11
- private
12
-
13
14
  # Indent of the node.
14
15
  #
15
16
  # @param node [Parser::AST::Node]
@@ -3,8 +3,11 @@
3
3
  module Synvert::Core
4
4
  # PrependAction to prepend code to the top of node body.
5
5
  class Rewriter::PrependAction < Rewriter::Action
6
+ private
7
+
6
8
  DO_LENGTH = ' do'.length
7
9
 
10
+ # Calculate the begin and end positions.
8
11
  def calculate_position
9
12
  @begin_pos =
10
13
  case @node.type
@@ -26,8 +29,6 @@ module Synvert::Core
26
29
  @end_pos = @begin_pos
27
30
  end
28
31
 
29
- private
30
-
31
32
  # Indent of the node.
32
33
  #
33
34
  # @param node [Parser::AST::Node]
@@ -3,13 +3,21 @@
3
3
  module Synvert::Core
4
4
  # RemoveAction to remove current node.
5
5
  class Rewriter::RemoveAction < Rewriter::Action
6
+ # Initialize a RemoveAction.
7
+ #
8
+ # @param instance [Synvert::Core::Rewriter::RemoveAction]
6
9
  def initialize(instance)
7
10
  super(instance, nil)
8
11
  end
9
12
 
10
- # Begin position of code to replace.
11
- #
12
- # @return [Integer] begin position.
13
+ # The rewritten code, always empty string.
14
+ def rewritten_code
15
+ ''
16
+ end
17
+
18
+ private
19
+
20
+ # Calculate the begin the end positions.
13
21
  def calculate_position
14
22
  if take_whole_line?
15
23
  @begin_pos = start_index
@@ -23,22 +31,20 @@ module Synvert::Core
23
31
  end
24
32
  end
25
33
 
26
- # The rewritten code, always empty string.
27
- def rewritten_code
28
- ''
29
- end
30
-
31
- private
32
-
34
+ # Check if the source code of current node takes the whole line.
35
+ #
36
+ # @return [Boolean]
33
37
  def take_whole_line?
34
38
  @node.to_source == file_source[start_index...end_index].strip
35
39
  end
36
40
 
41
+ # Get the start position of the line
37
42
  def start_index
38
43
  index = file_source[0..@node.loc.expression.begin_pos].rindex("\n")
39
44
  index ? index + "\n".length : @node.loc.expression.begin_pos
40
45
  end
41
46
 
47
+ # Get the end position of the line
42
48
  def end_index
43
49
  index = file_source[@node.loc.expression.end_pos..-1].index("\n")
44
50
  index ? @node.loc.expression.end_pos + index + "\n".length : @node.loc.expression.end_pos
@@ -3,21 +3,31 @@
3
3
  module Synvert::Core
4
4
  # ReplaceAction to replace child node with code.
5
5
  class Rewriter::ReplaceAction < Rewriter::Action
6
+ # Initailize a ReplaceAction.
7
+ #
8
+ # @param instance [Synvert::Core::Rewriter::Instance]
9
+ # @param selectors [Array<Symbol|String>] used to select child nodes
10
+ # @param with [String] the new code
6
11
  def initialize(instance, *selectors, with:)
7
12
  super(instance, with)
8
13
  @selectors = selectors
9
14
  end
10
15
 
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
14
- end
15
-
16
16
  # The rewritten source code.
17
17
  #
18
18
  # @return [String] rewritten code.
19
19
  def rewritten_code
20
20
  rewritten_source
21
21
  end
22
+
23
+ private
24
+
25
+ # Calculate the begin the end positions.
26
+ def calculate_position
27
+ @begin_pos = @selectors.map { |selector| @node.child_node_range(selector).begin_pos }
28
+ .min
29
+ @end_pos = @selectors.map { |selector| @node.child_node_range(selector).end_pos }
30
+ .max
31
+ end
22
32
  end
23
33
  end
@@ -2,12 +2,28 @@
2
2
 
3
3
  module Synvert::Core
4
4
  # ReplaceErbStmtWithExprAction to replace erb stmt code to expr,
5
+ # @example
5
6
  # e.g. <% form_for ... %> => <%= form_for ... %>.
6
7
  class Rewriter::ReplaceErbStmtWithExprAction < Rewriter::Action
7
- def initialize(instance, code = nil)
8
- super
8
+ # Initialize a ReplaceErbStmtWithExprAction.
9
+ #
10
+ # @param instance [Synvert::Core::Rewriter::Instance]
11
+ def initialize(instance)
12
+ super(instance, nil)
13
+ end
14
+
15
+ # The rewritten erb expr code.
16
+ #
17
+ # @return [String] rewritten code.
18
+ def rewritten_code
19
+ @node.loc.expression.source_buffer.source[begin_pos...end_pos]
20
+ .sub(Engine::ERUBY_STMT_SPLITTER, '@output_buffer.append= ')
21
+ .sub(Engine::ERUBY_STMT_SPLITTER, Engine::ERUBY_EXPR_SPLITTER)
9
22
  end
10
23
 
24
+ private
25
+
26
+ # Calculate the begin the end positions.
11
27
  def calculate_position
12
28
  node_begin_pos = @node.loc.expression.begin_pos
13
29
  while @node.loc.expression.source_buffer.source[node_begin_pos -= 1] == ' '
@@ -20,14 +36,5 @@ module Synvert::Core
20
36
  end
21
37
  @end_pos = node_begin_pos
22
38
  end
23
-
24
- # The rewritten erb expr code.
25
- #
26
- # @return [String] rewritten code.
27
- def rewritten_code
28
- @node.loc.expression.source_buffer.source[begin_pos...end_pos]
29
- .sub(Engine::ERUBY_STMT_SPLITTER, '@output_buffer.append= ')
30
- .sub(Engine::ERUBY_STMT_SPLITTER, Engine::ERUBY_EXPR_SPLITTER)
31
- end
32
39
  end
33
40
  end
@@ -3,11 +3,6 @@
3
3
  module Synvert::Core
4
4
  # ReplaceWithAction to replace code.
5
5
  class Rewriter::ReplaceWithAction < Rewriter::Action
6
- def calculate_position
7
- @begin_pos = @node.loc.expression.begin_pos
8
- @end_pos = @node.loc.expression.end_pos
9
- end
10
-
11
6
  # The rewritten source code with proper indent.
12
7
  #
13
8
  # @return [String] rewritten code.
@@ -25,6 +20,12 @@ module Synvert::Core
25
20
 
26
21
  private
27
22
 
23
+ # Calculate the begin the end positions.
24
+ def calculate_position
25
+ @begin_pos = @node.loc.expression.begin_pos
26
+ @end_pos = @node.loc.expression.end_pos
27
+ end
28
+
28
29
  # Indent of the node
29
30
  #
30
31
  # @return [String] n times whitesphace
@@ -6,23 +6,32 @@ module Synvert::Core
6
6
  # Note: if WrapAction is conflicted with another action (begin_pos and end_pos are overlapped),
7
7
  # we have to put those 2 actions into 2 within_file scopes.
8
8
  class Rewriter::WrapAction < Rewriter::Action
9
+ # Initialize a WrapAction.
10
+ #
11
+ # @param instance [Synvert::Core::Rewriter::WrapAction]
12
+ # @param with [String] new code to wrap
13
+ # @param indent [Integer, nil] number of whitespaces
9
14
  def initialize(instance, with:, indent: nil)
10
15
  super(instance, with)
11
16
  @indent = indent || @node.column
12
17
  end
13
18
 
14
- def calculate_position
15
- @begin_pos = @node.loc.expression.begin_pos
16
- @end_pos = @node.loc.expression.end_pos
17
- end
18
-
19
19
  # The rewritten source code.
20
20
  #
21
21
  # @return [String] rewritten code.
22
22
  def rewritten_code
23
23
  "#{@code}\n#{' ' * @indent}" +
24
- @node.to_source.split("\n").map { |line| " #{line}" }.join("\n") +
25
- "\n#{' ' * @indent}end"
24
+ @node.to_source.split("\n").map { |line| " #{line}" }
25
+ .join("\n") +
26
+ "\n#{' ' * @indent}end"
27
+ end
28
+
29
+ private
30
+
31
+ # Calculate the begin the end positions.
32
+ def calculate_position
33
+ @begin_pos = @node.loc.expression.begin_pos
34
+ @end_pos = @node.loc.expression.end_pos
26
35
  end
27
36
  end
28
37
  end
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Synvert::Core
4
- # Action defines rewriter action, add, replace or remove code.
4
+ # Action defines rewriter action, insert, replace or delete code.
5
5
  class Rewriter::Action
6
6
  DEFAULT_INDENT = 2
7
7
 
@@ -14,31 +14,28 @@ module Synvert::Core
14
14
  # Initialize an action.
15
15
  #
16
16
  # @param instance [Synvert::Core::Rewriter::Instance]
17
- # @param code [String] new code to add, replace or remove.
17
+ # @param code [String] new code to insert, replace or delete.
18
18
  def initialize(instance, code)
19
19
  @instance = instance
20
20
  @code = code
21
21
  @node = @instance.current_node
22
22
  end
23
23
 
24
+ # Calculate begin and end positions, and return self.
25
+ #
26
+ # @return [Synvert::Core::Rewriter::Action] self
24
27
  def process
25
28
  calculate_position
26
29
  self
27
30
  end
28
31
 
29
- # Line number of current node.
30
- #
31
- # @return [Integer] line number.
32
- def line
33
- @node.loc.expression.line
34
- end
35
-
36
32
  # The rewritten source code with proper indent.
37
33
  #
38
34
  # @return [String] rewritten code.
39
35
  def rewritten_code
40
36
  if rewritten_source.split("\n").length > 1
41
- "\n\n" + rewritten_source.split("\n").map { |line| indent(@node) + line }.join("\n")
37
+ "\n\n" + rewritten_source.split("\n").map { |line| indent(@node) + line }
38
+ .join("\n")
42
39
  else
43
40
  "\n" + indent(@node) + rewritten_source
44
41
  end
@@ -46,6 +43,13 @@ module Synvert::Core
46
43
 
47
44
  protected
48
45
 
46
+ # Calculate the begin the end positions.
47
+ #
48
+ # @abstract
49
+ def calculate_position
50
+ raise NotImplementedError, 'must be implemented by subclasses'
51
+ end
52
+
49
53
  # The rewritten source code.
50
54
  #
51
55
  # @return [String] rewritten source code.
@@ -53,12 +57,14 @@ module Synvert::Core
53
57
  @rewritten_source ||= @node.rewritten_source(@code)
54
58
  end
55
59
 
60
+ # Squeeze spaces from source code.
56
61
  def squeeze_spaces
57
62
  if file_source[@begin_pos - 1] == ' ' && file_source[@end_pos] == ' '
58
63
  @begin_pos -= 1
59
64
  end
60
65
  end
61
66
 
67
+ # Squeeze empty lines from source code.
62
68
  def squeeze_lines
63
69
  lines = file_source.split("\n")
64
70
  begin_line = @node.loc.expression.first_line
@@ -71,6 +77,9 @@ module Synvert::Core
71
77
  end
72
78
  end
73
79
 
80
+ # Remove unused comma.
81
+ # e.g. `foobar(foo, bar)`, if we remove `foo`, the comma should also be removed,
82
+ # the code should be changed to `foobar(bar)`.
74
83
  def remove_comma
75
84
  if ',' == file_source[@begin_pos - 1]
76
85
  @begin_pos -= 1
@@ -83,6 +92,9 @@ module Synvert::Core
83
92
  end
84
93
  end
85
94
 
95
+ # Return file source.
96
+ #
97
+ # @return [String]
86
98
  def file_source
87
99
  @file_source ||= @instance.file_source
88
100
  end
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Synvert::Core
4
+ # A new type to match any value.
4
5
  class Rewriter::AnyValue
5
6
  end
6
7
  end
@@ -3,7 +3,11 @@
3
3
  module Synvert::Core
4
4
  # IfExistCondition checks if matching node exists in the node children.
5
5
  class Rewriter::IfExistCondition < Rewriter::Condition
6
+ private
7
+
6
8
  # check if any child node matches the rules.
9
+ #
10
+ # @return [Boolean]
7
11
  def match?
8
12
  match = false
9
13
  @instance.current_node.recursive_children do |child_node|
@@ -3,7 +3,11 @@
3
3
  module Synvert::Core
4
4
  # IfOnlyExistCondition checks if node has only one child node and the child node matches rules.
5
5
  class Rewriter::IfOnlyExistCondition < Rewriter::Condition
6
+ private
7
+
6
8
  # check if only have one child node and the child node matches rules.
9
+ #
10
+ # @return [Boolean]
7
11
  def match?
8
12
  @instance.current_node.body.size == 1 && @instance.current_node.body.first.match?(@rules)
9
13
  end
@@ -3,7 +3,11 @@
3
3
  module Synvert::Core
4
4
  # UnlessExistCondition checks if matching node doesn't exist in the node children.
5
5
  class Rewriter::UnlessExistCondition < Rewriter::Condition
6
+ private
7
+
6
8
  # check if none of child node matches the rules.
9
+ #
10
+ # return [Boolean]
7
11
  def match?
8
12
  match = false
9
13
  @instance.current_node.recursive_children do |child_node|
@@ -3,12 +3,11 @@
3
3
  module Synvert::Core
4
4
  # Condition checks if rules matches.
5
5
  class Rewriter::Condition
6
- # Initialize a condition.
6
+ # Initialize a Condition.
7
7
  #
8
8
  # @param instance [Synvert::Core::Rewriter::Instance]
9
9
  # @param rules [Hash]
10
- # @param block [Block]
11
- # @return [Synvert::Core::Rewriter::Condition]
10
+ # @yield run when condition matches
12
11
  def initialize(instance, rules, &block)
13
12
  @instance = instance
14
13
  @rules = rules
@@ -19,5 +18,14 @@ module Synvert::Core
19
18
  def process
20
19
  @instance.instance_eval(&@block) if match?
21
20
  end
21
+
22
+ protected
23
+
24
+ # Check if condition matches
25
+ #
26
+ # @abstract
27
+ def match?
28
+ raise NotImplementedError, 'must be implemented by subclasses'
29
+ end
22
30
  end
23
31
  end
@@ -3,12 +3,16 @@
3
3
  module Synvert::Core
4
4
  # GemSpec checks and compares gem version.
5
5
  class Rewriter::GemSpec
6
+ # @!attribute [r] name
7
+ # @return [String] the name of gem_spec
8
+ # @!attribute [r] version
9
+ # @return [String] the version of gem_spec
6
10
  attr_reader :name, :version
7
11
 
8
- # Initialize a gem_spec.
12
+ # Initialize a GemSpec.
9
13
  #
10
14
  # @param name [String] gem name
11
- # @param version [String] gem version, e.g. '~> 2.0.0',
15
+ # @param version [String] gem version, e.g. '~> 2.0.0'
12
16
  def initialize(name, version)
13
17
  @name = name
14
18
  @version = version
@@ -17,7 +21,6 @@ module Synvert::Core
17
21
  # Check if the specified gem version in Gemfile.lock matches gem_spec comparator.
18
22
  #
19
23
  # @return [Boolean] true if matches, otherwise false.
20
- # @raise [Synvert::Core::GemfileLockNotFound] raise if Gemfile.lock does not exist.
21
24
  def match?
22
25
  gemfile_lock_path = File.expand_path(File.join(Configuration.path, 'Gemfile.lock'))
23
26
 
@@ -24,7 +24,7 @@ module Synvert::Core
24
24
 
25
25
  # Add arguments with parenthesis if necessary.
26
26
  #
27
- # @return [String] return `({{arguments}})` if node.arguments present, otherwise return nothing.
27
+ # @return [String] return (!{{arguments}}) if node.arguments present, otherwise return nothing.
28
28
  #
29
29
  # @example
30
30
  #
@@ -65,7 +65,9 @@ module Synvert::Core
65
65
  #
66
66
  # strip_brackets("(1..100)") #=> "1..100"
67
67
  def strip_brackets(code)
68
- code.sub(/^\((.*)\)$/) { Regexp.last_match(1) }.sub(/^\[(.*)\]$/) { Regexp.last_match(1) }.sub(/^{(.*)}$/) {
68
+ code.sub(/^\((.*)\)$/) { Regexp.last_match(1) }
69
+ .sub(/^\[(.*)\]$/) { Regexp.last_match(1) }
70
+ .sub(/^{(.*)}$/) {
69
71
  Regexp.last_match(1).strip
70
72
  }
71
73
  end
@@ -73,7 +75,7 @@ module Synvert::Core
73
75
  # Reject some keys from hash node.
74
76
  #
75
77
  # @param hash_node [Parser::AST::Node]
76
- # @param keys [Array] keys should be rejected from the hash.
78
+ # @param keys [Array<String, Symbol>] keys should be rejected from the hash.
77
79
  # @return [String] source of of the hash node after rejecting some keys.
78
80
  #
79
81
  # @example
@@ -81,7 +83,8 @@ module Synvert::Core
81
83
  # hash_node = Parser::CurrentRuby.parse("{ key1: 'value1', key2: 'value2' }")
82
84
  # reject_keys_from_hash(hash_node, :key1) => "key2: 'value2'"
83
85
  def reject_keys_from_hash(hash_node, *keys)
84
- hash_node.children.reject { |pair_node| keys.include?(pair_node.key.to_value) }.map(&:to_source).join(', ')
86
+ hash_node.children.reject { |pair_node| keys.include?(pair_node.key.to_value) }
87
+ .map(&:to_source).join(', ')
85
88
  end
86
89
  end
87
90
  end