node_mutation 1.21.6 → 1.22.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/CHANGELOG.md +10 -0
 - data/Gemfile.lock +1 -1
 - data/README.md +1 -5
 - data/lib/node_mutation/action/append_action.rb +9 -4
 - data/lib/node_mutation/action/delete_action.rb +6 -5
 - data/lib/node_mutation/action/group_action.rb +1 -0
 - data/lib/node_mutation/action/indent_action.rb +6 -5
 - data/lib/node_mutation/action/insert_action.rb +7 -6
 - data/lib/node_mutation/action/noop_action.rb +8 -5
 - data/lib/node_mutation/action/prepend_action.rb +10 -5
 - data/lib/node_mutation/action/remove_action.rb +9 -9
 - data/lib/node_mutation/action/replace_action.rb +5 -4
 - data/lib/node_mutation/action/replace_with_action.rb +10 -5
 - data/lib/node_mutation/action.rb +5 -3
 - data/lib/node_mutation/adapter/parser.rb +3 -1
 - data/lib/node_mutation/adapter/syntax_tree.rb +1 -1
 - data/lib/node_mutation/version.rb +1 -1
 - data/lib/node_mutation.rb +26 -22
 - data/sig/node_mutation.rbs +2 -4
 - metadata +2 -2
 
    
        checksums.yaml
    CHANGED
    
    | 
         @@ -1,7 +1,7 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            ---
         
     | 
| 
       2 
2 
     | 
    
         
             
            SHA256:
         
     | 
| 
       3 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       4 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 3 
     | 
    
         
            +
              metadata.gz: 1039c5eaf805a6938a0470e3dbafd304b9b7c2a84c3f321fc040f030e0314dea
         
     | 
| 
      
 4 
     | 
    
         
            +
              data.tar.gz: fd7895425980b04494de197902a84bef9dcdb6153255654ccc2a5c28b31badb7
         
     | 
| 
       5 
5 
     | 
    
         
             
            SHA512:
         
     | 
| 
       6 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       7 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 6 
     | 
    
         
            +
              metadata.gz: 0ebb7d1aaf7ffd54e8f99bc1064caaa23c3f76e131260acf58dc43eb23de49a3d3d09482e19754b43ab19c699b313370fdd17ae5dfd02c1e3964470df002ffa8
         
     | 
| 
      
 7 
     | 
    
         
            +
              data.tar.gz: 674438f94176b2ed7e77283e7238ab96edefc49a4423f9bb967904137a964d2d72228fd7f815fdb102b3ed0823820ef4e99fe54a0863b2144a98d3a240a2ccdb
         
     | 
    
        data/CHANGELOG.md
    CHANGED
    
    | 
         @@ -1,5 +1,15 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            # NodeMutation
         
     | 
| 
       2 
2 
     | 
    
         | 
| 
      
 3 
     | 
    
         
            +
            ## 1.22.1 (2023-12-04)
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
            * `child_node_range` supports int/float/str/sym `value`
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
            ## 1.22.0 (2023-11-27)
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
            * Add `adapter` parameter to `NodeMutation`
         
     | 
| 
      
 10 
     | 
    
         
            +
            * Add `adapter` parameter to `NodeMutation::Action`
         
     | 
| 
      
 11 
     | 
    
         
            +
            * Do not allow to configure an `adapter` globally
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
       3 
13 
     | 
    
         
             
            ## 1.21.6 (2023-11-20)
         
     | 
| 
       4 
14 
     | 
    
         | 
| 
       5 
15 
     | 
    
         
             
            * Flat and sort actions after filtering actions when processing
         
     | 
    
        data/Gemfile.lock
    CHANGED
    
    
    
        data/README.md
    CHANGED
    
    | 
         @@ -25,7 +25,7 @@ Or install it yourself as: 
     | 
|
| 
       25 
25 
     | 
    
         
             
            ```ruby
         
     | 
| 
       26 
26 
     | 
    
         
             
            require 'node_mutation'
         
     | 
| 
       27 
27 
     | 
    
         | 
| 
       28 
     | 
    
         
            -
            mutation = NodeMutation.new(source)
         
     | 
| 
      
 28 
     | 
    
         
            +
            mutation = NodeMutation.new(source, adapter: :parser)
         
     | 
| 
       29 
29 
     | 
    
         
             
            ```
         
     | 
| 
       30 
30 
     | 
    
         | 
| 
       31 
31 
     | 
    
         
             
            2. call the rewrite apis:
         
     | 
| 
         @@ -91,10 +91,6 @@ Different parsers, like parse and ripper, will generate different AST nodes, to 
     | 
|
| 
       91 
91 
     | 
    
         
             
            we define an [Adapter](https://github.com/xinminlabs/node-mutation-ruby/blob/main/lib/node_mutation/adapter.rb) interface,
         
     | 
| 
       92 
92 
     | 
    
         
             
            if you implement the Adapter interface, you can set it as NodeMutation's adapter.
         
     | 
| 
       93 
93 
     | 
    
         | 
| 
       94 
     | 
    
         
            -
            ```ruby
         
     | 
| 
       95 
     | 
    
         
            -
            NodeMutation.configure(adapter: SyntaxTreeAdapter.new) // default is ParserAdapter
         
     | 
| 
       96 
     | 
    
         
            -
            ```
         
     | 
| 
       97 
     | 
    
         
            -
             
     | 
| 
       98 
94 
     | 
    
         
             
            ### strategy
         
     | 
| 
       99 
95 
     | 
    
         | 
| 
       100 
96 
     | 
    
         
             
            It provides 3 strategies to handle conflicts when processing actions:
         
     | 
| 
         @@ -2,8 +2,13 @@ 
     | 
|
| 
       2 
2 
     | 
    
         | 
| 
       3 
3 
     | 
    
         
             
            # AppendAction appends code to the bottom of node body.
         
     | 
| 
       4 
4 
     | 
    
         
             
            class NodeMutation::AppendAction < NodeMutation::Action
         
     | 
| 
       5 
     | 
    
         
            -
               
     | 
| 
       6 
     | 
    
         
            -
             
     | 
| 
      
 5 
     | 
    
         
            +
              # Initialize an AppendAction.
         
     | 
| 
      
 6 
     | 
    
         
            +
              #
         
     | 
| 
      
 7 
     | 
    
         
            +
              # @param node [Node]
         
     | 
| 
      
 8 
     | 
    
         
            +
              # @param code [String] new code to append.
         
     | 
| 
      
 9 
     | 
    
         
            +
              # @param adapter [NodeMutation::Adapter]
         
     | 
| 
      
 10 
     | 
    
         
            +
              def initialize(node, code, adapter:)
         
     | 
| 
      
 11 
     | 
    
         
            +
                super(node, code, adapter: adapter)
         
     | 
| 
       7 
12 
     | 
    
         
             
                @type = :insert
         
     | 
| 
       8 
13 
     | 
    
         
             
              end
         
     | 
| 
       9 
14 
     | 
    
         | 
| 
         @@ -13,7 +18,7 @@ class NodeMutation::AppendAction < NodeMutation::Action 
     | 
|
| 
       13 
18 
     | 
    
         | 
| 
       14 
19 
     | 
    
         
             
              # Calculate the begin the end positions.
         
     | 
| 
       15 
20 
     | 
    
         
             
              def calculate_position
         
     | 
| 
       16 
     | 
    
         
            -
                @start =  
     | 
| 
      
 21 
     | 
    
         
            +
                @start = @adapter.get_end(@node) - @adapter.get_start_loc(@node).column - END_LENGTH
         
     | 
| 
       17 
22 
     | 
    
         
             
                @end = @start
         
     | 
| 
       18 
23 
     | 
    
         
             
              end
         
     | 
| 
       19 
24 
     | 
    
         | 
| 
         @@ -22,6 +27,6 @@ class NodeMutation::AppendAction < NodeMutation::Action 
     | 
|
| 
       22 
27 
     | 
    
         
             
              # @param node [Parser::AST::Node]
         
     | 
| 
       23 
28 
     | 
    
         
             
              # @return [String] n times whitesphace
         
     | 
| 
       24 
29 
     | 
    
         
             
              def indent(node)
         
     | 
| 
       25 
     | 
    
         
            -
                ' ' *  ( 
     | 
| 
      
 30 
     | 
    
         
            +
                ' ' *  (@adapter.get_start_loc(node).column + NodeMutation.tab_width)
         
     | 
| 
       26 
31 
     | 
    
         
             
              end
         
     | 
| 
       27 
32 
     | 
    
         
             
            end
         
     | 
| 
         @@ -6,9 +6,10 @@ class NodeMutation::DeleteAction < NodeMutation::Action 
     | 
|
| 
       6 
6 
     | 
    
         
             
              #
         
     | 
| 
       7 
7 
     | 
    
         
             
              # @param node [Node]
         
     | 
| 
       8 
8 
     | 
    
         
             
              # @param selectors [Array<Symbol, String>] used to select child nodes
         
     | 
| 
       9 
     | 
    
         
            -
              # @ 
     | 
| 
       10 
     | 
    
         
            -
               
     | 
| 
       11 
     | 
    
         
            -
             
     | 
| 
      
 9 
     | 
    
         
            +
              # @param and_comma [Boolean] delete extra comma.
         
     | 
| 
      
 10 
     | 
    
         
            +
              # @param adapter [NodeMutation::Adapter]
         
     | 
| 
      
 11 
     | 
    
         
            +
              def initialize(node, *selectors, adapter:, and_comma: false)
         
     | 
| 
      
 12 
     | 
    
         
            +
                super(node, nil, adapter: adapter)
         
     | 
| 
       12 
13 
     | 
    
         
             
                @selectors = selectors
         
     | 
| 
       13 
14 
     | 
    
         
             
                @and_comma = and_comma
         
     | 
| 
       14 
15 
     | 
    
         
             
                @type = :delete
         
     | 
| 
         @@ -23,9 +24,9 @@ class NodeMutation::DeleteAction < NodeMutation::Action 
     | 
|
| 
       23 
24 
     | 
    
         | 
| 
       24 
25 
     | 
    
         
             
              # Calculate the begin and end positions.
         
     | 
| 
       25 
26 
     | 
    
         
             
              def calculate_position
         
     | 
| 
       26 
     | 
    
         
            -
                @start = @selectors.map { |selector|  
     | 
| 
      
 27 
     | 
    
         
            +
                @start = @selectors.map { |selector| @adapter.child_node_range(@node, selector) }
         
     | 
| 
       27 
28 
     | 
    
         
             
                                   .compact.map(&:start).min
         
     | 
| 
       28 
     | 
    
         
            -
                @end = @selectors.map { |selector|  
     | 
| 
      
 29 
     | 
    
         
            +
                @end = @selectors.map { |selector| @adapter.child_node_range(@node, selector) }
         
     | 
| 
       29 
30 
     | 
    
         
             
                                 .compact.map(&:end).max
         
     | 
| 
       30 
31 
     | 
    
         
             
                remove_comma if @and_comma
         
     | 
| 
       31 
32 
     | 
    
         
             
                remove_whitespace
         
     | 
| 
         @@ -6,8 +6,9 @@ class NodeMutation::IndentAction < NodeMutation::Action 
     | 
|
| 
       6 
6 
     | 
    
         
             
              #
         
     | 
| 
       7 
7 
     | 
    
         
             
              # @param node [Node]
         
     | 
| 
       8 
8 
     | 
    
         
             
              # @param tab_size [Integer] tab size
         
     | 
| 
       9 
     | 
    
         
            -
               
     | 
| 
       10 
     | 
    
         
            -
             
     | 
| 
      
 9 
     | 
    
         
            +
              # @param adapter [NodeMutation::Adapter]
         
     | 
| 
      
 10 
     | 
    
         
            +
              def initialize(node, tab_size = 1, adapter:)
         
     | 
| 
      
 11 
     | 
    
         
            +
                super(node, nil, adapter: adapter)
         
     | 
| 
       11 
12 
     | 
    
         
             
                @tab_size = tab_size
         
     | 
| 
       12 
13 
     | 
    
         
             
                @type = :replace
         
     | 
| 
       13 
14 
     | 
    
         
             
              end
         
     | 
| 
         @@ -16,7 +17,7 @@ class NodeMutation::IndentAction < NodeMutation::Action 
     | 
|
| 
       16 
17 
     | 
    
         
             
              #
         
     | 
| 
       17 
18 
     | 
    
         
             
              # @return [String] rewritten code.
         
     | 
| 
       18 
19 
     | 
    
         
             
              def new_code
         
     | 
| 
       19 
     | 
    
         
            -
                source =  
     | 
| 
      
 20 
     | 
    
         
            +
                source = @adapter.get_source(@node)
         
     | 
| 
       20 
21 
     | 
    
         
             
                source.each_line.map { |line| (' ' * NodeMutation.tab_width * @tab_size) + line }
         
     | 
| 
       21 
22 
     | 
    
         
             
                      .join
         
     | 
| 
       22 
23 
     | 
    
         
             
              end
         
     | 
| 
         @@ -25,7 +26,7 @@ class NodeMutation::IndentAction < NodeMutation::Action 
     | 
|
| 
       25 
26 
     | 
    
         | 
| 
       26 
27 
     | 
    
         
             
              # Calculate the begin the end positions.
         
     | 
| 
       27 
28 
     | 
    
         
             
              def calculate_position
         
     | 
| 
       28 
     | 
    
         
            -
                @start =  
     | 
| 
       29 
     | 
    
         
            -
                @end =  
     | 
| 
      
 29 
     | 
    
         
            +
                @start = @adapter.get_start(@node)
         
     | 
| 
      
 30 
     | 
    
         
            +
                @end = @adapter.get_end(@node)
         
     | 
| 
       30 
31 
     | 
    
         
             
              end
         
     | 
| 
       31 
32 
     | 
    
         
             
            end
         
     | 
| 
         @@ -9,8 +9,9 @@ class NodeMutation::InsertAction < NodeMutation::Action 
     | 
|
| 
       9 
9 
     | 
    
         
             
              # @param at [String] position to insert, beginning or end
         
     | 
| 
       10 
10 
     | 
    
         
             
              # @param to [<nil|String>] name of child node
         
     | 
| 
       11 
11 
     | 
    
         
             
              # @param and_comma [Boolean] insert extra comma.
         
     | 
| 
       12 
     | 
    
         
            -
               
     | 
| 
       13 
     | 
    
         
            -
             
     | 
| 
      
 12 
     | 
    
         
            +
              # @param adapter [NodeMutation::Adapter]
         
     | 
| 
      
 13 
     | 
    
         
            +
              def initialize(node, code, adapter:, at: 'end', to: nil, and_comma: false)
         
     | 
| 
      
 14 
     | 
    
         
            +
                super(node, code, adapter: adapter)
         
     | 
| 
       14 
15 
     | 
    
         
             
                @at = at
         
     | 
| 
       15 
16 
     | 
    
         
             
                @to = to
         
     | 
| 
       16 
17 
     | 
    
         
             
                @and_comma = and_comma
         
     | 
| 
         @@ -35,15 +36,15 @@ class NodeMutation::InsertAction < NodeMutation::Action 
     | 
|
| 
       35 
36 
     | 
    
         
             
                @start =
         
     | 
| 
       36 
37 
     | 
    
         
             
                  if @at == 'end'
         
     | 
| 
       37 
38 
     | 
    
         
             
                    if @to
         
     | 
| 
       38 
     | 
    
         
            -
                       
     | 
| 
      
 39 
     | 
    
         
            +
                      @adapter.child_node_range(@node, @to).end
         
     | 
| 
       39 
40 
     | 
    
         
             
                    else
         
     | 
| 
       40 
     | 
    
         
            -
                       
     | 
| 
      
 41 
     | 
    
         
            +
                      @adapter.get_end(@node)
         
     | 
| 
       41 
42 
     | 
    
         
             
                    end
         
     | 
| 
       42 
43 
     | 
    
         
             
                  else
         
     | 
| 
       43 
44 
     | 
    
         
             
                    if @to
         
     | 
| 
       44 
     | 
    
         
            -
                       
     | 
| 
      
 45 
     | 
    
         
            +
                      @adapter.child_node_range(@node, @to).start
         
     | 
| 
       45 
46 
     | 
    
         
             
                    else
         
     | 
| 
       46 
     | 
    
         
            -
                       
     | 
| 
      
 47 
     | 
    
         
            +
                      @adapter.get_start(@node)
         
     | 
| 
       47 
48 
     | 
    
         
             
                    end
         
     | 
| 
       48 
49 
     | 
    
         
             
                  end
         
     | 
| 
       49 
50 
     | 
    
         
             
                @end = @start
         
     | 
| 
         @@ -2,9 +2,12 @@ 
     | 
|
| 
       2 
2 
     | 
    
         | 
| 
       3 
3 
     | 
    
         
             
            # NoopAction to do no operation.
         
     | 
| 
       4 
4 
     | 
    
         
             
            class NodeMutation::NoopAction < NodeMutation::Action
         
     | 
| 
       5 
     | 
    
         
            -
              #  
     | 
| 
       6 
     | 
    
         
            -
               
     | 
| 
       7 
     | 
    
         
            -
             
     | 
| 
      
 5 
     | 
    
         
            +
              # Initialize a NoopAction.
         
     | 
| 
      
 6 
     | 
    
         
            +
              #
         
     | 
| 
      
 7 
     | 
    
         
            +
              # @param node [Node]
         
     | 
| 
      
 8 
     | 
    
         
            +
              # @param adapter [NodeMutation::Adapter]
         
     | 
| 
      
 9 
     | 
    
         
            +
              def initialize(node, adapter:)
         
     | 
| 
      
 10 
     | 
    
         
            +
                super(node, nil, adapter: adapter)
         
     | 
| 
       8 
11 
     | 
    
         
             
              end
         
     | 
| 
       9 
12 
     | 
    
         | 
| 
       10 
13 
     | 
    
         
             
              # The rewritten source code with proper indent.
         
     | 
| 
         @@ -18,7 +21,7 @@ class NodeMutation::NoopAction < NodeMutation::Action 
     | 
|
| 
       18 
21 
     | 
    
         | 
| 
       19 
22 
     | 
    
         
             
              # Calculate the begin the end positions.
         
     | 
| 
       20 
23 
     | 
    
         
             
              def calculate_position
         
     | 
| 
       21 
     | 
    
         
            -
                @start =  
     | 
| 
       22 
     | 
    
         
            -
                @end =  
     | 
| 
      
 24 
     | 
    
         
            +
                @start = @adapter.get_start(@node)
         
     | 
| 
      
 25 
     | 
    
         
            +
                @end = @adapter.get_end(@node)
         
     | 
| 
       23 
26 
     | 
    
         
             
              end
         
     | 
| 
       24 
27 
     | 
    
         
             
            end
         
     | 
| 
         @@ -2,8 +2,13 @@ 
     | 
|
| 
       2 
2 
     | 
    
         | 
| 
       3 
3 
     | 
    
         
             
            # PrependAction to prepend code to the top of node body.
         
     | 
| 
       4 
4 
     | 
    
         
             
            class NodeMutation::PrependAction < NodeMutation::Action
         
     | 
| 
       5 
     | 
    
         
            -
               
     | 
| 
       6 
     | 
    
         
            -
             
     | 
| 
      
 5 
     | 
    
         
            +
              # Initialize an PrependAction.
         
     | 
| 
      
 6 
     | 
    
         
            +
              #
         
     | 
| 
      
 7 
     | 
    
         
            +
              # @param node [Node]
         
     | 
| 
      
 8 
     | 
    
         
            +
              # @param code [String] new code to prepend.
         
     | 
| 
      
 9 
     | 
    
         
            +
              # @param adapter [NodeMutation::Adapter]
         
     | 
| 
      
 10 
     | 
    
         
            +
              def initialize(node, code, adapter:)
         
     | 
| 
      
 11 
     | 
    
         
            +
                super(node, code, adapter: adapter)
         
     | 
| 
       7 
12 
     | 
    
         
             
                @type = :insert
         
     | 
| 
       8 
13 
     | 
    
         
             
              end
         
     | 
| 
       9 
14 
     | 
    
         | 
| 
         @@ -11,8 +16,8 @@ class NodeMutation::PrependAction < NodeMutation::Action 
     | 
|
| 
       11 
16 
     | 
    
         | 
| 
       12 
17 
     | 
    
         
             
              # Calculate the begin and end positions.
         
     | 
| 
       13 
18 
     | 
    
         
             
              def calculate_position
         
     | 
| 
       14 
     | 
    
         
            -
                node_start =  
     | 
| 
       15 
     | 
    
         
            -
                node_source =  
     | 
| 
      
 19 
     | 
    
         
            +
                node_start = @adapter.get_start(@node)
         
     | 
| 
      
 20 
     | 
    
         
            +
                node_source = @adapter.get_source(@node)
         
     | 
| 
       16 
21 
     | 
    
         
             
                first_line = node_source.split("\n").first
         
     | 
| 
       17 
22 
     | 
    
         
             
                @start = first_line.end_with?("do") ? node_start + first_line.rindex("do") + "do".length : node_start + first_line.length
         
     | 
| 
       18 
23 
     | 
    
         
             
                @end = @start
         
     | 
| 
         @@ -23,6 +28,6 @@ class NodeMutation::PrependAction < NodeMutation::Action 
     | 
|
| 
       23 
28 
     | 
    
         
             
              # @param node [Parser::AST::Node]
         
     | 
| 
       24 
29 
     | 
    
         
             
              # @return [String] n times whitesphace
         
     | 
| 
       25 
30 
     | 
    
         
             
              def indent(node)
         
     | 
| 
       26 
     | 
    
         
            -
                ' ' * ( 
     | 
| 
      
 31 
     | 
    
         
            +
                ' ' * (@adapter.get_start_loc(node).column + NodeMutation.tab_width)
         
     | 
| 
       27 
32 
     | 
    
         
             
              end
         
     | 
| 
       28 
33 
     | 
    
         
             
            end
         
     | 
| 
         @@ -5,10 +5,10 @@ class NodeMutation::RemoveAction < NodeMutation::Action 
     | 
|
| 
       5 
5 
     | 
    
         
             
              # Initialize a RemoveAction.
         
     | 
| 
       6 
6 
     | 
    
         
             
              #
         
     | 
| 
       7 
7 
     | 
    
         
             
              # @param node [Node]
         
     | 
| 
       8 
     | 
    
         
            -
              # @param  
     | 
| 
       9 
     | 
    
         
            -
              # @ 
     | 
| 
       10 
     | 
    
         
            -
              def initialize(node, and_comma: false)
         
     | 
| 
       11 
     | 
    
         
            -
                super(node, nil)
         
     | 
| 
      
 8 
     | 
    
         
            +
              # @param and_comma [Boolean] delete extra comma.
         
     | 
| 
      
 9 
     | 
    
         
            +
              # @param adapter [NodeMutation::Adapter]
         
     | 
| 
      
 10 
     | 
    
         
            +
              def initialize(node, adapter:, and_comma: false)
         
     | 
| 
      
 11 
     | 
    
         
            +
                super(node, nil, adapter: adapter)
         
     | 
| 
       12 
12 
     | 
    
         
             
                @and_comma = and_comma
         
     | 
| 
       13 
13 
     | 
    
         
             
                @type = :delete
         
     | 
| 
       14 
14 
     | 
    
         
             
              end
         
     | 
| 
         @@ -22,8 +22,8 @@ class NodeMutation::RemoveAction < NodeMutation::Action 
     | 
|
| 
       22 
22 
     | 
    
         | 
| 
       23 
23 
     | 
    
         
             
              # Calculate the begin the end positions.
         
     | 
| 
       24 
24 
     | 
    
         
             
              def calculate_position
         
     | 
| 
       25 
     | 
    
         
            -
                @start =  
     | 
| 
       26 
     | 
    
         
            -
                @end =  
     | 
| 
      
 25 
     | 
    
         
            +
                @start = @adapter.get_start(@node)
         
     | 
| 
      
 26 
     | 
    
         
            +
                @end = @adapter.get_end(@node)
         
     | 
| 
       27 
27 
     | 
    
         
             
                remove_comma if @and_comma
         
     | 
| 
       28 
28 
     | 
    
         
             
                remove_whitespace
         
     | 
| 
       29 
29 
     | 
    
         
             
                if take_whole_line?
         
     | 
| 
         @@ -36,7 +36,7 @@ class NodeMutation::RemoveAction < NodeMutation::Action 
     | 
|
| 
       36 
36 
     | 
    
         
             
              #
         
     | 
| 
       37 
37 
     | 
    
         
             
              # @return [Boolean]
         
     | 
| 
       38 
38 
     | 
    
         
             
              def take_whole_line?
         
     | 
| 
       39 
     | 
    
         
            -
                 
     | 
| 
      
 39 
     | 
    
         
            +
                @adapter.get_source(@node) == file_source[@start...@end].strip.chomp(',')
         
     | 
| 
       40 
40 
     | 
    
         
             
              end
         
     | 
| 
       41 
41 
     | 
    
         | 
| 
       42 
42 
     | 
    
         
             
              def remove_newline
         
     | 
| 
         @@ -73,8 +73,8 @@ class NodeMutation::RemoveAction < NodeMutation::Action 
     | 
|
| 
       73 
73 
     | 
    
         | 
| 
       74 
74 
     | 
    
         
             
              def squeeze_lines
         
     | 
| 
       75 
75 
     | 
    
         
             
                lines = file_source.split("\n")
         
     | 
| 
       76 
     | 
    
         
            -
                begin_line =  
     | 
| 
       77 
     | 
    
         
            -
                end_line =  
     | 
| 
      
 76 
     | 
    
         
            +
                begin_line = @adapter.get_start_loc(@node).line
         
     | 
| 
      
 77 
     | 
    
         
            +
                end_line = @adapter.get_end_loc(@node).line
         
     | 
| 
       78 
78 
     | 
    
         
             
                before_line_is_blank = begin_line == 1 || lines[begin_line - 2] == ''
         
     | 
| 
       79 
79 
     | 
    
         
             
                after_line_is_blank = lines[end_line] == ''
         
     | 
| 
       80 
80 
     | 
    
         | 
| 
         @@ -7,8 +7,9 @@ class NodeMutation::ReplaceAction < NodeMutation::Action 
     | 
|
| 
       7 
7 
     | 
    
         
             
              # @param node [Node]
         
     | 
| 
       8 
8 
     | 
    
         
             
              # @param selectors [Array<Symbol|String>] used to select child nodes
         
     | 
| 
       9 
9 
     | 
    
         
             
              # @param with [String] the new code
         
     | 
| 
       10 
     | 
    
         
            -
               
     | 
| 
       11 
     | 
    
         
            -
             
     | 
| 
      
 10 
     | 
    
         
            +
              # @param adapter [NodeMutation::Adapter]
         
     | 
| 
      
 11 
     | 
    
         
            +
              def initialize(node, *selectors, adapter:, with:)
         
     | 
| 
      
 12 
     | 
    
         
            +
                super(node, with, adapter: adapter)
         
     | 
| 
       12 
13 
     | 
    
         
             
                @selectors = selectors
         
     | 
| 
       13 
14 
     | 
    
         
             
                @type = :replace
         
     | 
| 
       14 
15 
     | 
    
         
             
              end
         
     | 
| 
         @@ -24,9 +25,9 @@ class NodeMutation::ReplaceAction < NodeMutation::Action 
     | 
|
| 
       24 
25 
     | 
    
         | 
| 
       25 
26 
     | 
    
         
             
              # Calculate the begin the end positions.
         
     | 
| 
       26 
27 
     | 
    
         
             
              def calculate_position
         
     | 
| 
       27 
     | 
    
         
            -
                @start = @selectors.map { |selector|  
     | 
| 
      
 28 
     | 
    
         
            +
                @start = @selectors.map { |selector| @adapter.child_node_range(@node, selector).start }
         
     | 
| 
       28 
29 
     | 
    
         
             
                                   .min
         
     | 
| 
       29 
     | 
    
         
            -
                @end = @selectors.map { |selector|  
     | 
| 
      
 30 
     | 
    
         
            +
                @end = @selectors.map { |selector| @adapter.child_node_range(@node, selector).end }
         
     | 
| 
       30 
31 
     | 
    
         
             
                                 .max
         
     | 
| 
       31 
32 
     | 
    
         
             
              end
         
     | 
| 
       32 
33 
     | 
    
         
             
            end
         
     | 
| 
         @@ -2,8 +2,13 @@ 
     | 
|
| 
       2 
2 
     | 
    
         | 
| 
       3 
3 
     | 
    
         
             
            # ReplaceWithAction to replace code.
         
     | 
| 
       4 
4 
     | 
    
         
             
            class NodeMutation::ReplaceWithAction < NodeMutation::Action
         
     | 
| 
       5 
     | 
    
         
            -
               
     | 
| 
       6 
     | 
    
         
            -
             
     | 
| 
      
 5 
     | 
    
         
            +
              # Initailize a ReplaceWithAction.
         
     | 
| 
      
 6 
     | 
    
         
            +
              #
         
     | 
| 
      
 7 
     | 
    
         
            +
              # @param node [Node]
         
     | 
| 
      
 8 
     | 
    
         
            +
              # @param code [String] the new code.
         
     | 
| 
      
 9 
     | 
    
         
            +
              # @param adapter [NodeMutation::Adapter]
         
     | 
| 
      
 10 
     | 
    
         
            +
              def initialize(node, code, adapter:)
         
     | 
| 
      
 11 
     | 
    
         
            +
                super(node, code, adapter: adapter)
         
     | 
| 
       7 
12 
     | 
    
         
             
                @type = :replace
         
     | 
| 
       8 
13 
     | 
    
         
             
              end
         
     | 
| 
       9 
14 
     | 
    
         | 
| 
         @@ -26,14 +31,14 @@ class NodeMutation::ReplaceWithAction < NodeMutation::Action 
     | 
|
| 
       26 
31 
     | 
    
         | 
| 
       27 
32 
     | 
    
         
             
              # Calculate the begin the end positions.
         
     | 
| 
       28 
33 
     | 
    
         
             
              def calculate_position
         
     | 
| 
       29 
     | 
    
         
            -
                @start =  
     | 
| 
       30 
     | 
    
         
            -
                @end =  
     | 
| 
      
 34 
     | 
    
         
            +
                @start = @adapter.get_start(@node)
         
     | 
| 
      
 35 
     | 
    
         
            +
                @end = @adapter.get_end(@node)
         
     | 
| 
       31 
36 
     | 
    
         
             
              end
         
     | 
| 
       32 
37 
     | 
    
         | 
| 
       33 
38 
     | 
    
         
             
              # Indent of the node
         
     | 
| 
       34 
39 
     | 
    
         
             
              #
         
     | 
| 
       35 
40 
     | 
    
         
             
              # @return [String] n times whitesphace
         
     | 
| 
       36 
41 
     | 
    
         
             
              def indent
         
     | 
| 
       37 
     | 
    
         
            -
                ' ' *  
     | 
| 
      
 42 
     | 
    
         
            +
                ' ' * @adapter.get_start_loc(@node).column
         
     | 
| 
       38 
43 
     | 
    
         
             
              end
         
     | 
| 
       39 
44 
     | 
    
         
             
            end
         
     | 
    
        data/lib/node_mutation/action.rb
    CHANGED
    
    | 
         @@ -16,9 +16,11 @@ class NodeMutation::Action 
     | 
|
| 
       16 
16 
     | 
    
         
             
              #
         
     | 
| 
       17 
17 
     | 
    
         
             
              # @param node [Node]
         
     | 
| 
       18 
18 
     | 
    
         
             
              # @param code [String] new code to insert, replace or delete.
         
     | 
| 
       19 
     | 
    
         
            -
               
     | 
| 
      
 19 
     | 
    
         
            +
              # @param adapter [NodeMutation::Adapter]
         
     | 
| 
      
 20 
     | 
    
         
            +
              def initialize(node, code, adapter:)
         
     | 
| 
       20 
21 
     | 
    
         
             
                @node = node
         
     | 
| 
       21 
22 
     | 
    
         
             
                @code = code
         
     | 
| 
      
 23 
     | 
    
         
            +
                @adapter = adapter
         
     | 
| 
       22 
24 
     | 
    
         
             
              end
         
     | 
| 
       23 
25 
     | 
    
         | 
| 
       24 
26 
     | 
    
         
             
              # Calculate begin and end positions, and return self.
         
     | 
| 
         @@ -59,7 +61,7 @@ class NodeMutation::Action 
     | 
|
| 
       59 
61 
     | 
    
         
             
              #
         
     | 
| 
       60 
62 
     | 
    
         
             
              # @return [String] rewritten source code.
         
     | 
| 
       61 
63 
     | 
    
         
             
              def rewritten_source
         
     | 
| 
       62 
     | 
    
         
            -
                @rewritten_source ||=  
     | 
| 
      
 64 
     | 
    
         
            +
                @rewritten_source ||= @adapter.rewritten_source(@node, @code)
         
     | 
| 
       63 
65 
     | 
    
         
             
              end
         
     | 
| 
       64 
66 
     | 
    
         | 
| 
       65 
67 
     | 
    
         
             
              # remove unused whitespace.
         
     | 
| 
         @@ -115,6 +117,6 @@ class NodeMutation::Action 
     | 
|
| 
       115 
117 
     | 
    
         
             
              #
         
     | 
| 
       116 
118 
     | 
    
         
             
              # @return [String]
         
     | 
| 
       117 
119 
     | 
    
         
             
              def file_source
         
     | 
| 
       118 
     | 
    
         
            -
                @file_source ||=  
     | 
| 
      
 120 
     | 
    
         
            +
                @file_source ||= @adapter.file_source(@node)
         
     | 
| 
       119 
121 
     | 
    
         
             
              end
         
     | 
| 
       120 
122 
     | 
    
         
             
            end
         
     | 
| 
         @@ -82,7 +82,7 @@ class NodeMutation::ParserAdapter < NodeMutation::Adapter 
     | 
|
| 
       82 
82 
     | 
    
         
             
                      if lines_count > 1 && lines_count == evaluated.size
         
     | 
| 
       83 
83 
     | 
    
         
             
                        new_code = []
         
     | 
| 
       84 
84 
     | 
    
         
             
                        lines.each_with_index { |line, index|
         
     | 
| 
       85 
     | 
    
         
            -
                          new_code << (index == 0 ? line : line[ 
     | 
| 
      
 85 
     | 
    
         
            +
                          new_code << (index == 0 ? line : line[get_indent(evaluated.first) - NodeMutation.tab_width..-1])
         
     | 
| 
       86 
86 
     | 
    
         
             
                        }
         
     | 
| 
       87 
87 
     | 
    
         
             
                        new_code.join("\n")
         
     | 
| 
       88 
88 
     | 
    
         
             
                      else
         
     | 
| 
         @@ -185,6 +185,8 @@ class NodeMutation::ParserAdapter < NodeMutation::Adapter 
     | 
|
| 
       185 
185 
     | 
    
         
             
                  NodeMutation::Struct::Range.new(node.loc.operator.begin_pos, node.loc.operator.end_pos) if node.loc.operator
         
     | 
| 
       186 
186 
     | 
    
         
             
                when %i[defs self]
         
     | 
| 
       187 
187 
     | 
    
         
             
                  NodeMutation::Struct::Range.new(node.loc.operator.begin_pos - 'self'.length, node.loc.operator.begin_pos)
         
     | 
| 
      
 188 
     | 
    
         
            +
                when %i[float value], %i[int value], %i[rational value], %i[str value], %i[sym value]
         
     | 
| 
      
 189 
     | 
    
         
            +
                  NodeMutation::Struct::Range.new(node.loc.expression.begin_pos, node.loc.expression.end_pos)
         
     | 
| 
       188 
190 
     | 
    
         
             
                when %i[lvasgn variable], %i[ivasgn variable], %i[cvasgn variable], %i[gvasgn variable]
         
     | 
| 
       189 
191 
     | 
    
         
             
                  NodeMutation::Struct::Range.new(node.loc.name.begin_pos, node.loc.name.end_pos)
         
     | 
| 
       190 
192 
     | 
    
         
             
                when %i[send dot], %i[csend dot]
         
     | 
| 
         @@ -74,7 +74,7 @@ class NodeMutation::SyntaxTreeAdapter < NodeMutation::Adapter 
     | 
|
| 
       74 
74 
     | 
    
         
             
                      if lines_count > 1 && lines_count == evaluated.size
         
     | 
| 
       75 
75 
     | 
    
         
             
                        new_code = []
         
     | 
| 
       76 
76 
     | 
    
         
             
                        lines.each_with_index { |line, index|
         
     | 
| 
       77 
     | 
    
         
            -
                          new_code << (index == 0 ? line : line[ 
     | 
| 
      
 77 
     | 
    
         
            +
                          new_code << (index == 0 ? line : line[get_indent(evaluated.first) - NodeMutation.tab_width..-1])
         
     | 
| 
       78 
78 
     | 
    
         
             
                        }
         
     | 
| 
       79 
79 
     | 
    
         
             
                        new_code.join("\n")
         
     | 
| 
       80 
80 
     | 
    
         
             
                      else
         
     | 
    
        data/lib/node_mutation.rb
    CHANGED
    
    | 
         @@ -5,6 +5,7 @@ require_relative "node_mutation/version" 
     | 
|
| 
       5 
5 
     | 
    
         
             
            class NodeMutation
         
     | 
| 
       6 
6 
     | 
    
         
             
              class MethodNotSupported < StandardError; end
         
     | 
| 
       7 
7 
     | 
    
         
             
              class ConflictActionError < StandardError; end
         
     | 
| 
      
 8 
     | 
    
         
            +
              class InvalidAdapterError < StandardError; end
         
     | 
| 
       8 
9 
     | 
    
         | 
| 
       9 
10 
     | 
    
         
             
              autoload :Adapter, "node_mutation/adapter"
         
     | 
| 
       10 
11 
     | 
    
         
             
              autoload :ParserAdapter, "node_mutation/adapter/parser"
         
     | 
| 
         @@ -27,7 +28,7 @@ class NodeMutation 
     | 
|
| 
       27 
28 
     | 
    
         | 
| 
       28 
29 
     | 
    
         
             
              # @!attribute [r] actions
         
     | 
| 
       29 
30 
     | 
    
         
             
              #   @return [Array<NodeMutation::Struct::Action>]
         
     | 
| 
       30 
     | 
    
         
            -
              attr_reader :actions
         
     | 
| 
      
 31 
     | 
    
         
            +
              attr_reader :actions, :adapter
         
     | 
| 
       31 
32 
     | 
    
         | 
| 
       32 
33 
     | 
    
         
             
              # @!attribute [rw] transform_proc
         
     | 
| 
       33 
34 
     | 
    
         
             
              #  @return [Proc] proc to transfor the actions
         
     | 
| 
         @@ -36,13 +37,9 @@ class NodeMutation 
     | 
|
| 
       36 
37 
     | 
    
         
             
              class << self
         
     | 
| 
       37 
38 
     | 
    
         
             
                # Configure NodeMutation
         
     | 
| 
       38 
39 
     | 
    
         
             
                # @param [Hash] options options to configure
         
     | 
| 
       39 
     | 
    
         
            -
                # @option options [NodeMutation::Adapter] :adapter the adpater
         
     | 
| 
       40 
40 
     | 
    
         
             
                # @option options [NodeMutation::Strategy] :strategy the strategy
         
     | 
| 
       41 
41 
     | 
    
         
             
                # @option options [Integer] :tab_width the tab width
         
     | 
| 
       42 
42 
     | 
    
         
             
                def configure(options)
         
     | 
| 
       43 
     | 
    
         
            -
                  if options[:adapter]
         
     | 
| 
       44 
     | 
    
         
            -
                    @adapter = options[:adapter]
         
     | 
| 
       45 
     | 
    
         
            -
                  end
         
     | 
| 
       46 
43 
     | 
    
         
             
                  if options[:strategy]
         
     | 
| 
       47 
44 
     | 
    
         
             
                    @strategy = options[:strategy]
         
     | 
| 
       48 
45 
     | 
    
         
             
                  end
         
     | 
| 
         @@ -51,12 +48,6 @@ class NodeMutation 
     | 
|
| 
       51 
48 
     | 
    
         
             
                  end
         
     | 
| 
       52 
49 
     | 
    
         
             
                end
         
     | 
| 
       53 
50 
     | 
    
         | 
| 
       54 
     | 
    
         
            -
                # Get the adapter
         
     | 
| 
       55 
     | 
    
         
            -
                # @return [NodeMutation::Adapter] current adapter, by default is {NodeMutation::ParserAdapter}
         
     | 
| 
       56 
     | 
    
         
            -
                def adapter
         
     | 
| 
       57 
     | 
    
         
            -
                  @adapter ||= ParserAdapter.new
         
     | 
| 
       58 
     | 
    
         
            -
                end
         
     | 
| 
       59 
     | 
    
         
            -
             
     | 
| 
       60 
51 
     | 
    
         
             
                # Get the strategy
         
     | 
| 
       61 
52 
     | 
    
         
             
                # @return [Integer] current strategy, could be {NodeMutation::Strategy::KEEP_RUNNING} or {NodeMutation::Strategy::THROW_ERROR},
         
     | 
| 
       62 
53 
     | 
    
         
             
                # by default is {NodeMutation::Strategy::KEEP_RUNNING}
         
     | 
| 
         @@ -73,9 +64,11 @@ class NodeMutation 
     | 
|
| 
       73 
64 
     | 
    
         | 
| 
       74 
65 
     | 
    
         
             
              # Initialize a NodeMutation.
         
     | 
| 
       75 
66 
     | 
    
         
             
              # @param source [String] file source
         
     | 
| 
       76 
     | 
    
         
            -
               
     | 
| 
      
 67 
     | 
    
         
            +
              # @param adapter [Symbol] :parser or :syntax_tree
         
     | 
| 
      
 68 
     | 
    
         
            +
              def initialize(source, adapter:)
         
     | 
| 
       77 
69 
     | 
    
         
             
                @source = source
         
     | 
| 
       78 
70 
     | 
    
         
             
                @actions = []
         
     | 
| 
      
 71 
     | 
    
         
            +
                @adapter = get_adapter_instance(adapter)
         
     | 
| 
       79 
72 
     | 
    
         
             
              end
         
     | 
| 
       80 
73 
     | 
    
         | 
| 
       81 
74 
     | 
    
         
             
              # Append code to the ast node.
         
     | 
| 
         @@ -94,7 +87,7 @@ class NodeMutation 
     | 
|
| 
       94 
87 
     | 
    
         
             
              #       super
         
     | 
| 
       95 
88 
     | 
    
         
             
              #     end
         
     | 
| 
       96 
89 
     | 
    
         
             
              def append(node, code)
         
     | 
| 
       97 
     | 
    
         
            -
                @actions << AppendAction.new(node, code).process
         
     | 
| 
      
 90 
     | 
    
         
            +
                @actions << AppendAction.new(node, code, adapter: @adapter).process
         
     | 
| 
       98 
91 
     | 
    
         
             
              end
         
     | 
| 
       99 
92 
     | 
    
         | 
| 
       100 
93 
     | 
    
         
             
              # Delete source code of the child ast node.
         
     | 
| 
         @@ -109,7 +102,7 @@ class NodeMutation 
     | 
|
| 
       109 
102 
     | 
    
         
             
              # the source code will be rewritten to
         
     | 
| 
       110 
103 
     | 
    
         
             
              #     create(...)
         
     | 
| 
       111 
104 
     | 
    
         
             
              def delete(node, *selectors, and_comma: false)
         
     | 
| 
       112 
     | 
    
         
            -
                @actions << DeleteAction.new(node, *selectors, and_comma: and_comma).process
         
     | 
| 
      
 105 
     | 
    
         
            +
                @actions << DeleteAction.new(node, *selectors, and_comma: and_comma, adapter: @adapter).process
         
     | 
| 
       113 
106 
     | 
    
         
             
              end
         
     | 
| 
       114 
107 
     | 
    
         | 
| 
       115 
108 
     | 
    
         
             
              # Insert code to the ast node.
         
     | 
| 
         @@ -126,7 +119,7 @@ class NodeMutation 
     | 
|
| 
       126 
119 
     | 
    
         
             
              # the source code will be rewritten to
         
     | 
| 
       127 
120 
     | 
    
         
             
              #     URI.open('http://test.com')
         
     | 
| 
       128 
121 
     | 
    
         
             
              def insert(node, code, at: 'end', to: nil, and_comma: false)
         
     | 
| 
       129 
     | 
    
         
            -
                @actions << InsertAction.new(node, code, at: at, to: to, and_comma: and_comma).process
         
     | 
| 
      
 122 
     | 
    
         
            +
                @actions << InsertAction.new(node, code, at: at, to: to, and_comma: and_comma, adapter: @adapter).process
         
     | 
| 
       130 
123 
     | 
    
         
             
              end
         
     | 
| 
       131 
124 
     | 
    
         | 
| 
       132 
125 
     | 
    
         
             
              # Prepend code to the ast node.
         
     | 
| 
         @@ -145,7 +138,7 @@ class NodeMutation 
     | 
|
| 
       145 
138 
     | 
    
         
             
              #       do_something
         
     | 
| 
       146 
139 
     | 
    
         
             
              #     end
         
     | 
| 
       147 
140 
     | 
    
         
             
              def prepend(node, code)
         
     | 
| 
       148 
     | 
    
         
            -
                @actions << PrependAction.new(node, code).process
         
     | 
| 
      
 141 
     | 
    
         
            +
                @actions << PrependAction.new(node, code, adapter: @adapter).process
         
     | 
| 
       149 
142 
     | 
    
         
             
              end
         
     | 
| 
       150 
143 
     | 
    
         | 
| 
       151 
144 
     | 
    
         
             
              # Remove source code of the ast node.
         
     | 
| 
         @@ -158,7 +151,7 @@ class NodeMutation 
     | 
|
| 
       158 
151 
     | 
    
         
             
              #     mutation.remove(node)
         
     | 
| 
       159 
152 
     | 
    
         
             
              # the source code will be removed
         
     | 
| 
       160 
153 
     | 
    
         
             
              def remove(node, and_comma: false)
         
     | 
| 
       161 
     | 
    
         
            -
                @actions << RemoveAction.new(node, and_comma: and_comma).process
         
     | 
| 
      
 154 
     | 
    
         
            +
                @actions << RemoveAction.new(node, and_comma: and_comma, adapter: @adapter).process
         
     | 
| 
       162 
155 
     | 
    
         
             
              end
         
     | 
| 
       163 
156 
     | 
    
         | 
| 
       164 
157 
     | 
    
         
             
              # Replace child node of the ast node with new code.
         
     | 
| 
         @@ -174,7 +167,7 @@ class NodeMutation 
     | 
|
| 
       174 
167 
     | 
    
         
             
              # the source code will be rewritten to
         
     | 
| 
       175 
168 
     | 
    
         
             
              #     assert_empty(object)
         
     | 
| 
       176 
169 
     | 
    
         
             
              def replace(node, *selectors, with:)
         
     | 
| 
       177 
     | 
    
         
            -
                @actions << ReplaceAction.new(node, *selectors, with: with).process
         
     | 
| 
      
 170 
     | 
    
         
            +
                @actions << ReplaceAction.new(node, *selectors, with: with, adapter: @adapter).process
         
     | 
| 
       178 
171 
     | 
    
         
             
              end
         
     | 
| 
       179 
172 
     | 
    
         | 
| 
       180 
173 
     | 
    
         
             
              # Replace source code of the ast node with new code.
         
     | 
| 
         @@ -188,7 +181,7 @@ class NodeMutation 
     | 
|
| 
       188 
181 
     | 
    
         
             
              # the source code will be rewritten to
         
     | 
| 
       189 
182 
     | 
    
         
             
              #     allow(obj).to receive_messages(:foo => 1, :bar => 2)
         
     | 
| 
       190 
183 
     | 
    
         
             
              def replace_with(node, code)
         
     | 
| 
       191 
     | 
    
         
            -
                @actions << ReplaceWithAction.new(node, code).process
         
     | 
| 
      
 184 
     | 
    
         
            +
                @actions << ReplaceWithAction.new(node, code, adapter: @adapter).process
         
     | 
| 
       192 
185 
     | 
    
         
             
              end
         
     | 
| 
       193 
186 
     | 
    
         | 
| 
       194 
187 
     | 
    
         
             
              # Wrap source code of the ast node with prefix and suffix code.
         
     | 
| 
         @@ -209,7 +202,7 @@ class NodeMutation 
     | 
|
| 
       209 
202 
     | 
    
         
             
              #     end
         
     | 
| 
       210 
203 
     | 
    
         
             
              def wrap(node, prefix:, suffix:, newline: false)
         
     | 
| 
       211 
204 
     | 
    
         
             
                if newline
         
     | 
| 
       212 
     | 
    
         
            -
                  indentation =  
     | 
| 
      
 205 
     | 
    
         
            +
                  indentation = @adapter.get_start_loc(node).column
         
     | 
| 
       213 
206 
     | 
    
         
             
                  group do
         
     | 
| 
       214 
207 
     | 
    
         
             
                    insert node, prefix + "\n" + (' ' * indentation), at: 'beginning'
         
     | 
| 
       215 
208 
     | 
    
         
             
                    insert node, "\n" + (' ' * indentation) + suffix, at: 'end'
         
     | 
| 
         @@ -235,13 +228,13 @@ class NodeMutation 
     | 
|
| 
       235 
228 
     | 
    
         
             
              #       class Foobar
         
     | 
| 
       236 
229 
     | 
    
         
             
              #       end
         
     | 
| 
       237 
230 
     | 
    
         
             
              def indent(node)
         
     | 
| 
       238 
     | 
    
         
            -
                @actions << IndentAction.new(node).process
         
     | 
| 
      
 231 
     | 
    
         
            +
                @actions << IndentAction.new(node, adapter: @adapter).process
         
     | 
| 
       239 
232 
     | 
    
         
             
              end
         
     | 
| 
       240 
233 
     | 
    
         | 
| 
       241 
234 
     | 
    
         
             
              # No operation.
         
     | 
| 
       242 
235 
     | 
    
         
             
              # @param node [Node] ast node
         
     | 
| 
       243 
236 
     | 
    
         
             
              def noop(node)
         
     | 
| 
       244 
     | 
    
         
            -
                @actions << NoopAction.new(node).process
         
     | 
| 
      
 237 
     | 
    
         
            +
                @actions << NoopAction.new(node, adapter: @adapter).process
         
     | 
| 
       245 
238 
     | 
    
         
             
              end
         
     | 
| 
       246 
239 
     | 
    
         | 
| 
       247 
240 
     | 
    
         
             
              # group multiple actions
         
     | 
| 
         @@ -424,4 +417,15 @@ class NodeMutation 
     | 
|
| 
       424 
417 
     | 
    
         
             
              def strategy?(strategy)
         
     | 
| 
       425 
418 
     | 
    
         
             
                NodeMutation.strategy & strategy == strategy
         
     | 
| 
       426 
419 
     | 
    
         
             
              end
         
     | 
| 
      
 420 
     | 
    
         
            +
             
     | 
| 
      
 421 
     | 
    
         
            +
              def get_adapter_instance(adapter)
         
     | 
| 
      
 422 
     | 
    
         
            +
                case adapter.to_sym
         
     | 
| 
      
 423 
     | 
    
         
            +
                when :parser
         
     | 
| 
      
 424 
     | 
    
         
            +
                  ParserAdapter.new
         
     | 
| 
      
 425 
     | 
    
         
            +
                when :syntax_tree
         
     | 
| 
      
 426 
     | 
    
         
            +
                  SyntaxTreeAdapter.new
         
     | 
| 
      
 427 
     | 
    
         
            +
                else
         
     | 
| 
      
 428 
     | 
    
         
            +
                  raise InvalidAdapterError, "adapter #{adapter} is not supported"
         
     | 
| 
      
 429 
     | 
    
         
            +
                end
         
     | 
| 
      
 430 
     | 
    
         
            +
              end
         
     | 
| 
       427 
431 
     | 
    
         
             
            end
         
     | 
    
        data/sig/node_mutation.rbs
    CHANGED
    
    | 
         @@ -9,15 +9,13 @@ class NodeMutation[T] 
     | 
|
| 
       9 
9 
     | 
    
         | 
| 
       10 
10 
     | 
    
         
             
              attr_reader actions: Array[NodeMutation::Action]
         
     | 
| 
       11 
11 
     | 
    
         | 
| 
       12 
     | 
    
         
            -
              def self.configure: (options: {  
     | 
| 
       13 
     | 
    
         
            -
             
     | 
| 
       14 
     | 
    
         
            -
              def self.adapter: () -> NodeMutation::Adapter
         
     | 
| 
      
 12 
     | 
    
         
            +
              def self.configure: (options: { strategy: Integer, tab_width: Integer }) -> void
         
     | 
| 
       15 
13 
     | 
    
         | 
| 
       16 
14 
     | 
    
         
             
              def self.strategy: () -> Integer
         
     | 
| 
       17 
15 
     | 
    
         | 
| 
       18 
16 
     | 
    
         
             
              def self.tab_width: () -> Integer
         
     | 
| 
       19 
17 
     | 
    
         | 
| 
       20 
     | 
    
         
            -
              def initialize: (source: String) -> NodeMutation
         
     | 
| 
      
 18 
     | 
    
         
            +
              def initialize: (source: String, adapter: Symbol) -> NodeMutation
         
     | 
| 
       21 
19 
     | 
    
         | 
| 
       22 
20 
     | 
    
         
             
              def append: (node: T, code: String) -> void
         
     | 
| 
       23 
21 
     | 
    
         | 
    
        metadata
    CHANGED
    
    | 
         @@ -1,14 +1,14 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            --- !ruby/object:Gem::Specification
         
     | 
| 
       2 
2 
     | 
    
         
             
            name: node_mutation
         
     | 
| 
       3 
3 
     | 
    
         
             
            version: !ruby/object:Gem::Version
         
     | 
| 
       4 
     | 
    
         
            -
              version: 1. 
     | 
| 
      
 4 
     | 
    
         
            +
              version: 1.22.1
         
     | 
| 
       5 
5 
     | 
    
         
             
            platform: ruby
         
     | 
| 
       6 
6 
     | 
    
         
             
            authors:
         
     | 
| 
       7 
7 
     | 
    
         
             
            - Richard Huang
         
     | 
| 
       8 
8 
     | 
    
         
             
            autorequire:
         
     | 
| 
       9 
9 
     | 
    
         
             
            bindir: exe
         
     | 
| 
       10 
10 
     | 
    
         
             
            cert_chain: []
         
     | 
| 
       11 
     | 
    
         
            -
            date: 2023- 
     | 
| 
      
 11 
     | 
    
         
            +
            date: 2023-12-04 00:00:00.000000000 Z
         
     | 
| 
       12 
12 
     | 
    
         
             
            dependencies: []
         
     | 
| 
       13 
13 
     | 
    
         
             
            description: ast node mutation apis
         
     | 
| 
       14 
14 
     | 
    
         
             
            email:
         
     |