mutant 0.2.7 → 0.2.8
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.
- data/Changelog.md +9 -1
- data/Gemfile.devtools +5 -12
- data/LICENSE +20 -0
- data/README.md +25 -24
- data/TODO +10 -2
- data/config/flay.yml +2 -2
- data/config/flog.yml +1 -1
- data/config/site.reek +4 -2
- data/lib/mutant.rb +18 -9
- data/lib/mutant/context/scope.rb +3 -3
- data/lib/mutant/differ.rb +13 -1
- data/lib/mutant/killer.rb +1 -0
- data/lib/mutant/matcher/scope_methods.rb +16 -11
- data/lib/mutant/mutator.rb +10 -0
- data/lib/mutant/mutator/node.rb +5 -18
- data/lib/mutant/mutator/node/actual_arguments.rb +25 -0
- data/lib/mutant/mutator/node/arguments.rb +0 -155
- data/lib/mutant/mutator/node/default_arguments.rb +24 -0
- data/lib/mutant/mutator/node/formal_arguments_19.rb +40 -0
- data/lib/mutant/mutator/node/formal_arguments_19/default_mutations.rb +32 -0
- data/lib/mutant/mutator/node/formal_arguments_19/pattern_argument_expansion.rb +35 -0
- data/lib/mutant/mutator/node/formal_arguments_19/require_defaults.rb +37 -0
- data/lib/mutant/mutator/node/literal.rb +14 -0
- data/lib/mutant/mutator/node/literal/hash.rb +1 -7
- data/lib/mutant/mutator/node/pattern_arguments.rb +41 -0
- data/lib/mutant/mutator/node/pattern_variable.rb +23 -0
- data/lib/mutant/mutator/node/send.rb +76 -6
- data/lib/mutant/mutator/util.rb +0 -71
- data/lib/mutant/mutator/util/array.rb +70 -0
- data/lib/mutant/mutator/util/symbol.rb +39 -0
- data/mutant.gemspec +2 -2
- data/spec/shared/mutator_behavior.rb +3 -2
- data/spec/unit/mutant/mutator/node/define/mutation_spec.rb +12 -0
- data/spec/unit/mutant/mutator/node/send/mutation_spec.rb +24 -17
- metadata +15 -3
| @@ -1,161 +1,6 @@ | |
| 1 1 | 
             
            module Mutant
         | 
| 2 2 | 
             
              class Mutator
         | 
| 3 3 | 
             
                class Node
         | 
| 4 | 
            -
                  # Mutator for pattern arguments
         | 
| 5 | 
            -
                  class PatternVariable < self
         | 
| 6 | 
            -
             | 
| 7 | 
            -
                    handle(Rubinius::AST::PatternVariable)
         | 
| 8 | 
            -
             | 
| 9 | 
            -
                  private
         | 
| 10 | 
            -
             | 
| 11 | 
            -
                    # Emit mutations
         | 
| 12 | 
            -
                    #
         | 
| 13 | 
            -
                    # @return [undefined]
         | 
| 14 | 
            -
                    #
         | 
| 15 | 
            -
                    # @api private
         | 
| 16 | 
            -
                    #
         | 
| 17 | 
            -
                    def dispatch
         | 
| 18 | 
            -
                      emit_attribute_mutations(:name)
         | 
| 19 | 
            -
                    end
         | 
| 20 | 
            -
                  end
         | 
| 21 | 
            -
             | 
| 22 | 
            -
                  # Mutantor for default arguments
         | 
| 23 | 
            -
                  class DefaultArguments < self
         | 
| 24 | 
            -
                    handle(Rubinius::AST::DefaultArguments)
         | 
| 25 | 
            -
             | 
| 26 | 
            -
                  private
         | 
| 27 | 
            -
             | 
| 28 | 
            -
                    # Emit mutations
         | 
| 29 | 
            -
                    #
         | 
| 30 | 
            -
                    # @return [undefined]
         | 
| 31 | 
            -
                    #
         | 
| 32 | 
            -
                    # @api private
         | 
| 33 | 
            -
                    #
         | 
| 34 | 
            -
                    def dispatch
         | 
| 35 | 
            -
                      emit_attribute_mutations(:arguments) do |argument|
         | 
| 36 | 
            -
                        argument.names = argument.arguments.map(&:name)
         | 
| 37 | 
            -
                      end
         | 
| 38 | 
            -
                    end
         | 
| 39 | 
            -
                  end
         | 
| 40 | 
            -
             | 
| 41 | 
            -
                  # Mutator for pattern arguments
         | 
| 42 | 
            -
                  class PatternArguments < self
         | 
| 43 | 
            -
             | 
| 44 | 
            -
                    handle(Rubinius::AST::PatternArguments)
         | 
| 45 | 
            -
             | 
| 46 | 
            -
                  private
         | 
| 47 | 
            -
             | 
| 48 | 
            -
                    # Emit mutations
         | 
| 49 | 
            -
                    #
         | 
| 50 | 
            -
                    # @return [undefined]
         | 
| 51 | 
            -
                    #
         | 
| 52 | 
            -
                    # @api private
         | 
| 53 | 
            -
                    #
         | 
| 54 | 
            -
                    def dispatch
         | 
| 55 | 
            -
                      Mutator.each(node.arguments.body) do |mutation|
         | 
| 56 | 
            -
                        dup = dup_node
         | 
| 57 | 
            -
                        dup.arguments.body = mutation
         | 
| 58 | 
            -
                        emit(dup)
         | 
| 59 | 
            -
                      end
         | 
| 60 | 
            -
                    end
         | 
| 61 | 
            -
             | 
| 62 | 
            -
                    # Test if mutation should be skipped
         | 
| 63 | 
            -
                    #
         | 
| 64 | 
            -
                    # @return [true]
         | 
| 65 | 
            -
                    #   if mutation should be skipped
         | 
| 66 | 
            -
                    #
         | 
| 67 | 
            -
                    # @return [false]
         | 
| 68 | 
            -
                    #   otherwise
         | 
| 69 | 
            -
                    #
         | 
| 70 | 
            -
                    # @api private
         | 
| 71 | 
            -
                    #
         | 
| 72 | 
            -
                    def allow?(object)
         | 
| 73 | 
            -
                      object.arguments.body.size >= 2
         | 
| 74 | 
            -
                    end
         | 
| 75 | 
            -
                  end
         | 
| 76 | 
            -
             | 
| 77 | 
            -
                  # Mutator for formal arguments
         | 
| 78 | 
            -
                  class FormatlArguments19 < self
         | 
| 79 | 
            -
             | 
| 80 | 
            -
                  private
         | 
| 81 | 
            -
             | 
| 82 | 
            -
                    handle(Rubinius::AST::FormalArguments19)
         | 
| 83 | 
            -
             | 
| 84 | 
            -
                    # Emit mutations
         | 
| 85 | 
            -
                    #
         | 
| 86 | 
            -
                    # @return [undefined]
         | 
| 87 | 
            -
                    #
         | 
| 88 | 
            -
                    # @api private
         | 
| 89 | 
            -
                    #
         | 
| 90 | 
            -
                    def dispatch
         | 
| 91 | 
            -
                      expand_pattern_args
         | 
| 92 | 
            -
                      emit_default_mutations
         | 
| 93 | 
            -
                      emit_required_defaults_mutation
         | 
| 94 | 
            -
                      emit_attribute_mutations(:required) do |mutation|
         | 
| 95 | 
            -
                        mutation.names = mutation.optional + mutation.required
         | 
| 96 | 
            -
                      end
         | 
| 97 | 
            -
                    end
         | 
| 98 | 
            -
             | 
| 99 | 
            -
                    # Emit default mutations
         | 
| 100 | 
            -
                    #
         | 
| 101 | 
            -
                    # @return [undefined]
         | 
| 102 | 
            -
                    #
         | 
| 103 | 
            -
                    # @api private
         | 
| 104 | 
            -
                    #
         | 
| 105 | 
            -
                    def emit_default_mutations
         | 
| 106 | 
            -
                      return unless node.defaults
         | 
| 107 | 
            -
                      emit_attribute_mutations(:defaults) do |mutation|
         | 
| 108 | 
            -
                        mutation.optional = mutation.defaults.names
         | 
| 109 | 
            -
                        mutation.names = mutation.required + mutation.optional
         | 
| 110 | 
            -
                        if mutation.defaults.names.empty?
         | 
| 111 | 
            -
                          mutation.defaults = nil
         | 
| 112 | 
            -
                        end
         | 
| 113 | 
            -
                      end 
         | 
| 114 | 
            -
                    end
         | 
| 115 | 
            -
             | 
| 116 | 
            -
                    # Emit required defaults mutations
         | 
| 117 | 
            -
                    #
         | 
| 118 | 
            -
                    # @return [undefined]
         | 
| 119 | 
            -
                    #
         | 
| 120 | 
            -
                    # @api private
         | 
| 121 | 
            -
                    #
         | 
| 122 | 
            -
                    def emit_required_defaults_mutation
         | 
| 123 | 
            -
                      return unless node.defaults
         | 
| 124 | 
            -
                      arguments = node.defaults.arguments
         | 
| 125 | 
            -
                      arguments.each_index do |index|
         | 
| 126 | 
            -
                        names = arguments.take(index+1).map(&:name)
         | 
| 127 | 
            -
                        dup = dup_node
         | 
| 128 | 
            -
                        defaults = dup.defaults
         | 
| 129 | 
            -
                        defaults.arguments = defaults.arguments.drop(names.size)
         | 
| 130 | 
            -
                        names.each { |name| dup.optional.delete(name) }
         | 
| 131 | 
            -
                        dup.required.concat(names)
         | 
| 132 | 
            -
                        if dup.optional.empty?
         | 
| 133 | 
            -
                          dup.defaults = nil
         | 
| 134 | 
            -
                        end
         | 
| 135 | 
            -
                        emit(dup)
         | 
| 136 | 
            -
                      end
         | 
| 137 | 
            -
                    end
         | 
| 138 | 
            -
             | 
| 139 | 
            -
                    # Emit pattern args expansions
         | 
| 140 | 
            -
                    # 
         | 
| 141 | 
            -
                    # @return [undefined]
         | 
| 142 | 
            -
                    #
         | 
| 143 | 
            -
                    # @api private
         | 
| 144 | 
            -
                    #
         | 
| 145 | 
            -
                    def expand_pattern_args
         | 
| 146 | 
            -
                      node.required.each_with_index do |argument, index|
         | 
| 147 | 
            -
                        next unless argument.kind_of?(Rubinius::AST::PatternArguments)
         | 
| 148 | 
            -
                        dup = dup_node
         | 
| 149 | 
            -
                        required = dup.required
         | 
| 150 | 
            -
                        required.delete_at(index)
         | 
| 151 | 
            -
                        argument.arguments.body.reverse.each do |node|
         | 
| 152 | 
            -
                          required.insert(index, node.name)
         | 
| 153 | 
            -
                        end
         | 
| 154 | 
            -
                        dup.names |= required
         | 
| 155 | 
            -
                        emit(dup)
         | 
| 156 | 
            -
                      end
         | 
| 157 | 
            -
                    end
         | 
| 158 | 
            -
                  end
         | 
| 159 4 |  | 
| 160 5 | 
             
                  # Mutator for arguments
         | 
| 161 6 | 
             
                  class Arguments < self
         | 
| @@ -0,0 +1,24 @@ | |
| 1 | 
            +
            module Mutant
         | 
| 2 | 
            +
              class Mutator
         | 
| 3 | 
            +
                class Node
         | 
| 4 | 
            +
                  # Mutantor for default arguments
         | 
| 5 | 
            +
                  class DefaultArguments < self
         | 
| 6 | 
            +
                    handle(Rubinius::AST::DefaultArguments)
         | 
| 7 | 
            +
             | 
| 8 | 
            +
                  private
         | 
| 9 | 
            +
             | 
| 10 | 
            +
                    # Emit mutations
         | 
| 11 | 
            +
                    #
         | 
| 12 | 
            +
                    # @return [undefined]
         | 
| 13 | 
            +
                    #
         | 
| 14 | 
            +
                    # @api private
         | 
| 15 | 
            +
                    #
         | 
| 16 | 
            +
                    def dispatch
         | 
| 17 | 
            +
                      emit_attribute_mutations(:arguments) do |argument|
         | 
| 18 | 
            +
                        argument.names = argument.arguments.map(&:name)
         | 
| 19 | 
            +
                      end
         | 
| 20 | 
            +
                    end
         | 
| 21 | 
            +
                  end
         | 
| 22 | 
            +
                end
         | 
| 23 | 
            +
              end
         | 
| 24 | 
            +
            end
         | 
| @@ -0,0 +1,40 @@ | |
| 1 | 
            +
            module Mutant
         | 
| 2 | 
            +
              class Mutator
         | 
| 3 | 
            +
                class Node
         | 
| 4 | 
            +
             | 
| 5 | 
            +
                  # Mutator for formal arguments in 1.9 mode
         | 
| 6 | 
            +
                  class FormalArguments19 < self
         | 
| 7 | 
            +
             | 
| 8 | 
            +
                  private
         | 
| 9 | 
            +
             | 
| 10 | 
            +
                    handle(Rubinius::AST::FormalArguments19)
         | 
| 11 | 
            +
             | 
| 12 | 
            +
                    # Emit mutations
         | 
| 13 | 
            +
                    #
         | 
| 14 | 
            +
                    # @return [undefined]
         | 
| 15 | 
            +
                    #
         | 
| 16 | 
            +
                    # @api private
         | 
| 17 | 
            +
                    #
         | 
| 18 | 
            +
                    def dispatch
         | 
| 19 | 
            +
                      run(DefaultMutations)
         | 
| 20 | 
            +
                      run(RequireDefaults)
         | 
| 21 | 
            +
                      run(PatternArgumentExpansion)
         | 
| 22 | 
            +
                      emit_required_mutations
         | 
| 23 | 
            +
                    end
         | 
| 24 | 
            +
             | 
| 25 | 
            +
             | 
| 26 | 
            +
                    # Emit required mutations
         | 
| 27 | 
            +
                    #
         | 
| 28 | 
            +
                    # @return [undefined]
         | 
| 29 | 
            +
                    #
         | 
| 30 | 
            +
                    # @api private
         | 
| 31 | 
            +
                    #
         | 
| 32 | 
            +
                    def emit_required_mutations
         | 
| 33 | 
            +
                      emit_attribute_mutations(:required) do |mutation|
         | 
| 34 | 
            +
                        mutation.names = mutation.optional + mutation.required
         | 
| 35 | 
            +
                      end
         | 
| 36 | 
            +
                    end
         | 
| 37 | 
            +
                  end
         | 
| 38 | 
            +
                end
         | 
| 39 | 
            +
              end
         | 
| 40 | 
            +
            end
         | 
| @@ -0,0 +1,32 @@ | |
| 1 | 
            +
            module Mutant
         | 
| 2 | 
            +
              class Mutator
         | 
| 3 | 
            +
                class Node
         | 
| 4 | 
            +
                  class FormalArguments19
         | 
| 5 | 
            +
             | 
| 6 | 
            +
                    # Mutator for default argument values
         | 
| 7 | 
            +
                    class DefaultMutations < Node
         | 
| 8 | 
            +
             | 
| 9 | 
            +
                    private
         | 
| 10 | 
            +
             | 
| 11 | 
            +
                      # Emit mutations
         | 
| 12 | 
            +
                      #
         | 
| 13 | 
            +
                      # @return [undefined]
         | 
| 14 | 
            +
                      #
         | 
| 15 | 
            +
                      # @api private
         | 
| 16 | 
            +
                      #
         | 
| 17 | 
            +
                      def dispatch
         | 
| 18 | 
            +
                        return unless node.defaults
         | 
| 19 | 
            +
                        emit_attribute_mutations(:defaults) do |mutation|
         | 
| 20 | 
            +
                          mutation.optional = mutation.defaults.names
         | 
| 21 | 
            +
                          mutation.names = mutation.required + mutation.optional
         | 
| 22 | 
            +
                          if mutation.defaults.names.empty?
         | 
| 23 | 
            +
                            mutation.defaults = nil
         | 
| 24 | 
            +
                          end
         | 
| 25 | 
            +
                        end 
         | 
| 26 | 
            +
                      end
         | 
| 27 | 
            +
             | 
| 28 | 
            +
                    end
         | 
| 29 | 
            +
                  end
         | 
| 30 | 
            +
                end
         | 
| 31 | 
            +
              end
         | 
| 32 | 
            +
            end
         | 
| @@ -0,0 +1,35 @@ | |
| 1 | 
            +
            module Mutant
         | 
| 2 | 
            +
              class Mutator
         | 
| 3 | 
            +
                class Node
         | 
| 4 | 
            +
                  class FormalArguments19
         | 
| 5 | 
            +
             | 
| 6 | 
            +
                    # Mutator that expands pattern arguments
         | 
| 7 | 
            +
                    class PatternArgumentExpansion < Node
         | 
| 8 | 
            +
             | 
| 9 | 
            +
                    private
         | 
| 10 | 
            +
             | 
| 11 | 
            +
                      # Emit mutations
         | 
| 12 | 
            +
                      #
         | 
| 13 | 
            +
                      # @return [undefined]
         | 
| 14 | 
            +
                      #
         | 
| 15 | 
            +
                      # @api private
         | 
| 16 | 
            +
                      #
         | 
| 17 | 
            +
                      def dispatch
         | 
| 18 | 
            +
                        node.required.each_with_index do |argument, index|
         | 
| 19 | 
            +
                          next unless argument.kind_of?(Rubinius::AST::PatternArguments)
         | 
| 20 | 
            +
                          dup = dup_node
         | 
| 21 | 
            +
                          required = dup.required
         | 
| 22 | 
            +
                          required.delete_at(index)
         | 
| 23 | 
            +
                          argument.arguments.body.reverse.each do |node|
         | 
| 24 | 
            +
                            required.insert(index, node.name)
         | 
| 25 | 
            +
                          end
         | 
| 26 | 
            +
                          dup.names |= required
         | 
| 27 | 
            +
                          emit(dup)
         | 
| 28 | 
            +
                        end
         | 
| 29 | 
            +
                      end
         | 
| 30 | 
            +
             | 
| 31 | 
            +
                    end
         | 
| 32 | 
            +
                  end
         | 
| 33 | 
            +
                end
         | 
| 34 | 
            +
              end
         | 
| 35 | 
            +
            end
         | 
| @@ -0,0 +1,37 @@ | |
| 1 | 
            +
            module Mutant
         | 
| 2 | 
            +
              class Mutator
         | 
| 3 | 
            +
                class Node
         | 
| 4 | 
            +
                  class FormalArguments19
         | 
| 5 | 
            +
             | 
| 6 | 
            +
                    # Mutator for removing defaults and transform them into required arguments
         | 
| 7 | 
            +
                    class RequireDefaults < Node
         | 
| 8 | 
            +
             | 
| 9 | 
            +
                    private
         | 
| 10 | 
            +
             | 
| 11 | 
            +
                      # Emit mutants
         | 
| 12 | 
            +
                      #
         | 
| 13 | 
            +
                      # @return [undefined]
         | 
| 14 | 
            +
                      #
         | 
| 15 | 
            +
                      # @api private
         | 
| 16 | 
            +
                      #
         | 
| 17 | 
            +
                      def dispatch
         | 
| 18 | 
            +
                        return unless node.defaults
         | 
| 19 | 
            +
                        arguments = node.defaults.arguments
         | 
| 20 | 
            +
                        arguments.each_index do |index|
         | 
| 21 | 
            +
                          names = arguments.take(index+1).map(&:name)
         | 
| 22 | 
            +
                          dup = dup_node
         | 
| 23 | 
            +
                          defaults = dup.defaults
         | 
| 24 | 
            +
                          defaults.arguments = defaults.arguments.drop(names.size)
         | 
| 25 | 
            +
                          names.each { |name| dup.optional.delete(name) }
         | 
| 26 | 
            +
                          dup.required.concat(names)
         | 
| 27 | 
            +
                          if dup.optional.empty?
         | 
| 28 | 
            +
                            dup.defaults = nil
         | 
| 29 | 
            +
                          end
         | 
| 30 | 
            +
                          emit(dup)
         | 
| 31 | 
            +
                        end
         | 
| 32 | 
            +
                      end
         | 
| 33 | 
            +
                    end
         | 
| 34 | 
            +
                  end
         | 
| 35 | 
            +
                end
         | 
| 36 | 
            +
              end
         | 
| 37 | 
            +
            end
         | 
| @@ -19,6 +19,20 @@ module Mutant | |
| 19 19 | 
             
                      new(Rubinius::AST::FloatLiteral, value)
         | 
| 20 20 | 
             
                    end
         | 
| 21 21 |  | 
| 22 | 
            +
                    # Emit a new node with wrapping class for each entry in values
         | 
| 23 | 
            +
                    #
         | 
| 24 | 
            +
                    # @param [Array] values
         | 
| 25 | 
            +
                    #
         | 
| 26 | 
            +
                    # @return [undefined]
         | 
| 27 | 
            +
                    #
         | 
| 28 | 
            +
                    # @api private
         | 
| 29 | 
            +
                    #
         | 
| 30 | 
            +
                    def emit_values(values)
         | 
| 31 | 
            +
                      values.each do |value|
         | 
| 32 | 
            +
                        emit_self(value)
         | 
| 33 | 
            +
                      end
         | 
| 34 | 
            +
                    end
         | 
| 35 | 
            +
             | 
| 22 36 | 
             
                    # Return AST representing NaN
         | 
| 23 37 | 
             
                    #
         | 
| 24 38 | 
             
                    # @return [Rubinius::Node::AST]
         | 
| @@ -29,13 +29,7 @@ module Mutant | |
| 29 29 | 
             
                      # @api private
         | 
| 30 30 | 
             
                      #
         | 
| 31 31 | 
             
                      def emit_body
         | 
| 32 | 
            -
                        array | 
| 33 | 
            -
                          dup = dup_array
         | 
| 34 | 
            -
                          Mutator.each(element).each do |mutation|
         | 
| 35 | 
            -
                            dup[index]=mutation
         | 
| 36 | 
            -
                            emit_self(dup)
         | 
| 37 | 
            -
                          end
         | 
| 38 | 
            -
                        end
         | 
| 32 | 
            +
                        emit_attribute_mutations(:array, Mutator::Util::Array::Element)
         | 
| 39 33 | 
             
                      end
         | 
| 40 34 |  | 
| 41 35 | 
             
                      # Return array of values in literal
         | 
| @@ -0,0 +1,41 @@ | |
| 1 | 
            +
            module Mutant
         | 
| 2 | 
            +
              class Mutator
         | 
| 3 | 
            +
                class Node
         | 
| 4 | 
            +
                  # Mutator for pattern arguments
         | 
| 5 | 
            +
                  class PatternArguments < self
         | 
| 6 | 
            +
             | 
| 7 | 
            +
                    handle(Rubinius::AST::PatternArguments)
         | 
| 8 | 
            +
             | 
| 9 | 
            +
                  private
         | 
| 10 | 
            +
             | 
| 11 | 
            +
                    # Emit mutations
         | 
| 12 | 
            +
                    #
         | 
| 13 | 
            +
                    # @return [undefined]
         | 
| 14 | 
            +
                    #
         | 
| 15 | 
            +
                    # @api private
         | 
| 16 | 
            +
                    #
         | 
| 17 | 
            +
                    def dispatch
         | 
| 18 | 
            +
                      Mutator.each(node.arguments.body) do |mutation|
         | 
| 19 | 
            +
                        dup = dup_node
         | 
| 20 | 
            +
                        dup.arguments.body = mutation
         | 
| 21 | 
            +
                        emit(dup)
         | 
| 22 | 
            +
                      end
         | 
| 23 | 
            +
                    end
         | 
| 24 | 
            +
             | 
| 25 | 
            +
                    # Test if mutation should be skipped
         | 
| 26 | 
            +
                    #
         | 
| 27 | 
            +
                    # @return [true]
         | 
| 28 | 
            +
                    #   if mutation should be skipped
         | 
| 29 | 
            +
                    #
         | 
| 30 | 
            +
                    # @return [false]
         | 
| 31 | 
            +
                    #   otherwise
         | 
| 32 | 
            +
                    #
         | 
| 33 | 
            +
                    # @api private
         | 
| 34 | 
            +
                    #
         | 
| 35 | 
            +
                    def allow?(object)
         | 
| 36 | 
            +
                      object.arguments.body.size >= 2
         | 
| 37 | 
            +
                    end
         | 
| 38 | 
            +
                  end
         | 
| 39 | 
            +
                end
         | 
| 40 | 
            +
              end
         | 
| 41 | 
            +
            end
         | 
| @@ -0,0 +1,23 @@ | |
| 1 | 
            +
            module Mutant
         | 
| 2 | 
            +
              class Mutator
         | 
| 3 | 
            +
                class Node
         | 
| 4 | 
            +
                  # Mutator for pattern variable
         | 
| 5 | 
            +
                  class PatternVariable < self
         | 
| 6 | 
            +
             | 
| 7 | 
            +
                    handle(Rubinius::AST::PatternVariable)
         | 
| 8 | 
            +
             | 
| 9 | 
            +
                  private
         | 
| 10 | 
            +
             | 
| 11 | 
            +
                    # Emit mutations
         | 
| 12 | 
            +
                    #
         | 
| 13 | 
            +
                    # @return [undefined]
         | 
| 14 | 
            +
                    #
         | 
| 15 | 
            +
                    # @api private
         | 
| 16 | 
            +
                    #
         | 
| 17 | 
            +
                    def dispatch
         | 
| 18 | 
            +
                      emit_attribute_mutations(:name)
         | 
| 19 | 
            +
                    end
         | 
| 20 | 
            +
                  end
         | 
| 21 | 
            +
                end
         | 
| 22 | 
            +
              end
         | 
| 23 | 
            +
            end
         | 
| @@ -6,6 +6,24 @@ module Mutant | |
| 6 6 |  | 
| 7 7 | 
             
                    handle(Rubinius::AST::Send)
         | 
| 8 8 |  | 
| 9 | 
            +
                    # Test if node corresponds to "self.class"
         | 
| 10 | 
            +
                    #
         | 
| 11 | 
            +
                    # @param [Rubinius::AST::Node] node
         | 
| 12 | 
            +
                    #
         | 
| 13 | 
            +
                    # @return [true]
         | 
| 14 | 
            +
                    #   if node equals to self.class
         | 
| 15 | 
            +
                    #
         | 
| 16 | 
            +
                    # @return [false]
         | 
| 17 | 
            +
                    #   otherwise
         | 
| 18 | 
            +
                    #
         | 
| 19 | 
            +
                    # @api private
         | 
| 20 | 
            +
                    #
         | 
| 21 | 
            +
                    def self.self_class?(node)
         | 
| 22 | 
            +
                      node.kind_of?(Rubinius::AST::Send) && 
         | 
| 23 | 
            +
                      node.name == :class                && 
         | 
| 24 | 
            +
                      node.receiver.kind_of?(Rubinius::AST::Self)
         | 
| 25 | 
            +
                    end
         | 
| 26 | 
            +
             | 
| 9 27 | 
             
                  private
         | 
| 10 28 |  | 
| 11 29 | 
             
                    # Emit mutations
         | 
| @@ -15,11 +33,51 @@ module Mutant | |
| 15 33 | 
             
                    # @api private
         | 
| 16 34 | 
             
                    #
         | 
| 17 35 | 
             
                    def dispatch
         | 
| 36 | 
            +
                      emit_receiver 
         | 
| 18 37 | 
             
                      emit_implicit_self_receiver
         | 
| 19 | 
            -
                       | 
| 38 | 
            +
                      emit_receiver_mutations
         | 
| 39 | 
            +
                      emit_block_mutations
         | 
| 20 40 | 
             
                      emit_block_absence_mutation
         | 
| 21 41 | 
             
                    end
         | 
| 22 42 |  | 
| 43 | 
            +
                    # Emit receiver 
         | 
| 44 | 
            +
                    #
         | 
| 45 | 
            +
                    # @return [undefined]
         | 
| 46 | 
            +
                    #
         | 
| 47 | 
            +
                    # @api private
         | 
| 48 | 
            +
                    #
         | 
| 49 | 
            +
                    def emit_receiver
         | 
| 50 | 
            +
                      unless to_self?
         | 
| 51 | 
            +
                        emit(receiver)
         | 
| 52 | 
            +
                      end
         | 
| 53 | 
            +
                    end
         | 
| 54 | 
            +
             | 
| 55 | 
            +
                    # Emit block mutations
         | 
| 56 | 
            +
                    #
         | 
| 57 | 
            +
                    # @return [undefined]
         | 
| 58 | 
            +
                    #
         | 
| 59 | 
            +
                    # @api private
         | 
| 60 | 
            +
                    #
         | 
| 61 | 
            +
                    def emit_block_mutations
         | 
| 62 | 
            +
                      if node.block
         | 
| 63 | 
            +
                        emit_attribute_mutations(:block) 
         | 
| 64 | 
            +
                      end
         | 
| 65 | 
            +
                    end
         | 
| 66 | 
            +
             | 
| 67 | 
            +
                    # Emit receiver mutations
         | 
| 68 | 
            +
                    #
         | 
| 69 | 
            +
                    # @return [undefined]
         | 
| 70 | 
            +
                    #
         | 
| 71 | 
            +
                    # @api private
         | 
| 72 | 
            +
                    #
         | 
| 73 | 
            +
                    def emit_receiver_mutations
         | 
| 74 | 
            +
                      util = self.class
         | 
| 75 | 
            +
             | 
| 76 | 
            +
                      unless to_self? or util.self_class?(receiver) 
         | 
| 77 | 
            +
                        emit_attribute_mutations(:receiver) 
         | 
| 78 | 
            +
                      end
         | 
| 79 | 
            +
                    end
         | 
| 80 | 
            +
             | 
| 23 81 | 
             
                    # Emit block absence mutation
         | 
| 24 82 | 
             
                    #
         | 
| 25 83 | 
             
                    # @return [undefined]
         | 
| @@ -55,14 +113,14 @@ module Mutant | |
| 55 113 | 
             
                    # Check if receiver is self
         | 
| 56 114 | 
             
                    #
         | 
| 57 115 | 
             
                    # @return [true]
         | 
| 58 | 
            -
                    #    | 
| 116 | 
            +
                    #   if receiver is a Rubinius::AST::Self node
         | 
| 59 117 | 
             
                    #
         | 
| 60 118 | 
             
                    # @return [false]
         | 
| 61 119 | 
             
                    #   return false otherwise
         | 
| 62 120 | 
             
                    #
         | 
| 63 121 | 
             
                    # @api private
         | 
| 64 122 | 
             
                    #
         | 
| 65 | 
            -
                    def  | 
| 123 | 
            +
                    def to_self?
         | 
| 66 124 | 
             
                      receiver.kind_of?(Rubinius::AST::Self)
         | 
| 67 125 | 
             
                    end
         | 
| 68 126 |  | 
| @@ -92,9 +150,8 @@ module Mutant | |
| 92 150 | 
             
                    # @api private
         | 
| 93 151 | 
             
                    #
         | 
| 94 152 | 
             
                    def emit_implicit_self_receiver
         | 
| 95 | 
            -
                       | 
| 96 | 
            -
                      return if  | 
| 97 | 
            -
                      return unless self?
         | 
| 153 | 
            +
                      return unless to_self? 
         | 
| 154 | 
            +
                      return if self.class.self_class?(node)
         | 
| 98 155 | 
             
                      mutant = dup_node
         | 
| 99 156 | 
             
                      mutant.privately = true
         | 
| 100 157 | 
             
                      # TODO: Fix rubinius to allow this as an attr_accessor
         | 
| @@ -116,9 +173,22 @@ module Mutant | |
| 116 173 | 
             
                      #
         | 
| 117 174 | 
             
                      def dispatch
         | 
| 118 175 | 
             
                        super
         | 
| 176 | 
            +
                        emit_call_remove_mutation
         | 
| 119 177 | 
             
                        emit_attribute_mutations(:arguments)
         | 
| 120 178 | 
             
                      end
         | 
| 121 179 |  | 
| 180 | 
            +
                      # Emit transfomr call mutation
         | 
| 181 | 
            +
                      #
         | 
| 182 | 
            +
                      # @return [undefined]
         | 
| 183 | 
            +
                      #
         | 
| 184 | 
            +
                      # @api private
         | 
| 185 | 
            +
                      #
         | 
| 186 | 
            +
                      def emit_call_remove_mutation
         | 
| 187 | 
            +
                        array = node.arguments.array
         | 
| 188 | 
            +
                        return unless array.length == 1
         | 
| 189 | 
            +
                        emit(array.first)
         | 
| 190 | 
            +
                      end
         | 
| 191 | 
            +
             | 
| 122 192 | 
             
                    end
         | 
| 123 193 | 
             
                  end
         | 
| 124 194 | 
             
                end
         |