synvert-core 0.63.1 → 1.0.1

Sign up to get free protection for your applications and to get access to all the features.
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