mutant 0.10.20 → 0.10.25
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.rb +23 -4
- data/lib/mutant/ast/meta/send.rb +0 -1
- data/lib/mutant/ast/regexp.rb +37 -0
- data/lib/mutant/ast/regexp/transformer.rb +150 -0
- data/lib/mutant/ast/regexp/transformer/direct.rb +121 -0
- data/lib/mutant/ast/regexp/transformer/named_group.rb +50 -0
- data/lib/mutant/ast/regexp/transformer/options_group.rb +68 -0
- data/lib/mutant/ast/regexp/transformer/quantifier.rb +90 -0
- data/lib/mutant/ast/regexp/transformer/recursive.rb +56 -0
- data/lib/mutant/ast/regexp/transformer/root.rb +28 -0
- data/lib/mutant/ast/regexp/transformer/text.rb +58 -0
- data/lib/mutant/ast/types.rb +115 -11
- data/lib/mutant/cli/command/environment.rb +9 -3
- data/lib/mutant/config.rb +8 -54
- data/lib/mutant/config/coverage_criteria.rb +61 -0
- data/lib/mutant/env.rb +8 -6
- data/lib/mutant/expression.rb +0 -12
- data/lib/mutant/expression/namespace.rb +1 -1
- data/lib/mutant/isolation/fork.rb +1 -1
- data/lib/mutant/loader.rb +1 -1
- data/lib/mutant/matcher.rb +2 -2
- data/lib/mutant/matcher/config.rb +27 -6
- data/lib/mutant/matcher/method.rb +2 -3
- data/lib/mutant/matcher/method/metaclass.rb +1 -1
- data/lib/mutant/meta/example/dsl.rb +6 -1
- data/lib/mutant/mutator/node/arguments.rb +0 -2
- data/lib/mutant/mutator/node/block.rb +5 -1
- data/lib/mutant/mutator/node/dynamic_literal.rb +1 -1
- data/lib/mutant/mutator/node/kwargs.rb +44 -0
- data/lib/mutant/mutator/node/literal/regex.rb +26 -0
- data/lib/mutant/mutator/node/literal/symbol.rb +0 -2
- data/lib/mutant/mutator/node/regexp.rb +20 -0
- data/lib/mutant/mutator/node/regexp/alternation_meta.rb +20 -0
- data/lib/mutant/mutator/node/regexp/beginning_of_line_anchor.rb +20 -0
- data/lib/mutant/mutator/node/regexp/capture_group.rb +25 -0
- data/lib/mutant/mutator/node/regexp/character_type.rb +31 -0
- data/lib/mutant/mutator/node/regexp/end_of_line_anchor.rb +20 -0
- data/lib/mutant/mutator/node/regexp/end_of_string_or_before_end_of_line_anchor.rb +20 -0
- data/lib/mutant/mutator/node/regexp/zero_or_more.rb +34 -0
- data/lib/mutant/mutator/node/sclass.rb +1 -1
- data/lib/mutant/mutator/node/send.rb +36 -19
- data/lib/mutant/parallel.rb +43 -28
- data/lib/mutant/parallel/driver.rb +9 -3
- data/lib/mutant/parallel/worker.rb +60 -2
- data/lib/mutant/pipe.rb +94 -0
- data/lib/mutant/reporter/cli/printer/env.rb +1 -1
- data/lib/mutant/reporter/cli/printer/isolation_result.rb +1 -6
- data/lib/mutant/result.rb +8 -0
- data/lib/mutant/runner.rb +7 -10
- data/lib/mutant/runner/sink.rb +12 -2
- data/lib/mutant/subject.rb +1 -3
- data/lib/mutant/subject/method/instance.rb +2 -4
- data/lib/mutant/timer.rb +2 -4
- data/lib/mutant/transform.rb +25 -2
- data/lib/mutant/version.rb +1 -1
- data/lib/mutant/world.rb +1 -2
- metadata +48 -9
- data/lib/mutant/warnings.rb +0 -106
| @@ -0,0 +1,68 @@ | |
| 1 | 
            +
            # frozen_string_literal: true
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            module Mutant
         | 
| 4 | 
            +
              module AST
         | 
| 5 | 
            +
                module Regexp
         | 
| 6 | 
            +
                  class Transformer
         | 
| 7 | 
            +
                    # Transformer for option groups
         | 
| 8 | 
            +
                    class OptionsGroup < self
         | 
| 9 | 
            +
                      register :regexp_options_group
         | 
| 10 | 
            +
                      register :regexp_options_switch_group
         | 
| 11 | 
            +
             | 
| 12 | 
            +
                      # Mapper from `Regexp::Expression` to `Parser::AST::Node`
         | 
| 13 | 
            +
                      class ExpressionToAST < Transformer::ExpressionToAST
         | 
| 14 | 
            +
             | 
| 15 | 
            +
                        # Transform options group into node
         | 
| 16 | 
            +
                        #
         | 
| 17 | 
            +
                        # @return [Parser::AST::Node]
         | 
| 18 | 
            +
                        def call
         | 
| 19 | 
            +
                          quantify(ast(expression.option_changes, *children))
         | 
| 20 | 
            +
                        end
         | 
| 21 | 
            +
                      end # ExpressionToAST
         | 
| 22 | 
            +
             | 
| 23 | 
            +
                      # Mapper from `Parser::AST::Node` to `Regexp::Expression`
         | 
| 24 | 
            +
                      class ASTToExpression < Transformer::ASTToExpression
         | 
| 25 | 
            +
                        include NamedChildren
         | 
| 26 | 
            +
             | 
| 27 | 
            +
                        children :option_changes
         | 
| 28 | 
            +
             | 
| 29 | 
            +
                      private
         | 
| 30 | 
            +
             | 
| 31 | 
            +
                        def transform
         | 
| 32 | 
            +
                          options_group.tap do |expression|
         | 
| 33 | 
            +
                            expression.expressions = subexpressions
         | 
| 34 | 
            +
                          end
         | 
| 35 | 
            +
                        end
         | 
| 36 | 
            +
             | 
| 37 | 
            +
                        def subexpressions
         | 
| 38 | 
            +
                          remaining_children.map(&Regexp.public_method(:to_expression))
         | 
| 39 | 
            +
                        end
         | 
| 40 | 
            +
             | 
| 41 | 
            +
                        def options_group
         | 
| 42 | 
            +
                          ::Regexp::Expression::Group::Options.new(
         | 
| 43 | 
            +
                            ::Regexp::Token.new(:group, type, text)
         | 
| 44 | 
            +
                          )
         | 
| 45 | 
            +
                        end
         | 
| 46 | 
            +
             | 
| 47 | 
            +
                        def type
         | 
| 48 | 
            +
                          {
         | 
| 49 | 
            +
                            regexp_options_group:        :options,
         | 
| 50 | 
            +
                            regexp_options_switch_group: :options_switch
         | 
| 51 | 
            +
                          }.fetch(node.type)
         | 
| 52 | 
            +
                        end
         | 
| 53 | 
            +
             | 
| 54 | 
            +
                        def text
         | 
| 55 | 
            +
                          pos, neg = option_changes.partition { |_opt, val| val }.map do |arr|
         | 
| 56 | 
            +
                            arr.map(&:first).join
         | 
| 57 | 
            +
                          end
         | 
| 58 | 
            +
                          neg_opt_sep = '-' unless neg.empty?
         | 
| 59 | 
            +
                          content_sep = ':' unless type.equal?(:options_switch)
         | 
| 60 | 
            +
             | 
| 61 | 
            +
                          "(?#{pos}#{neg_opt_sep}#{neg}#{content_sep}"
         | 
| 62 | 
            +
                        end
         | 
| 63 | 
            +
                      end # ASTToExpression
         | 
| 64 | 
            +
                    end # OptionsGroup
         | 
| 65 | 
            +
                  end # Transformer
         | 
| 66 | 
            +
                end # Regexp
         | 
| 67 | 
            +
              end # AST
         | 
| 68 | 
            +
            end # Mutant
         | 
| @@ -0,0 +1,90 @@ | |
| 1 | 
            +
            # frozen_string_literal: true
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            module Mutant
         | 
| 4 | 
            +
              module AST
         | 
| 5 | 
            +
                module Regexp
         | 
| 6 | 
            +
                  class Transformer
         | 
| 7 | 
            +
                    # Transformer for regexp quantifiers
         | 
| 8 | 
            +
                    class Quantifier < self
         | 
| 9 | 
            +
                      # Mapper from `Regexp::Expression` to `Parser::AST::Node`
         | 
| 10 | 
            +
                      class ExpressionToAST < Transformer::ExpressionToAST
         | 
| 11 | 
            +
                        # Transform quantifier into node
         | 
| 12 | 
            +
                        #
         | 
| 13 | 
            +
                        # @return [Parser::AST::Node]
         | 
| 14 | 
            +
                        def call
         | 
| 15 | 
            +
                          ast(expression.min, expression.max)
         | 
| 16 | 
            +
                        end
         | 
| 17 | 
            +
             | 
| 18 | 
            +
                      private
         | 
| 19 | 
            +
             | 
| 20 | 
            +
                        def type
         | 
| 21 | 
            +
                          :"regexp_#{expression.mode}_#{expression.token}"
         | 
| 22 | 
            +
                        end
         | 
| 23 | 
            +
                      end # ExpressionToAST
         | 
| 24 | 
            +
             | 
| 25 | 
            +
                      # Mapper from `Parser::AST::Node` to `Regexp::Expression`
         | 
| 26 | 
            +
                      class ASTToExpression < Transformer::ASTToExpression
         | 
| 27 | 
            +
                        include NamedChildren
         | 
| 28 | 
            +
             | 
| 29 | 
            +
                        children :min, :max, :subject
         | 
| 30 | 
            +
             | 
| 31 | 
            +
                        Quantifier = Class.new.include(Concord::Public.new(:type, :suffix, :mode))
         | 
| 32 | 
            +
             | 
| 33 | 
            +
                        QUANTIFIER_MAP = IceNine.deep_freeze({
         | 
| 34 | 
            +
                          regexp_greedy_zero_or_more:     [:zero_or_more, '*',  :greedy],
         | 
| 35 | 
            +
                          regexp_greedy_one_or_more:      [:one_or_more,  '+',  :greedy],
         | 
| 36 | 
            +
                          regexp_greedy_zero_or_one:      [:zero_or_one,  '?',  :greedy],
         | 
| 37 | 
            +
                          regexp_possessive_zero_or_one:  [:zero_or_one,  '?+', :possessive],
         | 
| 38 | 
            +
                          regexp_reluctant_zero_or_more:  [:zero_or_more, '*?', :reluctant],
         | 
| 39 | 
            +
                          regexp_reluctant_one_or_more:   [:one_or_more,  '+?', :reluctant],
         | 
| 40 | 
            +
                          regexp_possessive_zero_or_more: [:zero_or_more, '*+', :possessive],
         | 
| 41 | 
            +
                          regexp_possessive_one_or_more:  [:one_or_more,  '++', :possessive],
         | 
| 42 | 
            +
                          regexp_greedy_interval:         [:interval,     '',   :greedy],
         | 
| 43 | 
            +
                          regexp_reluctant_interval:      [:interval,     '?',  :reluctant],
         | 
| 44 | 
            +
                          regexp_possessive_interval:     [:interval,     '+',  :possessive]
         | 
| 45 | 
            +
                        }.transform_values { |arguments| Quantifier.new(*arguments) }.to_h)
         | 
| 46 | 
            +
             | 
| 47 | 
            +
                      private
         | 
| 48 | 
            +
             | 
| 49 | 
            +
                        def transform
         | 
| 50 | 
            +
                          Regexp.to_expression(subject).dup.tap do |expression|
         | 
| 51 | 
            +
                            expression.quantify(type, text, min, max, mode)
         | 
| 52 | 
            +
                          end
         | 
| 53 | 
            +
                        end
         | 
| 54 | 
            +
             | 
| 55 | 
            +
                        def text
         | 
| 56 | 
            +
                          if type.equal?(:interval)
         | 
| 57 | 
            +
                            interval_text + suffix
         | 
| 58 | 
            +
                          else
         | 
| 59 | 
            +
                            suffix
         | 
| 60 | 
            +
                          end
         | 
| 61 | 
            +
                        end
         | 
| 62 | 
            +
             | 
| 63 | 
            +
                        def type
         | 
| 64 | 
            +
                          quantifier.type
         | 
| 65 | 
            +
                        end
         | 
| 66 | 
            +
             | 
| 67 | 
            +
                        def suffix
         | 
| 68 | 
            +
                          quantifier.suffix
         | 
| 69 | 
            +
                        end
         | 
| 70 | 
            +
             | 
| 71 | 
            +
                        def mode
         | 
| 72 | 
            +
                          quantifier.mode
         | 
| 73 | 
            +
                        end
         | 
| 74 | 
            +
             | 
| 75 | 
            +
                        def quantifier
         | 
| 76 | 
            +
                          QUANTIFIER_MAP.fetch(node.type)
         | 
| 77 | 
            +
                        end
         | 
| 78 | 
            +
             | 
| 79 | 
            +
                        def interval_text
         | 
| 80 | 
            +
                          interval = [min, max].map { |num| num if num.positive? }.uniq
         | 
| 81 | 
            +
                          "{#{interval.join(',')}}"
         | 
| 82 | 
            +
                        end
         | 
| 83 | 
            +
                      end # ASTToExpression
         | 
| 84 | 
            +
             | 
| 85 | 
            +
                      ASTToExpression::QUANTIFIER_MAP.keys.each(&method(:register))
         | 
| 86 | 
            +
                    end # Quantifier
         | 
| 87 | 
            +
                  end # Transformer
         | 
| 88 | 
            +
                end # Regexp
         | 
| 89 | 
            +
              end # AST
         | 
| 90 | 
            +
            end # Mutant
         | 
| @@ -0,0 +1,56 @@ | |
| 1 | 
            +
            # frozen_string_literal: true
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            module Mutant
         | 
| 4 | 
            +
              module AST
         | 
| 5 | 
            +
                module Regexp
         | 
| 6 | 
            +
                  class Transformer
         | 
| 7 | 
            +
                    # Transformer for nodes with children
         | 
| 8 | 
            +
                    class Recursive < self
         | 
| 9 | 
            +
                      # Mapper from `Regexp::Expression` to `Parser::AST::Node`
         | 
| 10 | 
            +
                      class ExpressionToAST < Transformer::ExpressionToAST
         | 
| 11 | 
            +
                        # Transform expression and children into nodes
         | 
| 12 | 
            +
                        #
         | 
| 13 | 
            +
                        # @return [Parser::AST::Node]
         | 
| 14 | 
            +
                        def call
         | 
| 15 | 
            +
                          quantify(ast(*children))
         | 
| 16 | 
            +
                        end
         | 
| 17 | 
            +
                      end # ExpressionToAST
         | 
| 18 | 
            +
             | 
| 19 | 
            +
                      # Mapper from `Parser::AST::Node` to `Regexp::Expression`
         | 
| 20 | 
            +
                      class ASTToExpression < Transformer::ASTToExpression
         | 
| 21 | 
            +
                        include LookupTable
         | 
| 22 | 
            +
             | 
| 23 | 
            +
                        # Expression::Sequence represents conditional branches, alternation branches, and intersection branches
         | 
| 24 | 
            +
                        # rubocop:disable Layout/LineLength
         | 
| 25 | 
            +
                        TABLE = Table.create(
         | 
| 26 | 
            +
                          [:regexp_alternation_meta,      [:meta,        :alternation,  '|'],    ::Regexp::Expression::Alternation],
         | 
| 27 | 
            +
                          [:regexp_atomic_group,          [:group,       :atomic,       '(?>'],  ::Regexp::Expression::Group::Atomic],
         | 
| 28 | 
            +
                          [:regexp_capture_group,         [:group,       :capture,      '('],    ::Regexp::Expression::Group::Capture],
         | 
| 29 | 
            +
                          [:regexp_character_set,         [:set,         :character,    '['],    ::Regexp::Expression::CharacterSet],
         | 
| 30 | 
            +
                          [:regexp_intersection_set,      [:set,         :intersection, '&&'],   ::Regexp::Expression::CharacterSet::Intersection],
         | 
| 31 | 
            +
                          [:regexp_lookahead_assertion,   [:assertion,   :lookahead,    '(?='],  ::Regexp::Expression::Assertion::Lookahead],
         | 
| 32 | 
            +
                          [:regexp_lookbehind_assertion,  [:assertion,   :lookbehind,   '(?<='], ::Regexp::Expression::Assertion::Lookbehind],
         | 
| 33 | 
            +
                          [:regexp_nlookahead_assertion,  [:assertion,   :nlookahead,   '(?!'],  ::Regexp::Expression::Assertion::NegativeLookahead],
         | 
| 34 | 
            +
                          [:regexp_nlookbehind_assertion, [:assertion,   :nlookbehind,  '(?<!'], ::Regexp::Expression::Assertion::NegativeLookbehind],
         | 
| 35 | 
            +
                          [:regexp_open_conditional,      [:conditional, :open,         '(?'],   ::Regexp::Expression::Conditional::Expression],
         | 
| 36 | 
            +
                          [:regexp_passive_group,         [:group,       :passive,      '(?:'],  ::Regexp::Expression::Group::Passive],
         | 
| 37 | 
            +
                          [:regexp_range_set,             [:set,         :range,        '-'],    ::Regexp::Expression::CharacterSet::Range],
         | 
| 38 | 
            +
                          [:regexp_sequence_expression,   [:expression,  :sequence,     ''],     ::Regexp::Expression::Sequence]
         | 
| 39 | 
            +
                        )
         | 
| 40 | 
            +
                      # rubocop:enable Layout/LineLength
         | 
| 41 | 
            +
             | 
| 42 | 
            +
                      private
         | 
| 43 | 
            +
             | 
| 44 | 
            +
                        def transform
         | 
| 45 | 
            +
                          expression_class.new(expression_token).tap do |expression|
         | 
| 46 | 
            +
                            expression.expressions = subexpressions
         | 
| 47 | 
            +
                          end
         | 
| 48 | 
            +
                        end
         | 
| 49 | 
            +
                      end # ASTToExpression
         | 
| 50 | 
            +
             | 
| 51 | 
            +
                      ASTToExpression::TABLE.types.each(&method(:register))
         | 
| 52 | 
            +
                    end # Recursive
         | 
| 53 | 
            +
                  end # Transformer
         | 
| 54 | 
            +
                end # Regexp
         | 
| 55 | 
            +
              end # AST
         | 
| 56 | 
            +
            end # Mutant
         | 
| @@ -0,0 +1,28 @@ | |
| 1 | 
            +
            # frozen_string_literal: true
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            module Mutant
         | 
| 4 | 
            +
              module AST
         | 
| 5 | 
            +
                module Regexp
         | 
| 6 | 
            +
                  class Transformer
         | 
| 7 | 
            +
                    # Transformer for root nodes
         | 
| 8 | 
            +
                    class Root < self
         | 
| 9 | 
            +
                      register :regexp_root_expression
         | 
| 10 | 
            +
             | 
| 11 | 
            +
                      ExpressionToAST = Class.new(Recursive::ExpressionToAST)
         | 
| 12 | 
            +
             | 
| 13 | 
            +
                      # Mapper from `Parser::AST::Node` to `Regexp::Expression`
         | 
| 14 | 
            +
                      class ASTToExpression < Transformer::ASTToExpression
         | 
| 15 | 
            +
             | 
| 16 | 
            +
                      private
         | 
| 17 | 
            +
             | 
| 18 | 
            +
                        def transform
         | 
| 19 | 
            +
                          ::Regexp::Expression::Root.build.tap do |root|
         | 
| 20 | 
            +
                            root.expressions = subexpressions
         | 
| 21 | 
            +
                          end
         | 
| 22 | 
            +
                        end
         | 
| 23 | 
            +
                      end # ASTToExpression
         | 
| 24 | 
            +
                    end # Root
         | 
| 25 | 
            +
                  end # Transformer
         | 
| 26 | 
            +
                end # Regexp
         | 
| 27 | 
            +
              end # AST
         | 
| 28 | 
            +
            end # Mutant
         | 
| @@ -0,0 +1,58 @@ | |
| 1 | 
            +
            # frozen_string_literal: true
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            module Mutant
         | 
| 4 | 
            +
              module AST
         | 
| 5 | 
            +
                module Regexp
         | 
| 6 | 
            +
                  class Transformer
         | 
| 7 | 
            +
                    # Regexp AST transformer for nodes that encode a text value
         | 
| 8 | 
            +
                    class Text < self
         | 
| 9 | 
            +
                      # Mapper from `Regexp::Expression` to `Parser::AST::Node`
         | 
| 10 | 
            +
                      class ExpressionToAST < Transformer::ExpressionToAST
         | 
| 11 | 
            +
                        # Transform expression into node preserving text value
         | 
| 12 | 
            +
                        #
         | 
| 13 | 
            +
                        # @return [Parser::AST::Node]
         | 
| 14 | 
            +
                        def call
         | 
| 15 | 
            +
                          quantify(ast(expression.text))
         | 
| 16 | 
            +
                        end
         | 
| 17 | 
            +
                      end # ExpressionToAST
         | 
| 18 | 
            +
             | 
| 19 | 
            +
                      # Mapper from `Parser::AST::Node` to `Regexp::Expression`
         | 
| 20 | 
            +
                      class ASTToExpression < Transformer::ASTToExpression
         | 
| 21 | 
            +
                        include LookupTable
         | 
| 22 | 
            +
             | 
| 23 | 
            +
                        # rubocop:disable Layout/LineLength
         | 
| 24 | 
            +
                        TABLE = Table.create(
         | 
| 25 | 
            +
                          [:regexp_literal_literal,       %i[literal literal],       ::Regexp::Expression::Literal],
         | 
| 26 | 
            +
                          [:regexp_comment_group,         %i[group comment],         ::Regexp::Expression::Group::Comment],
         | 
| 27 | 
            +
                          [:regexp_number_backref,        %i[backref number],        ::Regexp::Expression::Backreference::Number],
         | 
| 28 | 
            +
                          [:regexp_name_call_backref,     %i[backref name_call],     ::Regexp::Expression::Backreference::NameCall],
         | 
| 29 | 
            +
                          [:regexp_whitespace_free_space, %i[free_space whitespace], ::Regexp::Expression::WhiteSpace],
         | 
| 30 | 
            +
                          [:regexp_comment_free_space,    %i[free_space comment],    ::Regexp::Expression::WhiteSpace],
         | 
| 31 | 
            +
                          [:regexp_hex_escape,            %i[escape hex],            ::Regexp::Expression::EscapeSequence::Hex],
         | 
| 32 | 
            +
                          [:regexp_octal_escape,          %i[escape octal],          ::Regexp::Expression::EscapeSequence::Octal],
         | 
| 33 | 
            +
                          [:regexp_literal_escape,        %i[escape literal],        ::Regexp::Expression::EscapeSequence::Literal],
         | 
| 34 | 
            +
                          [:regexp_backslash_escape,      %i[escape backslash],      ::Regexp::Expression::EscapeSequence::Literal],
         | 
| 35 | 
            +
                          [:regexp_tab_escape,            %i[escape tab],            ::Regexp::Expression::EscapeSequence::Literal],
         | 
| 36 | 
            +
                          [:regexp_codepoint_list_escape, %i[escape codepoint_list], ::Regexp::Expression::EscapeSequence::CodepointList],
         | 
| 37 | 
            +
                          [:regexp_codepoint_escape,      %i[escape codepoint],      ::Regexp::Expression::EscapeSequence::Codepoint],
         | 
| 38 | 
            +
                          [:regexp_control_escape,        %i[escape control],        ::Regexp::Expression::EscapeSequence::Control],
         | 
| 39 | 
            +
                          [:regexp_meta_sequence_escape,  %i[escape meta_sequence],  ::Regexp::Expression::EscapeSequence::Control],
         | 
| 40 | 
            +
                          [:regexp_condition_conditional, %i[conditional condition], ::Regexp::Expression::Conditional::Condition]
         | 
| 41 | 
            +
                        )
         | 
| 42 | 
            +
                      # rubocop:enable Layout/LineLength
         | 
| 43 | 
            +
             | 
| 44 | 
            +
                      private
         | 
| 45 | 
            +
             | 
| 46 | 
            +
                        def transform
         | 
| 47 | 
            +
                          token = expression_token.dup
         | 
| 48 | 
            +
                          token.text = Util.one(node.children)
         | 
| 49 | 
            +
                          expression_class.new(token)
         | 
| 50 | 
            +
                        end
         | 
| 51 | 
            +
                      end # ASTToExpression
         | 
| 52 | 
            +
             | 
| 53 | 
            +
                      ASTToExpression::TABLE.types.each(&method(:register))
         | 
| 54 | 
            +
                    end # Text
         | 
| 55 | 
            +
                  end # Transformer
         | 
| 56 | 
            +
                end # Regexp
         | 
| 57 | 
            +
              end # AST
         | 
| 58 | 
            +
            end # Mutant
         | 
    
        data/lib/mutant/ast/types.rb
    CHANGED
    
    | @@ -3,14 +3,9 @@ | |
| 3 3 | 
             
            module Mutant
         | 
| 4 4 | 
             
              module AST
         | 
| 5 5 | 
             
                # Groups of node types
         | 
| 6 | 
            -
                module Types
         | 
| 6 | 
            +
                module Types # rubocop:disable Metrics/ModuleLength
         | 
| 7 7 | 
             
                  ASSIGNABLE_VARIABLES = Set.new(%i[ivasgn lvasgn cvasgn gvasgn]).freeze
         | 
| 8 8 |  | 
| 9 | 
            -
                  INDEX_ASSIGN_OPERATOR = :[]=
         | 
| 10 | 
            -
             | 
| 11 | 
            -
                  # Set of nodes that cannot be on the LHS of an assignment
         | 
| 12 | 
            -
                  NOT_ASSIGNABLE         = Set.new(%i[int float str dstr class module self nil]).freeze
         | 
| 13 | 
            -
             | 
| 14 9 | 
             
                  # Set of op-assign types
         | 
| 15 10 | 
             
                  OP_ASSIGN              = Set.new(%i[or_asgn and_asgn op_asgn]).freeze
         | 
| 16 11 | 
             
                  # Set of node types that are not valid when emitted standalone
         | 
| @@ -53,21 +48,130 @@ module Mutant | |
| 53 48 | 
             
                    METHOD_OPERATORS - (INDEX_OPERATORS + UNARY_METHOD_OPERATORS)
         | 
| 54 49 | 
             
                  )
         | 
| 55 50 |  | 
| 56 | 
            -
                  OPERATOR_METHODS = Set.new(
         | 
| 57 | 
            -
                    METHOD_OPERATORS + INDEX_OPERATORS + UNARY_METHOD_OPERATORS
         | 
| 58 | 
            -
                  ).freeze
         | 
| 59 | 
            -
             | 
| 60 51 | 
             
                  # Nodes that are NOT handled by mutant.
         | 
| 61 52 | 
             
                  #
         | 
| 62 53 | 
             
                  # not - 1.8 only, mutant does not support 1.8
         | 
| 63 54 | 
             
                  #
         | 
| 64 55 | 
             
                  BLACKLIST = Set.new(%i[not]).freeze
         | 
| 65 56 |  | 
| 57 | 
            +
                  # Nodes generated by regular expression body parsing
         | 
| 58 | 
            +
                  REGEXP = Set.new(%i[
         | 
| 59 | 
            +
                    regexp_alnum_posixclass
         | 
| 60 | 
            +
                    regexp_alpha_posixclass
         | 
| 61 | 
            +
                    regexp_alpha_property
         | 
| 62 | 
            +
                    regexp_alternation_escape
         | 
| 63 | 
            +
                    regexp_alternation_meta
         | 
| 64 | 
            +
                    regexp_arabic_property
         | 
| 65 | 
            +
                    regexp_ascii_posixclass
         | 
| 66 | 
            +
                    regexp_atomic_group
         | 
| 67 | 
            +
                    regexp_backslash_escape
         | 
| 68 | 
            +
                    regexp_backspace_escape
         | 
| 69 | 
            +
                    regexp_bell_escape
         | 
| 70 | 
            +
                    regexp_blank_posixclass
         | 
| 71 | 
            +
                    regexp_bol_anchor
         | 
| 72 | 
            +
                    regexp_bol_escape
         | 
| 73 | 
            +
                    regexp_bos_anchor
         | 
| 74 | 
            +
                    regexp_capture_group
         | 
| 75 | 
            +
                    regexp_carriage_escape
         | 
| 76 | 
            +
                    regexp_character_set
         | 
| 77 | 
            +
                    regexp_cntrl_posixclass
         | 
| 78 | 
            +
                    regexp_codepoint_escape
         | 
| 79 | 
            +
                    regexp_codepoint_list_escape
         | 
| 80 | 
            +
                    regexp_comment_free_space
         | 
| 81 | 
            +
                    regexp_comment_group
         | 
| 82 | 
            +
                    regexp_condition_conditional
         | 
| 83 | 
            +
                    regexp_control_escape
         | 
| 84 | 
            +
                    regexp_digit_posixclass
         | 
| 85 | 
            +
                    regexp_digit_type
         | 
| 86 | 
            +
                    regexp_dot_escape
         | 
| 87 | 
            +
                    regexp_dot_meta
         | 
| 88 | 
            +
                    regexp_eol_anchor
         | 
| 89 | 
            +
                    regexp_eol_escape
         | 
| 90 | 
            +
                    regexp_eos_anchor
         | 
| 91 | 
            +
                    regexp_eos_ob_eol_anchor
         | 
| 92 | 
            +
                    regexp_escape_escape
         | 
| 93 | 
            +
                    regexp_form_feed_escape
         | 
| 94 | 
            +
                    regexp_graph_posixclass
         | 
| 95 | 
            +
                    regexp_greedy_interval
         | 
| 96 | 
            +
                    regexp_greedy_one_or_more
         | 
| 97 | 
            +
                    regexp_greedy_zero_or_more
         | 
| 98 | 
            +
                    regexp_greedy_zero_or_one
         | 
| 99 | 
            +
                    regexp_group_close_escape
         | 
| 100 | 
            +
                    regexp_group_open_escape
         | 
| 101 | 
            +
                    regexp_han_property
         | 
| 102 | 
            +
                    regexp_hangul_property
         | 
| 103 | 
            +
                    regexp_hex_escape
         | 
| 104 | 
            +
                    regexp_hex_type
         | 
| 105 | 
            +
                    regexp_hiragana_property
         | 
| 106 | 
            +
                    regexp_intersection_set
         | 
| 107 | 
            +
                    regexp_interval_close_escape
         | 
| 108 | 
            +
                    regexp_interval_open_escape
         | 
| 109 | 
            +
                    regexp_katakana_property
         | 
| 110 | 
            +
                    regexp_letter_property
         | 
| 111 | 
            +
                    regexp_linebreak_type
         | 
| 112 | 
            +
                    regexp_literal_escape
         | 
| 113 | 
            +
                    regexp_literal_literal
         | 
| 114 | 
            +
                    regexp_lookahead_assertion
         | 
| 115 | 
            +
                    regexp_lookbehind_assertion
         | 
| 116 | 
            +
                    regexp_lower_posixclass
         | 
| 117 | 
            +
                    regexp_mark_keep
         | 
| 118 | 
            +
                    regexp_match_start_anchor
         | 
| 119 | 
            +
                    regexp_meta_sequence_escape
         | 
| 120 | 
            +
                    regexp_name_call_backref
         | 
| 121 | 
            +
                    regexp_named_group
         | 
| 122 | 
            +
                    regexp_newline_escape
         | 
| 123 | 
            +
                    regexp_nlookahead_assertion
         | 
| 124 | 
            +
                    regexp_nlookbehind_assertion
         | 
| 125 | 
            +
                    regexp_nondigit_type
         | 
| 126 | 
            +
                    regexp_nonhex_type
         | 
| 127 | 
            +
                    regexp_nonspace_type
         | 
| 128 | 
            +
                    regexp_nonword_boundary_anchor
         | 
| 129 | 
            +
                    regexp_nonword_type
         | 
| 130 | 
            +
                    regexp_number_backref
         | 
| 131 | 
            +
                    regexp_octal_escape
         | 
| 132 | 
            +
                    regexp_one_or_more_escape
         | 
| 133 | 
            +
                    regexp_open_conditional
         | 
| 134 | 
            +
                    regexp_options_group
         | 
| 135 | 
            +
                    regexp_options_switch_group
         | 
| 136 | 
            +
                    regexp_passive_group
         | 
| 137 | 
            +
                    regexp_possessive_interval
         | 
| 138 | 
            +
                    regexp_possessive_one_or_more
         | 
| 139 | 
            +
                    regexp_possessive_zero_or_more
         | 
| 140 | 
            +
                    regexp_possessive_zero_or_one
         | 
| 141 | 
            +
                    regexp_print_nonposixclass
         | 
| 142 | 
            +
                    regexp_print_nonproperty
         | 
| 143 | 
            +
                    regexp_print_posixclass
         | 
| 144 | 
            +
                    regexp_print_posixclass
         | 
| 145 | 
            +
                    regexp_print_property
         | 
| 146 | 
            +
                    regexp_punct_posixclass
         | 
| 147 | 
            +
                    regexp_range_set
         | 
| 148 | 
            +
                    regexp_reluctant_interval
         | 
| 149 | 
            +
                    regexp_reluctant_one_or_more
         | 
| 150 | 
            +
                    regexp_reluctant_zero_or_more
         | 
| 151 | 
            +
                    regexp_root_expression
         | 
| 152 | 
            +
                    regexp_sequence_expression
         | 
| 153 | 
            +
                    regexp_set_close_escape
         | 
| 154 | 
            +
                    regexp_set_open_escape
         | 
| 155 | 
            +
                    regexp_space_posixclass
         | 
| 156 | 
            +
                    regexp_space_type
         | 
| 157 | 
            +
                    regexp_tab_escape
         | 
| 158 | 
            +
                    regexp_upper_posixclass
         | 
| 159 | 
            +
                    regexp_vertical_tab_escape
         | 
| 160 | 
            +
                    regexp_whitespace_free_space
         | 
| 161 | 
            +
                    regexp_word_boundary_anchor
         | 
| 162 | 
            +
                    regexp_word_posixclass
         | 
| 163 | 
            +
                    regexp_word_type
         | 
| 164 | 
            +
                    regexp_xdigit_posixclass
         | 
| 165 | 
            +
                    regexp_xgrapheme_type
         | 
| 166 | 
            +
                    regexp_zero_or_more_escape
         | 
| 167 | 
            +
                    regexp_zero_or_one_escape
         | 
| 168 | 
            +
                  ]).freeze
         | 
| 169 | 
            +
             | 
| 66 170 | 
             
                  # Nodes that are NOT generated by parser but used by mutant / unparser.
         | 
| 67 171 | 
             
                  GENERATED = Set.new(%i[empty]).freeze
         | 
| 68 172 |  | 
| 69 173 | 
             
                  ALL = Set.new(
         | 
| 70 | 
            -
                    (Parser::Meta::NODE_TYPES + GENERATED) - BLACKLIST
         | 
| 174 | 
            +
                    (Parser::Meta::NODE_TYPES + GENERATED + REGEXP) - BLACKLIST
         | 
| 71 175 | 
             
                  ).freeze
         | 
| 72 176 | 
             
                end # Types
         | 
| 73 177 | 
             
              end # AST
         |