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.
- checksums.yaml +4 -4
 - data/.github/workflows/main.yml +1 -1
 - data/.gitignore +4 -0
 - data/CHANGELOG.md +9 -1
 - data/Guardfile +11 -2
 - data/README.md +74 -34
 - data/Rakefile +15 -1
 - data/lib/synvert/core/array_ext.rb +41 -0
 - data/lib/synvert/core/configuration.rb +12 -0
 - data/lib/synvert/core/engine/erb.rb +9 -8
 - data/lib/synvert/core/exceptions.rb +0 -4
 - data/lib/synvert/core/node_ext.rb +232 -128
 - data/lib/synvert/core/node_query/compiler/array.rb +34 -0
 - data/lib/synvert/core/node_query/compiler/attribute.rb +51 -0
 - data/lib/synvert/core/node_query/compiler/attribute_list.rb +24 -0
 - data/lib/synvert/core/node_query/compiler/boolean.rb +23 -0
 - data/lib/synvert/core/node_query/compiler/comparable.rb +79 -0
 - data/lib/synvert/core/node_query/compiler/dynamic_attribute.rb +51 -0
 - data/lib/synvert/core/node_query/compiler/expression.rb +88 -0
 - data/lib/synvert/core/node_query/compiler/float.rb +23 -0
 - data/lib/synvert/core/node_query/compiler/identifier.rb +41 -0
 - data/lib/synvert/core/node_query/compiler/integer.rb +23 -0
 - data/lib/synvert/core/node_query/compiler/invalid_operator_error.rb +7 -0
 - data/lib/synvert/core/node_query/compiler/nil.rb +23 -0
 - data/lib/synvert/core/node_query/compiler/parse_error.rb +7 -0
 - data/lib/synvert/core/node_query/compiler/regexp.rb +37 -0
 - data/lib/synvert/core/node_query/compiler/selector.rb +51 -0
 - data/lib/synvert/core/node_query/compiler/string.rb +34 -0
 - data/lib/synvert/core/node_query/compiler/symbol.rb +23 -0
 - data/lib/synvert/core/node_query/compiler.rb +24 -0
 - data/lib/synvert/core/node_query/lexer.rex +96 -0
 - data/lib/synvert/core/node_query/lexer.rex.rb +293 -0
 - data/lib/synvert/core/node_query/parser.racc.rb +518 -0
 - data/lib/synvert/core/node_query/parser.y +84 -0
 - data/lib/synvert/core/node_query.rb +36 -0
 - data/lib/synvert/core/rewriter/action/append_action.rb +4 -3
 - data/lib/synvert/core/rewriter/action/delete_action.rb +17 -8
 - data/lib/synvert/core/rewriter/action/insert_action.rb +16 -7
 - data/lib/synvert/core/rewriter/action/insert_after_action.rb +3 -2
 - data/lib/synvert/core/rewriter/action/prepend_action.rb +3 -2
 - data/lib/synvert/core/rewriter/action/remove_action.rb +16 -10
 - data/lib/synvert/core/rewriter/action/replace_action.rb +15 -5
 - data/lib/synvert/core/rewriter/action/replace_erb_stmt_with_expr_action.rb +18 -11
 - data/lib/synvert/core/rewriter/action/replace_with_action.rb +6 -5
 - data/lib/synvert/core/rewriter/action/wrap_action.rb +16 -7
 - data/lib/synvert/core/rewriter/action.rb +22 -10
 - data/lib/synvert/core/rewriter/any_value.rb +1 -0
 - data/lib/synvert/core/rewriter/condition/if_exist_condition.rb +4 -0
 - data/lib/synvert/core/rewriter/condition/if_only_exist_condition.rb +4 -0
 - data/lib/synvert/core/rewriter/condition/unless_exist_condition.rb +4 -0
 - data/lib/synvert/core/rewriter/condition.rb +11 -3
 - data/lib/synvert/core/rewriter/gem_spec.rb +6 -3
 - data/lib/synvert/core/rewriter/helper.rb +7 -4
 - data/lib/synvert/core/rewriter/instance.rb +217 -104
 - data/lib/synvert/core/rewriter/ruby_version.rb +4 -4
 - data/lib/synvert/core/rewriter/scope/goto_scope.rb +5 -6
 - data/lib/synvert/core/rewriter/scope/query_scope.rb +36 -0
 - data/lib/synvert/core/rewriter/scope/within_scope.rb +10 -5
 - data/lib/synvert/core/rewriter/scope.rb +8 -0
 - data/lib/synvert/core/rewriter/warning.rb +1 -1
 - data/lib/synvert/core/rewriter.rb +91 -43
 - data/lib/synvert/core/version.rb +1 -1
 - data/lib/synvert/core.rb +22 -6
 - data/spec/synvert/core/engine/erb_spec.rb +2 -2
 - data/spec/synvert/core/node_ext_spec.rb +36 -12
 - data/spec/synvert/core/node_query/lexer_spec.rb +512 -0
 - data/spec/synvert/core/node_query/parser_spec.rb +270 -0
 - data/spec/synvert/core/rewriter/action_spec.rb +0 -4
 - data/spec/synvert/core/rewriter/condition/if_only_exist_condition_spec.rb +1 -6
 - data/spec/synvert/core/rewriter/gem_spec_spec.rb +1 -1
 - data/spec/synvert/core/rewriter/helper_spec.rb +4 -1
 - data/spec/synvert/core/rewriter/instance_spec.rb +31 -20
 - data/spec/synvert/core/rewriter/scope/query_scope_spec.rb +74 -0
 - data/spec/synvert/core/rewriter/scope/within_scope_spec.rb +12 -9
 - data/spec/synvert/core/rewriter_spec.rb +4 -2
 - data/synvert-core-ruby.gemspec +7 -2
 - 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 
     | 
    
         
            -
                 
     | 
| 
      
 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 
     | 
    
         
            -
                #  
     | 
| 
       11 
     | 
    
         
            -
                 
     | 
| 
       12 
     | 
    
         
            -
             
     | 
| 
      
 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 
     | 
    
         
            -
                #  
     | 
| 
       27 
     | 
    
         
            -
                 
     | 
| 
       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 
     | 
    
         
            -
                 
     | 
| 
       8 
     | 
    
         
            -
             
     | 
| 
      
 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 
     | 
    
         
            -
             
     | 
| 
       25 
     | 
    
         
            -
             
     | 
| 
      
 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,  
     | 
| 
      
 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  
     | 
| 
      
 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 } 
     | 
| 
      
 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
         
     | 
| 
         @@ -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  
     | 
| 
      
 6 
     | 
    
         
            +
                # Initialize a Condition.
         
     | 
| 
       7 
7 
     | 
    
         
             
                #
         
     | 
| 
       8 
8 
     | 
    
         
             
                # @param instance [Synvert::Core::Rewriter::Instance]
         
     | 
| 
       9 
9 
     | 
    
         
             
                # @param rules [Hash]
         
     | 
| 
       10 
     | 
    
         
            -
                # @ 
     | 
| 
       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  
     | 
| 
      
 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  
     | 
| 
      
 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) } 
     | 
| 
      
 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) } 
     | 
| 
      
 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
         
     |