mutant 0.11.13 → 0.11.14
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/lib/mutant/ast/find_metaclass_containing.rb +6 -6
- data/lib/mutant/ast/meta/const.rb +1 -1
- data/lib/mutant/ast/meta/optarg.rb +1 -1
- data/lib/mutant/ast/meta/resbody.rb +1 -1
- data/lib/mutant/ast/meta/send.rb +1 -1
- data/lib/mutant/ast/meta/symbol.rb +1 -1
- data/lib/mutant/ast/meta.rb +1 -1
- data/lib/mutant/ast/named_children.rb +1 -1
- data/lib/mutant/ast/node_predicates.rb +1 -1
- data/lib/mutant/ast/nodes.rb +1 -1
- data/lib/mutant/ast/pattern/lexer.rb +1 -1
- data/lib/mutant/ast/pattern/parser.rb +1 -1
- data/lib/mutant/ast/pattern/source.rb +1 -1
- data/lib/mutant/ast/pattern/token.rb +1 -1
- data/lib/mutant/ast/pattern.rb +1 -1
- data/lib/mutant/ast/regexp/transformer/direct.rb +1 -1
- data/lib/mutant/ast/regexp/transformer/named_group.rb +1 -1
- data/lib/mutant/ast/regexp/transformer/options_group.rb +1 -1
- data/lib/mutant/ast/regexp/transformer/quantifier.rb +1 -1
- data/lib/mutant/ast/regexp/transformer/recursive.rb +1 -1
- data/lib/mutant/ast/regexp/transformer/root.rb +1 -1
- data/lib/mutant/ast/regexp/transformer/text.rb +1 -1
- data/lib/mutant/ast/regexp/transformer.rb +1 -1
- data/lib/mutant/ast/regexp.rb +1 -1
- data/lib/mutant/ast/sexp.rb +1 -1
- data/lib/mutant/ast/structure.rb +8 -3
- data/lib/mutant/ast/types.rb +1 -1
- data/lib/mutant/ast.rb +31 -29
- data/lib/mutant/config.rb +1 -1
- data/lib/mutant/matcher/method/instance.rb +3 -2
- data/lib/mutant/matcher/method/metaclass.rb +4 -3
- data/lib/mutant/matcher/method/singleton.rb +3 -2
- data/lib/mutant/matcher/method.rb +32 -23
- data/lib/mutant/mutator/node/block.rb +5 -3
- data/lib/mutant/parser.rb +0 -7
- data/lib/mutant/version.rb +1 -1
- metadata +3 -3
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA256:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: 58b6affbd17beee4a525b5efa35e83b18d3d65316ec5abd2b773c4722377e79b
         | 
| 4 | 
            +
              data.tar.gz: 10b60ffd99ea8b477537bed09af2c122ffc14152a69c9a020ed09cca73dfa2d8
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: 39bd2f27290e3e3ba1ec6be8ae515759db5970fe121e9732797819bcb243c1038b0582c49e52fe7c6ab99d9332dfce4eb4fcf62b75558bd79954929bb432a8fd
         | 
| 7 | 
            +
              data.tar.gz: da7555f1f168b6359163aeb3cd58dd69b5cb553da005830169cabdc9de949317f7ddae0790e6e84cc7990dfcd3d7c0c2c9b85f05c0b7b8de18bf96079d2c58e7
         | 
| @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            # frozen_string_literal: true
         | 
| 2 2 |  | 
| 3 3 | 
             
            module Mutant
         | 
| 4 | 
            -
               | 
| 4 | 
            +
              class AST
         | 
| 5 5 | 
             
                # Given an AST, finds the sclass that directly(-ish) contains the provided
         | 
| 6 6 | 
             
                # node.
         | 
| 7 7 | 
             
                # This won't match arbitrarily complex structures - it only searches the
         | 
| @@ -10,7 +10,7 @@ module Mutant | |
| 10 10 | 
             
                # Descending into 'begin' nodes is supported because these are generated for
         | 
| 11 11 | 
             
                # the one-line syntax class << self; def foo; end
         | 
| 12 12 | 
             
                class FindMetaclassContaining
         | 
| 13 | 
            -
                  include NodePredicates, Concord.new(: | 
| 13 | 
            +
                  include NodePredicates, Concord.new(:ast, :target), Procto
         | 
| 14 14 |  | 
| 15 15 | 
             
                  SCLASS_BODY_INDEX = 1
         | 
| 16 16 |  | 
| @@ -22,11 +22,11 @@ module Mutant | |
| 22 22 | 
             
                  #
         | 
| 23 23 | 
             
                  # @api private
         | 
| 24 24 | 
             
                  def call
         | 
| 25 | 
            -
                     | 
| 26 | 
            -
                       | 
| 25 | 
            +
                    Structure.for(ast.node.type).each_node(ast.node) do |current|
         | 
| 26 | 
            +
                      return current if n_sclass?(current) && metaclass_of?(current)
         | 
| 27 | 
            +
                    end
         | 
| 27 28 |  | 
| 28 | 
            -
             | 
| 29 | 
            -
                    end.last
         | 
| 29 | 
            +
                    nil
         | 
| 30 30 | 
             
                  end
         | 
| 31 31 |  | 
| 32 32 | 
             
                private
         | 
    
        data/lib/mutant/ast/meta/send.rb
    CHANGED
    
    
    
        data/lib/mutant/ast/meta.rb
    CHANGED
    
    
    
        data/lib/mutant/ast/nodes.rb
    CHANGED
    
    
    
        data/lib/mutant/ast/pattern.rb
    CHANGED
    
    
    
        data/lib/mutant/ast/regexp.rb
    CHANGED
    
    
    
        data/lib/mutant/ast/sexp.rb
    CHANGED
    
    
    
        data/lib/mutant/ast/structure.rb
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            # frozen_string_literal: true
         | 
| 2 2 |  | 
| 3 3 | 
             
            module Mutant
         | 
| 4 | 
            -
               | 
| 4 | 
            +
              class AST
         | 
| 5 5 | 
             
                # AST Structure metadata
         | 
| 6 6 | 
             
                # rubocop:disable Metrics/ModuleLength
         | 
| 7 7 | 
             
                module Structure
         | 
| @@ -26,7 +26,7 @@ module Mutant | |
| 26 26 | 
             
                      end
         | 
| 27 27 |  | 
| 28 28 | 
             
                      def value(node)
         | 
| 29 | 
            -
                        node.children. | 
| 29 | 
            +
                        node.children.at(index)
         | 
| 30 30 | 
             
                      end
         | 
| 31 31 | 
             
                    end
         | 
| 32 32 |  | 
| @@ -246,7 +246,7 @@ module Mutant | |
| 246 246 | 
             
                      type:     :class,
         | 
| 247 247 | 
             
                      fixed:    Node.fixed(
         | 
| 248 248 | 
             
                        [
         | 
| 249 | 
            -
                          [Node::Fixed:: | 
| 249 | 
            +
                          [Node::Fixed::Attribute, :name],
         | 
| 250 250 | 
             
                          [Node::Fixed::Descendant, :superclass],
         | 
| 251 251 | 
             
                          [Node::Fixed::Descendant, :body]
         | 
| 252 252 | 
             
                        ]
         | 
| @@ -386,6 +386,11 @@ module Mutant | |
| 386 386 | 
             
                      fixed:    Node.fixed([[Node::Fixed::Attribute, :value]]),
         | 
| 387 387 | 
             
                      variable: nil
         | 
| 388 388 | 
             
                    ),
         | 
| 389 | 
            +
                    Node.new(
         | 
| 390 | 
            +
                      type:     :forwarded_args,
         | 
| 391 | 
            +
                      fixed:    EMPTY_ARRAY,
         | 
| 392 | 
            +
                      variable: nil
         | 
| 393 | 
            +
                    ),
         | 
| 389 394 | 
             
                    Node.new(
         | 
| 390 395 | 
             
                      type:     :for,
         | 
| 391 396 | 
             
                      fixed:    Node.fixed(
         | 
    
        data/lib/mutant/ast/types.rb
    CHANGED
    
    
    
        data/lib/mutant/ast.rb
    CHANGED
    
    | @@ -1,41 +1,43 @@ | |
| 1 1 | 
             
            # frozen_string_literal: true
         | 
| 2 2 |  | 
| 3 3 | 
             
            module Mutant
         | 
| 4 | 
            -
               | 
| 5 | 
            -
             | 
| 6 | 
            -
             | 
| 7 | 
            -
             | 
| 8 | 
            -
                 | 
| 9 | 
            -
             | 
| 10 | 
            -
                 | 
| 11 | 
            -
             | 
| 12 | 
            -
                 | 
| 13 | 
            -
             | 
| 14 | 
            -
                 | 
| 15 | 
            -
             | 
| 16 | 
            -
             | 
| 17 | 
            -
             | 
| 18 | 
            -
                 | 
| 19 | 
            -
             | 
| 20 | 
            -
             | 
| 21 | 
            -
             | 
| 22 | 
            -
             | 
| 23 | 
            -
             | 
| 24 | 
            -
             | 
| 25 | 
            -
             | 
| 4 | 
            +
              class AST
         | 
| 5 | 
            +
                include Adamantium, Anima.new(
         | 
| 6 | 
            +
                  :node,
         | 
| 7 | 
            +
                  :comment_associations
         | 
| 8 | 
            +
                )
         | 
| 9 | 
            +
             | 
| 10 | 
            +
                class View
         | 
| 11 | 
            +
                  include Adamantium, Anima.new(:node, :path)
         | 
| 12 | 
            +
                end
         | 
| 13 | 
            +
             | 
| 14 | 
            +
                def on_line(line)
         | 
| 15 | 
            +
                  line_map.fetch(line, EMPTY_HASH).map do |node, path|
         | 
| 16 | 
            +
                    View.new(node: node, path: path)
         | 
| 17 | 
            +
                  end
         | 
| 18 | 
            +
                end
         | 
| 19 | 
            +
             | 
| 20 | 
            +
              private
         | 
| 21 | 
            +
             | 
| 22 | 
            +
                def line_map
         | 
| 23 | 
            +
                  line_map = {}
         | 
| 24 | 
            +
             | 
| 25 | 
            +
                  walk_path(node) do |node, path|
         | 
| 26 | 
            +
                    expression = node.location.expression || next
         | 
| 27 | 
            +
                    (line_map[expression.line] ||= []) << [node, path]
         | 
| 26 28 | 
             
                  end
         | 
| 27 | 
            -
             | 
| 29 | 
            +
             | 
| 30 | 
            +
                  line_map
         | 
| 28 31 | 
             
                end
         | 
| 32 | 
            +
                memoize :line_map
         | 
| 29 33 |  | 
| 30 | 
            -
                def  | 
| 31 | 
            -
                  block.call(node, stack)
         | 
| 34 | 
            +
                def walk_path(node, stack = [node.type], &block)
         | 
| 35 | 
            +
                  block.call(node, stack.dup)
         | 
| 32 36 | 
             
                  node.children.grep(::Parser::AST::Node) do |child|
         | 
| 33 | 
            -
                    stack.push(child)
         | 
| 34 | 
            -
                     | 
| 37 | 
            +
                    stack.push(child.type)
         | 
| 38 | 
            +
                    walk_path(child, stack, &block)
         | 
| 35 39 | 
             
                    stack.pop
         | 
| 36 40 | 
             
                  end
         | 
| 37 41 | 
             
                end
         | 
| 38 | 
            -
                private_class_method :walk
         | 
| 39 | 
            -
             | 
| 40 42 | 
             
              end # AST
         | 
| 41 43 | 
             
            end # Mutant
         | 
    
        data/lib/mutant/config.rb
    CHANGED
    
    | @@ -42,7 +42,7 @@ module Mutant | |
| 42 42 | 
             
                MUTATION_TIMEOUT_DEPRECATION = <<~'MESSAGE'
         | 
| 43 43 | 
             
                  Deprecated configuration toplevel key `mutation_timeout` found.
         | 
| 44 44 |  | 
| 45 | 
            -
                  This key will be removed in the next  | 
| 45 | 
            +
                  This key will be removed in the next major version.
         | 
| 46 46 | 
             
                  Instead place your mutation timeout configuration under the `mutation` key
         | 
| 47 47 | 
             
                  like this:
         | 
| 48 48 |  | 
| @@ -30,8 +30,9 @@ module Mutant | |
| 30 30 |  | 
| 31 31 | 
             
                    # Instance method specific evaluator
         | 
| 32 32 | 
             
                    class Evaluator < Evaluator
         | 
| 33 | 
            -
                       | 
| 34 | 
            -
                      NAME_INDEX | 
| 33 | 
            +
                      MATCH_NODE_TYPE = :def
         | 
| 34 | 
            +
                      NAME_INDEX      = 0
         | 
| 35 | 
            +
                      SUBJECT_CLASS   = Subject::Method::Instance
         | 
| 35 36 |  | 
| 36 37 | 
             
                    private
         | 
| 37 38 |  | 
| @@ -22,10 +22,11 @@ module Mutant | |
| 22 22 | 
             
                    # Metaclass method evaluator
         | 
| 23 23 | 
             
                    class Evaluator < Evaluator
         | 
| 24 24 | 
             
                      # Terminology note: the "receiver" is the `self` in `class << self`
         | 
| 25 | 
            -
                      SUBJECT_CLASS         = Subject::Method::Metaclass
         | 
| 26 | 
            -
                      NAME_INDEX            = 0
         | 
| 27 25 | 
             
                      CONST_NAME_INDEX      = 1
         | 
| 26 | 
            +
                      MATCH_NODE_TYPE       = :def
         | 
| 27 | 
            +
                      NAME_INDEX            = 0
         | 
| 28 28 | 
             
                      SCLASS_RECEIVER_INDEX = 0
         | 
| 29 | 
            +
                      SUBJECT_CLASS         = Subject::Method::Metaclass
         | 
| 29 30 | 
             
                      RECEIVER_WARNING      = 'Can only match :def inside :sclass on ' \
         | 
| 30 31 | 
             
                                              ':self or :const, got :sclass on %p ' \
         | 
| 31 32 | 
             
                                              'unable to match'
         | 
| @@ -45,7 +46,7 @@ module Mutant | |
| 45 46 | 
             
                      end
         | 
| 46 47 |  | 
| 47 48 | 
             
                      def metaclass_containing(node)
         | 
| 48 | 
            -
                        AST::FindMetaclassContaining.call(ast | 
| 49 | 
            +
                        AST::FindMetaclassContaining.call(ast, node)
         | 
| 49 50 | 
             
                      end
         | 
| 50 51 |  | 
| 51 52 | 
             
                      def line?(node)
         | 
| @@ -18,10 +18,11 @@ module Mutant | |
| 18 18 |  | 
| 19 19 | 
             
                    # Singleton method evaluator
         | 
| 20 20 | 
             
                    class Evaluator < Evaluator
         | 
| 21 | 
            -
                       | 
| 22 | 
            -
                      RECEIVER_INDEX   = 0
         | 
| 21 | 
            +
                      MATCH_NODE_TYPE  = :defs
         | 
| 23 22 | 
             
                      NAME_INDEX       = 1
         | 
| 23 | 
            +
                      RECEIVER_INDEX   = 0
         | 
| 24 24 | 
             
                      RECEIVER_WARNING = 'Can only match :defs on :self or :const got %p unable to match'
         | 
| 25 | 
            +
                      SUBJECT_CLASS    = Subject::Method::Singleton
         | 
| 25 26 |  | 
| 26 27 | 
             
                    private
         | 
| 27 28 |  | 
| @@ -41,23 +41,38 @@ module Mutant | |
| 41 41 | 
             
                    #
         | 
| 42 42 | 
             
                    # @return [Enumerable<Subject>]
         | 
| 43 43 | 
             
                    def call
         | 
| 44 | 
            -
                       | 
| 44 | 
            +
                      location = source_location
         | 
| 45 | 
            +
             | 
| 46 | 
            +
                      if location.nil? || !location.first.end_with?('.rb')
         | 
| 47 | 
            +
                        env.warn(SOURCE_LOCATION_WARNING_FORMAT % target_method)
         | 
| 45 48 |  | 
| 46 | 
            -
             | 
| 49 | 
            +
                        return EMPTY_ARRAY
         | 
| 50 | 
            +
                      end
         | 
| 51 | 
            +
             | 
| 52 | 
            +
                      match_view
         | 
| 47 53 | 
             
                    end
         | 
| 48 54 |  | 
| 49 55 | 
             
                  private
         | 
| 50 56 |  | 
| 51 | 
            -
                    def  | 
| 52 | 
            -
                       | 
| 53 | 
            -
             | 
| 54 | 
            -
                      file = location&.first
         | 
| 57 | 
            +
                    def match_view
         | 
| 58 | 
            +
                      return EMPTY_ARRAY if matched_view.nil?
         | 
| 55 59 |  | 
| 56 | 
            -
                      if  | 
| 57 | 
            -
                        env.warn(SOURCE_LOCATION_WARNING_FORMAT % target_method)
         | 
| 58 | 
            -
                      elsif matched_node_path.any?(&method(:n_block?))
         | 
| 60 | 
            +
                      if matched_view.path.any?(&:block.public_method(:equal?))
         | 
| 59 61 | 
             
                        env.warn(CLOSURE_WARNING_FORMAT % target_method)
         | 
| 62 | 
            +
             | 
| 63 | 
            +
                        return EMPTY_ARRAY
         | 
| 60 64 | 
             
                      end
         | 
| 65 | 
            +
             | 
| 66 | 
            +
                      [subject]
         | 
| 67 | 
            +
                    end
         | 
| 68 | 
            +
             | 
| 69 | 
            +
                    def subject
         | 
| 70 | 
            +
                      self.class::SUBJECT_CLASS.new(
         | 
| 71 | 
            +
                        config:     subject_config(matched_view.node),
         | 
| 72 | 
            +
                        context:    context,
         | 
| 73 | 
            +
                        node:       matched_view.node,
         | 
| 74 | 
            +
                        visibility: visibility
         | 
| 75 | 
            +
                      )
         | 
| 61 76 | 
             
                    end
         | 
| 62 77 |  | 
| 63 78 | 
             
                    def method_name
         | 
| @@ -95,17 +110,6 @@ module Mutant | |
| 95 110 | 
             
                      T::Private::Methods.signature_for_method(target_method)
         | 
| 96 111 | 
             
                    end
         | 
| 97 112 |  | 
| 98 | 
            -
                    def subject
         | 
| 99 | 
            -
                      node = matched_node_path.last || return
         | 
| 100 | 
            -
             | 
| 101 | 
            -
                      self.class::SUBJECT_CLASS.new(
         | 
| 102 | 
            -
                        config:     subject_config(node),
         | 
| 103 | 
            -
                        context:    context,
         | 
| 104 | 
            -
                        node:       node,
         | 
| 105 | 
            -
                        visibility: visibility
         | 
| 106 | 
            -
                      )
         | 
| 107 | 
            -
                    end
         | 
| 108 | 
            -
             | 
| 109 113 | 
             
                    def subject_config(node)
         | 
| 110 114 | 
             
                      Subject::Config.parse(
         | 
| 111 115 | 
             
                        comments: ast.comment_associations.fetch(node, []),
         | 
| @@ -113,10 +117,15 @@ module Mutant | |
| 113 117 | 
             
                      )
         | 
| 114 118 | 
             
                    end
         | 
| 115 119 |  | 
| 116 | 
            -
                    def  | 
| 117 | 
            -
                       | 
| 120 | 
            +
                    def matched_view
         | 
| 121 | 
            +
                      return if source_location.nil?
         | 
| 122 | 
            +
             | 
| 123 | 
            +
                      ast
         | 
| 124 | 
            +
                        .on_line(source_line)
         | 
| 125 | 
            +
                        .select { |view| view.node.type.eql?(self.class::MATCH_NODE_TYPE) && match?(view.node) }
         | 
| 126 | 
            +
                        .last
         | 
| 118 127 | 
             
                    end
         | 
| 119 | 
            -
                    memoize : | 
| 128 | 
            +
                    memoize :matched_view
         | 
| 120 129 |  | 
| 121 130 | 
             
                    def visibility
         | 
| 122 131 | 
             
                      # This can be cleaned up once we are on >ruby-3.0
         | 
| @@ -38,9 +38,11 @@ module Mutant | |
| 38 38 | 
             
                    end
         | 
| 39 39 |  | 
| 40 40 | 
             
                    def body_has_control?
         | 
| 41 | 
            -
                      AST. | 
| 42 | 
            -
                        n_break?(node) || n_next?(node)
         | 
| 43 | 
            -
                      end | 
| 41 | 
            +
                      AST::Structure.for(body.type).each_node(body) do |node|
         | 
| 42 | 
            +
                        return true if n_break?(node) || n_next?(node)
         | 
| 43 | 
            +
                      end
         | 
| 44 | 
            +
             | 
| 45 | 
            +
                      false
         | 
| 44 46 | 
             
                    end
         | 
| 45 47 |  | 
| 46 48 | 
             
                    def mutate_body_receiver
         | 
    
        data/lib/mutant/parser.rb
    CHANGED
    
    
    
        data/lib/mutant/version.rb
    CHANGED
    
    
    
        metadata
    CHANGED
    
    | @@ -1,14 +1,14 @@ | |
| 1 1 | 
             
            --- !ruby/object:Gem::Specification
         | 
| 2 2 | 
             
            name: mutant
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version
         | 
| 4 | 
            -
              version: 0.11. | 
| 4 | 
            +
              version: 0.11.14
         | 
| 5 5 | 
             
            platform: ruby
         | 
| 6 6 | 
             
            authors:
         | 
| 7 7 | 
             
            - Markus Schirp
         | 
| 8 8 | 
             
            autorequire:
         | 
| 9 9 | 
             
            bindir: bin
         | 
| 10 10 | 
             
            cert_chain: []
         | 
| 11 | 
            -
            date: 2022-07- | 
| 11 | 
            +
            date: 2022-07-31 00:00:00.000000000 Z
         | 
| 12 12 | 
             
            dependencies:
         | 
| 13 13 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 14 14 | 
             
              name: diff-lcs
         | 
| @@ -393,7 +393,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement | |
| 393 393 | 
             
                - !ruby/object:Gem::Version
         | 
| 394 394 | 
             
                  version: '0'
         | 
| 395 395 | 
             
            requirements: []
         | 
| 396 | 
            -
            rubygems_version: 3. | 
| 396 | 
            +
            rubygems_version: 3.1.6
         | 
| 397 397 | 
             
            signing_key:
         | 
| 398 398 | 
             
            specification_version: 4
         | 
| 399 399 | 
             
            summary: ''
         |