mutant 0.11.16 → 0.11.18

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.
Files changed (37) hide show
  1. checksums.yaml +4 -4
  2. data/bin/mutant +55 -46
  3. data/lib/mutant/bootstrap.rb +66 -35
  4. data/lib/mutant/cli/command/environment/run.rb +1 -1
  5. data/lib/mutant/cli/command/environment.rb +2 -2
  6. data/lib/mutant/cli/command.rb +24 -11
  7. data/lib/mutant/env.rb +9 -0
  8. data/lib/mutant/mutator/node/literal/regex.rb +8 -8
  9. data/lib/mutant/mutator/node/send.rb +27 -17
  10. data/lib/mutant/mutator/regexp.rb +211 -0
  11. data/lib/mutant/parallel/driver.rb +1 -0
  12. data/lib/mutant/parallel/worker.rb +5 -1
  13. data/lib/mutant/runner.rb +8 -6
  14. data/lib/mutant/segment/recorder.rb +124 -0
  15. data/lib/mutant/segment.rb +25 -0
  16. data/lib/mutant/version.rb +1 -1
  17. data/lib/mutant/world.rb +5 -0
  18. data/lib/mutant.rb +288 -228
  19. metadata +12 -33
  20. data/lib/mutant/ast/regexp/transformer/direct.rb +0 -145
  21. data/lib/mutant/ast/regexp/transformer/named_group.rb +0 -50
  22. data/lib/mutant/ast/regexp/transformer/options_group.rb +0 -68
  23. data/lib/mutant/ast/regexp/transformer/quantifier.rb +0 -92
  24. data/lib/mutant/ast/regexp/transformer/recursive.rb +0 -56
  25. data/lib/mutant/ast/regexp/transformer/root.rb +0 -28
  26. data/lib/mutant/ast/regexp/transformer/text.rb +0 -58
  27. data/lib/mutant/ast/regexp/transformer.rb +0 -152
  28. data/lib/mutant/ast/regexp.rb +0 -54
  29. data/lib/mutant/mutator/node/regexp/alternation_meta.rb +0 -20
  30. data/lib/mutant/mutator/node/regexp/beginning_of_line_anchor.rb +0 -20
  31. data/lib/mutant/mutator/node/regexp/capture_group.rb +0 -23
  32. data/lib/mutant/mutator/node/regexp/character_type.rb +0 -31
  33. data/lib/mutant/mutator/node/regexp/end_of_line_anchor.rb +0 -20
  34. data/lib/mutant/mutator/node/regexp/end_of_string_or_before_end_of_line_anchor.rb +0 -20
  35. data/lib/mutant/mutator/node/regexp/named_group.rb +0 -39
  36. data/lib/mutant/mutator/node/regexp/zero_or_more.rb +0 -34
  37. data/lib/mutant/mutator/node/regexp.rb +0 -20
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.16
4
+ version: 0.11.18
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-09-11 00:00:00.000000000 Z
11
+ date: 2023-01-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: diff-lcs
@@ -30,34 +30,28 @@ dependencies:
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: 3.1.0
33
+ version: 3.2.0
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: 3.1.0
40
+ version: 3.2.0
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: regexp_parser
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
45
  - - "~>"
46
46
  - !ruby/object:Gem::Version
47
- version: '2.3'
48
- - - ">="
49
- - !ruby/object:Gem::Version
50
- version: 2.3.1
47
+ version: 2.6.1
51
48
  type: :runtime
52
49
  prerelease: false
53
50
  version_requirements: !ruby/object:Gem::Requirement
54
51
  requirements:
55
52
  - - "~>"
56
53
  - !ruby/object:Gem::Version
57
- version: '2.3'
58
- - - ">="
59
- - !ruby/object:Gem::Version
60
- version: 2.3.1
54
+ version: 2.6.1
61
55
  - !ruby/object:Gem::Dependency
62
56
  name: sorbet-runtime
63
57
  requirement: !ruby/object:Gem::Requirement
@@ -78,14 +72,14 @@ dependencies:
78
72
  requirements:
79
73
  - - "~>"
80
74
  - !ruby/object:Gem::Version
81
- version: 0.6.5
75
+ version: 0.6.6
82
76
  type: :runtime
83
77
  prerelease: false
84
78
  version_requirements: !ruby/object:Gem::Requirement
85
79
  requirements:
86
80
  - - "~>"
87
81
  - !ruby/object:Gem::Version
88
- version: 0.6.5
82
+ version: 0.6.6
89
83
  - !ruby/object:Gem::Dependency
90
84
  name: parallel
91
85
  requirement: !ruby/object:Gem::Requirement
@@ -184,15 +178,6 @@ files:
184
178
  - lib/mutant/ast/pattern/parser.rb
185
179
  - lib/mutant/ast/pattern/source.rb
186
180
  - lib/mutant/ast/pattern/token.rb
187
- - lib/mutant/ast/regexp.rb
188
- - lib/mutant/ast/regexp/transformer.rb
189
- - lib/mutant/ast/regexp/transformer/direct.rb
190
- - lib/mutant/ast/regexp/transformer/named_group.rb
191
- - lib/mutant/ast/regexp/transformer/options_group.rb
192
- - lib/mutant/ast/regexp/transformer/quantifier.rb
193
- - lib/mutant/ast/regexp/transformer/recursive.rb
194
- - lib/mutant/ast/regexp/transformer/root.rb
195
- - lib/mutant/ast/regexp/transformer/text.rb
196
181
  - lib/mutant/ast/sexp.rb
197
182
  - lib/mutant/ast/structure.rb
198
183
  - lib/mutant/ast/types.rb
@@ -297,15 +282,6 @@ files:
297
282
  - lib/mutant/mutator/node/op_asgn.rb
298
283
  - lib/mutant/mutator/node/or_asgn.rb
299
284
  - lib/mutant/mutator/node/procarg_zero.rb
300
- - lib/mutant/mutator/node/regexp.rb
301
- - lib/mutant/mutator/node/regexp/alternation_meta.rb
302
- - lib/mutant/mutator/node/regexp/beginning_of_line_anchor.rb
303
- - lib/mutant/mutator/node/regexp/capture_group.rb
304
- - lib/mutant/mutator/node/regexp/character_type.rb
305
- - lib/mutant/mutator/node/regexp/end_of_line_anchor.rb
306
- - lib/mutant/mutator/node/regexp/end_of_string_or_before_end_of_line_anchor.rb
307
- - lib/mutant/mutator/node/regexp/named_group.rb
308
- - lib/mutant/mutator/node/regexp/zero_or_more.rb
309
285
  - lib/mutant/mutator/node/regopt.rb
310
286
  - lib/mutant/mutator/node/resbody.rb
311
287
  - lib/mutant/mutator/node/rescue.rb
@@ -320,6 +296,7 @@ files:
320
296
  - lib/mutant/mutator/node/when.rb
321
297
  - lib/mutant/mutator/node/yield.rb
322
298
  - lib/mutant/mutator/node/zsuper.rb
299
+ - lib/mutant/mutator/regexp.rb
323
300
  - lib/mutant/mutator/util.rb
324
301
  - lib/mutant/mutator/util/array.rb
325
302
  - lib/mutant/mutator/util/symbol.rb
@@ -356,6 +333,8 @@ files:
356
333
  - lib/mutant/runner.rb
357
334
  - lib/mutant/runner/sink.rb
358
335
  - lib/mutant/scope.rb
336
+ - lib/mutant/segment.rb
337
+ - lib/mutant/segment/recorder.rb
359
338
  - lib/mutant/selector.rb
360
339
  - lib/mutant/selector/expression.rb
361
340
  - lib/mutant/selector/null.rb
@@ -393,7 +372,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
393
372
  - !ruby/object:Gem::Version
394
373
  version: '0'
395
374
  requirements: []
396
- rubygems_version: 3.3.7
375
+ rubygems_version: 3.3.26
397
376
  signing_key:
398
377
  specification_version: 4
399
378
  summary: ''
@@ -1,145 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Mutant
4
- class AST
5
- module Regexp
6
- class Transformer
7
- # Transformer for nodes which map directly to other domain
8
- #
9
- # A node maps "directly" to another domain if the node never
10
- # has children or text which needs to be preserved for a mapping
11
- #
12
- # @example direct mapping
13
- #
14
- # input = /\d/
15
- # expression = Regexp::Parser.parse(input).first
16
- # node = Transformer::Direct.to_ast(expression)
17
- #
18
- # # the digit type always has the same text and no children
19
- # expression.text # => "\\d"
20
- # expression.terminal? # => true
21
- #
22
- # # therefore the `Parser::AST::Node` is always the same
23
- # node # => s(:regexp_digit_type)
24
- class Direct < self
25
- # Mapper from `Regexp::Expression` to `Parser::AST::Node`
26
- class ExpressionToAST < Transformer::ExpressionToAST
27
- # Transform expression into node
28
- #
29
- # @return [Parser::AST::Node]
30
- def call
31
- quantify(ast)
32
- end
33
- end # ExpressionToAST
34
-
35
- # Mapper from `Parser::AST::Node` to `Regexp::Expression`
36
- class ASTToExpression < Transformer::ASTToExpression
37
- include LookupTable
38
-
39
- properties = ::Regexp::Syntax
40
- .version_class("ruby/#{RUBY_VERSION}")
41
- .features.fetch(:property)
42
- .flat_map do |property|
43
- property_specifier = "\\p{#{property}}"
44
- non_property_specifier = "\\P{#{property}}"
45
-
46
- property_regex = /#{property_specifier}/
47
- non_property_regex = /#{non_property_specifier}/
48
-
49
- [
50
- [
51
- :"regexp_#{property}_property",
52
- [
53
- :property,
54
- property.to_sym,
55
- property_specifier
56
- ],
57
- ::Regexp::Parser.parse(property_regex).expressions.first.class
58
- ],
59
- [
60
- :"regexp_#{property}_nonproperty",
61
- [
62
- :nonproperty,
63
- property.to_sym,
64
- non_property_specifier
65
- ],
66
- ::Regexp::Parser.parse(non_property_regex).expressions.first.class
67
- ]
68
- ]
69
- end
70
-
71
- # rubocop:disable Layout/LineLength
72
- TABLE = Table.create(
73
- *properties,
74
- [:regexp_alnum_posixclass, [:posixclass, :alnum, '[:alnum:]'], ::Regexp::Expression::PosixClass],
75
- [:regexp_alpha_posixclass, [:posixclass, :alpha, '[:alpha:]'], ::Regexp::Expression::PosixClass],
76
- [:regexp_alternation_escape, [:escape, :alternation, '\|'], ::Regexp::Expression::EscapeSequence::Literal],
77
- [:regexp_ascii_posixclass, [:posixclass, :ascii, '[:ascii:]'], ::Regexp::Expression::PosixClass],
78
- [:regexp_backspace_escape, [:escape, :backspace, '\b'], ::Regexp::Expression::EscapeSequence::Backspace],
79
- [:regexp_bell_escape, [:escape, :bell, '\a'], ::Regexp::Expression::EscapeSequence::Literal],
80
- [:regexp_blank_posixclass, [:posixclass, :blank, '[:blank:]'], ::Regexp::Expression::PosixClass],
81
- [:regexp_bol_anchor, [:anchor, :bol, '^'], ::Regexp::Expression::Anchor::BeginningOfLine],
82
- [:regexp_bol_escape, [:escape, :bol, '\^'], ::Regexp::Expression::EscapeSequence::Literal],
83
- [:regexp_bos_anchor, [:anchor, :bos, '\\A'], ::Regexp::Expression::Anchor::BeginningOfString],
84
- [:regexp_carriage_escape, [:escape, :carriage, '\r'], ::Regexp::Expression::EscapeSequence::Literal],
85
- [:regexp_cntrl_posixclass, [:posixclass, :cntrl, '[:cntrl:]'], ::Regexp::Expression::PosixClass],
86
- [:regexp_digit_posixclass, [:posixclass, :digit, '[:digit:]'], ::Regexp::Expression::PosixClass],
87
- [:regexp_digit_type, [:type, :digit, '\d'], ::Regexp::Expression::CharacterType::Digit],
88
- [:regexp_dot_escape, [:escape, :dot, '\.'], ::Regexp::Expression::EscapeSequence::Literal],
89
- [:regexp_dot_meta, [:meta, :dot, '.'], ::Regexp::Expression::CharacterType::Any],
90
- [:regexp_eol_anchor, [:anchor, :eol, '$'], ::Regexp::Expression::Anchor::EndOfLine],
91
- [:regexp_eol_escape, [:escape, :eol, '\$'], ::Regexp::Expression::EscapeSequence::Literal],
92
- [:regexp_eos_anchor, [:anchor, :eos, '\\z'], ::Regexp::Expression::Anchor::EndOfString],
93
- [:regexp_eos_ob_eol_anchor, [:anchor, :eos_ob_eol, '\\Z'], ::Regexp::Expression::Anchor::EndOfStringOrBeforeEndOfLine],
94
- [:regexp_escape_escape, [:escape, :escape, '\e'], ::Regexp::Expression::EscapeSequence::AsciiEscape],
95
- [:regexp_form_feed_escape, [:escape, :form_feed, '\f'], ::Regexp::Expression::EscapeSequence::FormFeed],
96
- [:regexp_graph_posixclass, [:posixclass, :graph, '[:graph:]'], ::Regexp::Expression::PosixClass],
97
- [:regexp_group_close_escape, [:escape, :group_close, '\)'], ::Regexp::Expression::EscapeSequence::Literal],
98
- [:regexp_group_open_escape, [:escape, :group_open, '\('], ::Regexp::Expression::EscapeSequence::Literal],
99
- [:regexp_hex_type, [:type, :hex, '\h'], ::Regexp::Expression::CharacterType::Hex],
100
- [:regexp_interval_close_escape, [:escape, :interval_close, '\}'], ::Regexp::Expression::EscapeSequence::Literal],
101
- [:regexp_interval_open_escape, [:escape, :interval_open, '\{'], ::Regexp::Expression::EscapeSequence::Literal],
102
- [:regexp_linebreak_type, [:type, :linebreak, '\R'], ::Regexp::Expression::CharacterType::Linebreak],
103
- [:regexp_lower_posixclass, [:posixclass, :lower, '[:lower:]'], ::Regexp::Expression::PosixClass],
104
- [:regexp_mark_keep, [:keep, :mark, '\K'], ::Regexp::Expression::Keep::Mark],
105
- [:regexp_match_start_anchor, [:anchor, :match_start, '\\G'], ::Regexp::Expression::Anchor::MatchStart],
106
- [:regexp_newline_escape, [:escape, :newline, '\n'], ::Regexp::Expression::EscapeSequence::Literal],
107
- [:regexp_nondigit_type, [:type, :nondigit, '\D'], ::Regexp::Expression::CharacterType::NonDigit],
108
- [:regexp_nonhex_type, [:type, :nonhex, '\H'], ::Regexp::Expression::CharacterType::NonHex],
109
- [:regexp_nonspace_type, [:type, :nonspace, '\S'], ::Regexp::Expression::CharacterType::NonSpace],
110
- [:regexp_nonword_boundary_anchor, [:anchor, :nonword_boundary, '\\B'], ::Regexp::Expression::Anchor::NonWordBoundary],
111
- [:regexp_nonword_type, [:type, :nonword, '\W'], ::Regexp::Expression::CharacterType::NonWord],
112
- [:regexp_one_or_more_escape, [:escape, :one_or_more, '\+'], ::Regexp::Expression::EscapeSequence::Literal],
113
- [:regexp_print_nonposixclass, [:nonposixclass, :print, '[:^print:]'], ::Regexp::Expression::PosixClass],
114
- [:regexp_print_posixclass, [:posixclass, :print, '[:print:]'], ::Regexp::Expression::PosixClass],
115
- [:regexp_print_posixclass, [:posixclass, :print, '[:print:]'], ::Regexp::Expression::PosixClass],
116
- [:regexp_punct_posixclass, [:posixclass, :punct, '[:punct:]'], ::Regexp::Expression::PosixClass],
117
- [:regexp_set_close_escape, [:escape, :set_close, '\]'], ::Regexp::Expression::EscapeSequence::Literal],
118
- [:regexp_set_open_escape, [:escape, :set_open, '\['], ::Regexp::Expression::EscapeSequence::Literal],
119
- [:regexp_space_posixclass, [:posixclass, :space, '[:space:]'], ::Regexp::Expression::PosixClass],
120
- [:regexp_space_type, [:type, :space, '\s'], ::Regexp::Expression::CharacterType::Space],
121
- [:regexp_upper_posixclass, [:posixclass, :upper, '[:upper:]'], ::Regexp::Expression::PosixClass],
122
- [:regexp_vertical_tab_escape, [:escape, :vertical_tab, '\v'], ::Regexp::Expression::EscapeSequence::VerticalTab],
123
- [:regexp_word_boundary_anchor, [:anchor, :word_boundary, '\b'], ::Regexp::Expression::Anchor::WordBoundary],
124
- [:regexp_word_posixclass, [:posixclass, :word, '[:word:]'], ::Regexp::Expression::PosixClass],
125
- [:regexp_word_type, [:type, :word, '\w'], ::Regexp::Expression::CharacterType::Word],
126
- [:regexp_xdigit_posixclass, [:posixclass, :xdigit, '[:xdigit:]'], ::Regexp::Expression::PosixClass],
127
- [:regexp_xgrapheme_type, [:type, :xgrapheme, '\X'], ::Regexp::Expression::CharacterType::ExtendedGrapheme],
128
- [:regexp_zero_or_more_escape, [:escape, :zero_or_more, '\*'], ::Regexp::Expression::EscapeSequence::Literal],
129
- [:regexp_zero_or_one_escape, [:escape, :zero_or_one, '\?'], ::Regexp::Expression::EscapeSequence::Literal]
130
- )
131
- # rubocop:enable Layout/LineLength
132
-
133
- private
134
-
135
- def transform
136
- expression_class.new(expression_token)
137
- end
138
- end # ASTToExpression
139
-
140
- ASTToExpression::TABLE.types.each(&method(:register))
141
- end # Direct
142
- end # Transformer
143
- end # Regexp
144
- end # AST
145
- end # Mutant
@@ -1,50 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Mutant
4
- class AST
5
- module Regexp
6
- class Transformer
7
- # Transformer for named groups
8
- class NamedGroup < self
9
- register :regexp_named_group
10
-
11
- # Mapper from `Regexp::Expression` to `Parser::AST::Node`
12
- class ExpressionToAST < Transformer::ExpressionToAST
13
-
14
- # Transform named group into node
15
- #
16
- # @return [Parser::AST::Node]
17
- def call
18
- quantify(ast(expression.name, *children))
19
- end
20
- end # ExpressionToAST
21
-
22
- # Mapper from `Parser::AST::Node` to `Regexp::Expression`
23
- class ASTToExpression < Transformer::ASTToExpression
24
- include NamedChildren
25
-
26
- children :name
27
-
28
- private
29
-
30
- def transform
31
- named_group.tap do |expression|
32
- expression.expressions = subexpressions
33
- end
34
- end
35
-
36
- def subexpressions
37
- remaining_children.map(&Regexp.public_method(:to_expression))
38
- end
39
-
40
- def named_group
41
- ::Regexp::Expression::Group::Named.new(
42
- ::Regexp::Token.new(:group, :named, "(?<#{name}>")
43
- )
44
- end
45
- end # ASTToExpression
46
- end # NamedGroup
47
- end # Transformer
48
- end # Regexp
49
- end # AST
50
- end # Mutant
@@ -1,68 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Mutant
4
- class 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
@@ -1,92 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Mutant
4
- class 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 = {
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) }
46
- .to_h
47
- .freeze
48
-
49
- private
50
-
51
- def transform
52
- Regexp.to_expression(subject).dup.tap do |expression|
53
- expression.quantify(type, text, min, max, mode)
54
- end
55
- end
56
-
57
- def text
58
- if type.equal?(:interval)
59
- interval_text + suffix
60
- else
61
- suffix
62
- end
63
- end
64
-
65
- def type
66
- quantifier.type
67
- end
68
-
69
- def suffix
70
- quantifier.suffix
71
- end
72
-
73
- def mode
74
- quantifier.mode
75
- end
76
-
77
- def quantifier
78
- QUANTIFIER_MAP.fetch(node.type)
79
- end
80
-
81
- def interval_text
82
- interval = [min, max].map { |num| num if num.positive? }.uniq
83
- "{#{interval.join(',')}}"
84
- end
85
- end # ASTToExpression
86
-
87
- ASTToExpression::QUANTIFIER_MAP.keys.each(&method(:register))
88
- end # Quantifier
89
- end # Transformer
90
- end # Regexp
91
- end # AST
92
- end # Mutant
@@ -1,56 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Mutant
4
- class 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
@@ -1,28 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Mutant
4
- class 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
@@ -1,58 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Mutant
4
- class 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