mutant 0.8.24 → 0.9.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (218) hide show
  1. checksums.yaml +4 -4
  2. data/.circleci/config.yml +3 -3
  3. data/Changelog.md +14 -654
  4. data/Gemfile +13 -0
  5. data/Gemfile.lock +59 -64
  6. data/LICENSE +271 -20
  7. data/README.md +73 -140
  8. data/Rakefile +0 -21
  9. data/bin/mutant +7 -2
  10. data/config/reek.yml +2 -1
  11. data/config/rubocop.yml +5 -9
  12. data/docs/incremental.md +76 -0
  13. data/docs/known-problems.md +0 -14
  14. data/docs/mutant-minitest.md +1 -1
  15. data/docs/mutant-rspec.md +2 -24
  16. data/lib/mutant.rb +45 -53
  17. data/lib/mutant/ast/nodes.rb +0 -2
  18. data/lib/mutant/ast/types.rb +1 -117
  19. data/lib/mutant/base.rb +192 -0
  20. data/lib/mutant/bootstrap.rb +145 -0
  21. data/lib/mutant/cli.rb +68 -54
  22. data/lib/mutant/config.rb +119 -6
  23. data/lib/mutant/env.rb +94 -8
  24. data/lib/mutant/expression.rb +6 -1
  25. data/lib/mutant/expression/parser.rb +9 -31
  26. data/lib/mutant/integration.rb +64 -36
  27. data/lib/mutant/isolation.rb +16 -1
  28. data/lib/mutant/isolation/fork.rb +105 -40
  29. data/lib/mutant/license.rb +34 -0
  30. data/lib/mutant/license/subscription.rb +47 -0
  31. data/lib/mutant/license/subscription/commercial.rb +57 -0
  32. data/lib/mutant/license/subscription/opensource.rb +77 -0
  33. data/lib/mutant/loader.rb +27 -4
  34. data/lib/mutant/matcher.rb +48 -1
  35. data/lib/mutant/matcher/chain.rb +1 -1
  36. data/lib/mutant/matcher/config.rb +0 -2
  37. data/lib/mutant/matcher/filter.rb +1 -1
  38. data/lib/mutant/matcher/method.rb +11 -7
  39. data/lib/mutant/matcher/methods.rb +1 -1
  40. data/lib/mutant/matcher/namespace.rb +1 -1
  41. data/lib/mutant/matcher/null.rb +1 -1
  42. data/lib/mutant/matcher/scope.rb +1 -1
  43. data/lib/mutant/meta/example/dsl.rb +0 -8
  44. data/lib/mutant/mutation.rb +1 -2
  45. data/lib/mutant/mutator/node.rb +2 -9
  46. data/lib/mutant/mutator/node/arguments.rb +1 -1
  47. data/lib/mutant/mutator/node/class.rb +0 -8
  48. data/lib/mutant/mutator/node/define.rb +0 -12
  49. data/lib/mutant/mutator/node/generic.rb +30 -44
  50. data/lib/mutant/mutator/node/index.rb +4 -4
  51. data/lib/mutant/mutator/node/literal/regex.rb +0 -39
  52. data/lib/mutant/mutator/node/send.rb +13 -12
  53. data/lib/mutant/parallel.rb +61 -40
  54. data/lib/mutant/parallel/driver.rb +59 -0
  55. data/lib/mutant/parallel/source.rb +6 -2
  56. data/lib/mutant/parallel/worker.rb +63 -45
  57. data/lib/mutant/range.rb +15 -0
  58. data/lib/mutant/reporter/cli.rb +5 -11
  59. data/lib/mutant/reporter/cli/format.rb +3 -46
  60. data/lib/mutant/reporter/cli/printer/config.rb +5 -6
  61. data/lib/mutant/reporter/cli/printer/env.rb +40 -0
  62. data/lib/mutant/reporter/cli/printer/env_progress.rb +13 -17
  63. data/lib/mutant/reporter/cli/printer/isolation_result.rb +17 -3
  64. data/lib/mutant/reporter/cli/printer/mutation_result.rb +2 -3
  65. data/lib/mutant/reporter/cli/printer/status_progressive.rb +19 -10
  66. data/lib/mutant/repository.rb +0 -65
  67. data/lib/mutant/repository/diff.rb +104 -0
  68. data/lib/mutant/repository/diff/ranges.rb +52 -0
  69. data/lib/mutant/result.rb +16 -7
  70. data/lib/mutant/runner.rb +38 -47
  71. data/lib/mutant/runner/sink.rb +1 -1
  72. data/lib/mutant/selector/null.rb +19 -0
  73. data/lib/mutant/subject.rb +3 -1
  74. data/lib/mutant/subject/method/instance.rb +3 -1
  75. data/lib/mutant/transform.rb +511 -0
  76. data/lib/mutant/variable.rb +282 -0
  77. data/lib/mutant/version.rb +1 -1
  78. data/lib/mutant/warnings.rb +113 -0
  79. data/meta/case.rb +1 -0
  80. data/meta/class.rb +0 -9
  81. data/meta/def.rb +1 -26
  82. data/meta/regexp.rb +10 -20
  83. data/meta/send.rb +14 -46
  84. data/mutant-minitest.gemspec +1 -1
  85. data/mutant-rspec.gemspec +2 -2
  86. data/mutant.gemspec +15 -16
  87. data/mutant.yml +6 -0
  88. data/spec/integration/mutant/isolation/fork_spec.rb +22 -5
  89. data/spec/integration/mutant/minitest_spec.rb +3 -2
  90. data/spec/integration/mutant/rspec_spec.rb +4 -3
  91. data/spec/integrations.yml +16 -13
  92. data/spec/shared/base_behavior.rb +45 -0
  93. data/spec/shared/framework_integration_behavior.rb +43 -14
  94. data/spec/spec_helper.rb +21 -17
  95. data/spec/support/corpus.rb +56 -95
  96. data/spec/support/shared_context.rb +37 -14
  97. data/spec/support/xspec.rb +7 -3
  98. data/spec/unit/mutant/bootstrap_spec.rb +216 -0
  99. data/spec/unit/mutant/cli_spec.rb +173 -117
  100. data/spec/unit/mutant/config_spec.rb +126 -0
  101. data/spec/unit/mutant/either_spec.rb +247 -0
  102. data/spec/unit/mutant/env_spec.rb +162 -40
  103. data/spec/unit/mutant/expression/method_spec.rb +16 -0
  104. data/spec/unit/mutant/expression/parser_spec.rb +29 -33
  105. data/spec/unit/mutant/expression_spec.rb +5 -7
  106. data/spec/unit/mutant/integration_spec.rb +100 -9
  107. data/spec/unit/mutant/isolation/fork_spec.rb +125 -67
  108. data/spec/unit/mutant/isolation/result_spec.rb +33 -1
  109. data/spec/unit/mutant/license_spec.rb +257 -0
  110. data/spec/unit/mutant/loader_spec.rb +50 -11
  111. data/spec/unit/mutant/matcher/compiler_spec.rb +0 -78
  112. data/spec/unit/mutant/matcher/method/instance_spec.rb +55 -11
  113. data/spec/unit/mutant/matcher/method/singleton_spec.rb +12 -2
  114. data/spec/unit/mutant/matcher_spec.rb +102 -0
  115. data/spec/unit/mutant/maybe_spec.rb +60 -0
  116. data/spec/unit/mutant/meta/example/dsl_spec.rb +1 -17
  117. data/spec/unit/mutant/mutation_spec.rb +13 -6
  118. data/spec/unit/mutant/parallel/driver_spec.rb +112 -14
  119. data/spec/unit/mutant/parallel/source/array_spec.rb +25 -17
  120. data/spec/unit/mutant/parallel/worker_spec.rb +182 -44
  121. data/spec/unit/mutant/parallel_spec.rb +105 -8
  122. data/spec/unit/mutant/range_spec.rb +141 -0
  123. data/spec/unit/mutant/reporter/cli/printer/config_spec.rb +7 -21
  124. data/spec/unit/mutant/reporter/cli/printer/env_progress_spec.rb +15 -6
  125. data/spec/unit/mutant/reporter/cli/printer/env_result_spec.rb +10 -2
  126. data/spec/unit/mutant/reporter/cli/printer/isolation_result_spec.rb +12 -4
  127. data/spec/unit/mutant/reporter/cli/printer/mutation_result_spec.rb +31 -2
  128. data/spec/unit/mutant/reporter/cli/printer/status_progressive_spec.rb +4 -4
  129. data/spec/unit/mutant/reporter/cli/printer/subject_result_spec.rb +5 -0
  130. data/spec/unit/mutant/reporter/cli_spec.rb +46 -123
  131. data/spec/unit/mutant/repository/diff/ranges_spec.rb +180 -0
  132. data/spec/unit/mutant/repository/diff_spec.rb +84 -71
  133. data/spec/unit/mutant/require_highjack_spec.rb +1 -1
  134. data/spec/unit/mutant/result/env_spec.rb +39 -9
  135. data/spec/unit/mutant/result/test_spec.rb +14 -0
  136. data/spec/unit/mutant/runner_spec.rb +88 -41
  137. data/spec/unit/mutant/selector/expression_spec.rb +11 -10
  138. data/spec/unit/mutant/selector/null_spec.rb +17 -0
  139. data/spec/unit/mutant/subject/method/instance_spec.rb +44 -5
  140. data/spec/unit/mutant/subject/method/singleton_spec.rb +9 -2
  141. data/spec/unit/mutant/subject_spec.rb +9 -1
  142. data/spec/unit/mutant/transform/array_spec.rb +92 -0
  143. data/spec/unit/mutant/transform/bool_spec.rb +63 -0
  144. data/spec/unit/mutant/transform/error_spec.rb +132 -0
  145. data/spec/unit/mutant/transform/exception_spec.rb +44 -0
  146. data/spec/unit/mutant/transform/hash_spec.rb +236 -0
  147. data/spec/unit/mutant/transform/index_spec.rb +92 -0
  148. data/spec/unit/mutant/transform/named_spec.rb +49 -0
  149. data/spec/unit/mutant/transform/primitive_spec.rb +56 -0
  150. data/spec/unit/mutant/transform/sequence_spec.rb +98 -0
  151. data/spec/unit/mutant/variable_spec.rb +618 -0
  152. data/spec/unit/mutant/warnings_spec.rb +89 -0
  153. data/spec/unit/mutant/world_spec.rb +63 -0
  154. data/test_app/Gemfile.minitest +0 -2
  155. metadata +79 -113
  156. data/.gitattributes +0 -1
  157. data/.ruby-gemset +0 -1
  158. data/config/triage.yml +0 -2
  159. data/lib/mutant/actor.rb +0 -57
  160. data/lib/mutant/actor/env.rb +0 -31
  161. data/lib/mutant/actor/mailbox.rb +0 -34
  162. data/lib/mutant/actor/receiver.rb +0 -42
  163. data/lib/mutant/actor/sender.rb +0 -26
  164. data/lib/mutant/ast/meta/restarg.rb +0 -19
  165. data/lib/mutant/ast/regexp.rb +0 -42
  166. data/lib/mutant/ast/regexp/transformer.rb +0 -187
  167. data/lib/mutant/ast/regexp/transformer/direct.rb +0 -123
  168. data/lib/mutant/ast/regexp/transformer/named_group.rb +0 -59
  169. data/lib/mutant/ast/regexp/transformer/options_group.rb +0 -83
  170. data/lib/mutant/ast/regexp/transformer/quantifier.rb +0 -114
  171. data/lib/mutant/ast/regexp/transformer/recursive.rb +0 -58
  172. data/lib/mutant/ast/regexp/transformer/root.rb +0 -31
  173. data/lib/mutant/ast/regexp/transformer/text.rb +0 -60
  174. data/lib/mutant/env/bootstrap.rb +0 -160
  175. data/lib/mutant/matcher/compiler.rb +0 -60
  176. data/lib/mutant/mutator/node/regexp.rb +0 -35
  177. data/lib/mutant/mutator/node/regexp/alternation_meta.rb +0 -23
  178. data/lib/mutant/mutator/node/regexp/capture_group.rb +0 -28
  179. data/lib/mutant/mutator/node/regexp/character_type.rb +0 -32
  180. data/lib/mutant/mutator/node/regexp/end_of_line_anchor.rb +0 -23
  181. data/lib/mutant/mutator/node/regexp/end_of_string_or_before_end_of_line_anchor.rb +0 -23
  182. data/lib/mutant/mutator/node/regexp/greedy_zero_or_more.rb +0 -27
  183. data/lib/mutant/parallel/master.rb +0 -181
  184. data/lib/mutant/reporter/cli/printer/status.rb +0 -53
  185. data/lib/mutant/reporter/cli/tput.rb +0 -46
  186. data/lib/mutant/warning_filter.rb +0 -61
  187. data/meta/regexp/character_types.rb +0 -23
  188. data/meta/regexp/regexp_alternation_meta.rb +0 -13
  189. data/meta/regexp/regexp_bol_anchor.rb +0 -10
  190. data/meta/regexp/regexp_bos_anchor.rb +0 -18
  191. data/meta/regexp/regexp_capture_group.rb +0 -19
  192. data/meta/regexp/regexp_eol_anchor.rb +0 -10
  193. data/meta/regexp/regexp_eos_anchor.rb +0 -8
  194. data/meta/regexp/regexp_eos_ob_eol_anchor.rb +0 -10
  195. data/meta/regexp/regexp_greedy_zero_or_more.rb +0 -12
  196. data/meta/regexp/regexp_root_expression.rb +0 -10
  197. data/meta/restarg.rb +0 -10
  198. data/spec/support/fake_actor.rb +0 -111
  199. data/spec/support/warning.rb +0 -66
  200. data/spec/unit/mutant/actor/binding_spec.rb +0 -34
  201. data/spec/unit/mutant/actor/env_spec.rb +0 -31
  202. data/spec/unit/mutant/actor/mailbox_spec.rb +0 -28
  203. data/spec/unit/mutant/actor/message_spec.rb +0 -25
  204. data/spec/unit/mutant/actor/receiver_spec.rb +0 -58
  205. data/spec/unit/mutant/actor/sender_spec.rb +0 -24
  206. data/spec/unit/mutant/ast/regexp/parse_spec.rb +0 -19
  207. data/spec/unit/mutant/ast/regexp/transformer/lookup_table/table_spec.rb +0 -21
  208. data/spec/unit/mutant/ast/regexp/transformer/lookup_table_spec.rb +0 -35
  209. data/spec/unit/mutant/ast/regexp/transformer_spec.rb +0 -21
  210. data/spec/unit/mutant/ast/regexp_spec.rb +0 -704
  211. data/spec/unit/mutant/env/bootstrap_spec.rb +0 -188
  212. data/spec/unit/mutant/matcher/compiler/subject_prefix_spec.rb +0 -26
  213. data/spec/unit/mutant/parallel/master_spec.rb +0 -338
  214. data/spec/unit/mutant/reporter/cli/printer/status_spec.rb +0 -121
  215. data/spec/unit/mutant/reporter/cli/tput_spec.rb +0 -50
  216. data/spec/unit/mutant/warning_filter_spec.rb +0 -106
  217. data/spec/unit/mutant_spec.rb +0 -17
  218. data/test_app/Gemfile.rspec3.7 +0 -7
@@ -1,123 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Mutant
4
- module 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
- # rubocop:disable LineLength
40
- TABLE = Table.create(
41
- [:regexp_alnum_posixclass, [:posixclass, :alnum, '[:alnum:]'], ::Regexp::Expression::PosixClass],
42
- [:regexp_alpha_posixclass, [:posixclass, :alpha, '[:alpha:]'], ::Regexp::Expression::PosixClass],
43
- [:regexp_alpha_property, [:property, :alpha, '\p{Alpha}'], ::Regexp::Expression::UnicodeProperty::Alpha],
44
- [:regexp_alternation_escape, [:escape, :alternation, '\|'], ::Regexp::Expression::EscapeSequence::Literal],
45
- [:regexp_arabic_property, [:property, :arabic, '\p{Arabic}'], ::Regexp::Expression::UnicodeProperty::Script],
46
- [:regexp_ascii_posixclass, [:posixclass, :ascii, '[:ascii:]'], ::Regexp::Expression::PosixClass],
47
- [:regexp_backspace_escape, [:escape, :backspace, '\b'], ::Regexp::Expression::EscapeSequence::Backspace],
48
- [:regexp_bell_escape, [:escape, :bell, '\a'], ::Regexp::Expression::EscapeSequence::Literal],
49
- [:regexp_blank_posixclass, [:posixclass, :blank, '[:blank:]'], ::Regexp::Expression::PosixClass],
50
- [:regexp_bol_anchor, [:anchor, :bol, '^'], ::Regexp::Expression::Anchor::BeginningOfLine],
51
- [:regexp_bol_escape, [:escape, :bol, '\^'], ::Regexp::Expression::EscapeSequence::Literal],
52
- [:regexp_bos_anchor, [:anchor, :bos, '\\A'], ::Regexp::Expression::Anchor::BeginningOfString],
53
- [:regexp_carriage_escape, [:escape, :carriage, '\r'], ::Regexp::Expression::EscapeSequence::Literal],
54
- [:regexp_cntrl_posixclass, [:posixclass, :cntrl, '[:cntrl:]'], ::Regexp::Expression::PosixClass],
55
- [:regexp_digit_posixclass, [:posixclass, :digit, '[:digit:]'], ::Regexp::Expression::PosixClass],
56
- [:regexp_digit_type, [:type, :digit, '\d'], ::Regexp::Expression::CharacterType::Digit],
57
- [:regexp_dot_escape, [:escape, :dot, '\.'], ::Regexp::Expression::EscapeSequence::Literal],
58
- [:regexp_dot_meta, [:meta, :dot, '.'], ::Regexp::Expression::CharacterType::Any],
59
- [:regexp_eol_anchor, [:anchor, :eol, '$'], ::Regexp::Expression::Anchor::EndOfLine],
60
- [:regexp_eol_escape, [:escape, :eol, '\$'], ::Regexp::Expression::EscapeSequence::Literal],
61
- [:regexp_eos_anchor, [:anchor, :eos, '\\z'], ::Regexp::Expression::Anchor::EndOfString],
62
- [:regexp_eos_ob_eol_anchor, [:anchor, :eos_ob_eol, '\\Z'], ::Regexp::Expression::Anchor::EndOfStringOrBeforeEndOfLine],
63
- [:regexp_escape_escape, [:escape, :escape, '\e'], ::Regexp::Expression::EscapeSequence::AsciiEscape],
64
- [:regexp_form_feed_escape, [:escape, :form_feed, '\f'], ::Regexp::Expression::EscapeSequence::FormFeed],
65
- [:regexp_graph_posixclass, [:posixclass, :graph, '[:graph:]'], ::Regexp::Expression::PosixClass],
66
- [:regexp_group_close_escape, [:escape, :group_close, '\)'], ::Regexp::Expression::EscapeSequence::Literal],
67
- [:regexp_group_open_escape, [:escape, :group_open, '\('], ::Regexp::Expression::EscapeSequence::Literal],
68
- [:regexp_han_property, [:property, :han, '\p{Han}'], ::Regexp::Expression::UnicodeProperty::Script],
69
- [:regexp_hangul_property, [:property, :hangul, '\p{Hangul}'], ::Regexp::Expression::UnicodeProperty::Script],
70
- [:regexp_hex_type, [:type, :hex, '\h'], ::Regexp::Expression::CharacterType::Hex],
71
- [:regexp_hiragana_property, [:property, :hiragana, '\p{Hiragana}'], ::Regexp::Expression::UnicodeProperty::Script],
72
- [:regexp_interval_close_escape, [:escape, :interval_close, '\}'], ::Regexp::Expression::EscapeSequence::Literal],
73
- [:regexp_interval_open_escape, [:escape, :interval_open, '\{'], ::Regexp::Expression::EscapeSequence::Literal],
74
- [:regexp_katakana_property, [:property, :katakana, '\p{Katakana}'], ::Regexp::Expression::UnicodeProperty::Script],
75
- [:regexp_letter_property, [:property, :letter, '\p{L}'], ::Regexp::Expression::UnicodeProperty::Letter::Any],
76
- [:regexp_linebreak_type, [:type, :linebreak, '\R'], ::Regexp::Expression::CharacterType::Linebreak],
77
- [:regexp_lower_posixclass, [:posixclass, :lower, '[:lower:]'], ::Regexp::Expression::PosixClass],
78
- [:regexp_mark_keep, [:keep, :mark, '\K'], ::Regexp::Expression::Keep::Mark],
79
- [:regexp_match_start_anchor, [:anchor, :match_start, '\\G'], ::Regexp::Expression::Anchor::MatchStart],
80
- [:regexp_newline_escape, [:escape, :newline, '\n'], ::Regexp::Expression::EscapeSequence::Literal],
81
- [:regexp_nondigit_type, [:type, :nondigit, '\D'], ::Regexp::Expression::CharacterType::NonDigit],
82
- [:regexp_nonhex_type, [:type, :nonhex, '\H'], ::Regexp::Expression::CharacterType::NonHex],
83
- [:regexp_nonspace_type, [:type, :nonspace, '\S'], ::Regexp::Expression::CharacterType::NonSpace],
84
- [:regexp_nonword_boundary_anchor, [:anchor, :nonword_boundary, '\\B'], ::Regexp::Expression::Anchor::NonWordBoundary],
85
- [:regexp_nonword_type, [:type, :nonword, '\W'], ::Regexp::Expression::CharacterType::NonWord],
86
- [:regexp_one_or_more_escape, [:escape, :one_or_more, '\+'], ::Regexp::Expression::EscapeSequence::Literal],
87
- [:regexp_print_nonposixclass, [:nonposixclass, :print, '[:^print:]'], ::Regexp::Expression::PosixClass],
88
- [:regexp_print_nonproperty, [:nonproperty, :print, '\P{Print}'], ::Regexp::Expression::UnicodeProperty::Print],
89
- [:regexp_print_posixclass, [:posixclass, :print, '[:print:]'], ::Regexp::Expression::PosixClass],
90
- [:regexp_print_posixclass, [:posixclass, :print, '[:print:]'], ::Regexp::Expression::PosixClass],
91
- [:regexp_print_property, [:property, :print, '\p{Print}'], ::Regexp::Expression::UnicodeProperty::Print],
92
- [:regexp_punct_posixclass, [:posixclass, :punct, '[:punct:]'], ::Regexp::Expression::PosixClass],
93
- [:regexp_set_close_escape, [:escape, :set_close, '\]'], ::Regexp::Expression::EscapeSequence::Literal],
94
- [:regexp_set_open_escape, [:escape, :set_open, '\['], ::Regexp::Expression::EscapeSequence::Literal],
95
- [:regexp_space_posixclass, [:posixclass, :space, '[:space:]'], ::Regexp::Expression::PosixClass],
96
- [:regexp_space_type, [:type, :space, '\s'], ::Regexp::Expression::CharacterType::Space],
97
- [:regexp_upper_posixclass, [:posixclass, :upper, '[:upper:]'], ::Regexp::Expression::PosixClass],
98
- [:regexp_vertical_tab_escape, [:escape, :vertical_tab, '\v'], ::Regexp::Expression::EscapeSequence::VerticalTab],
99
- [:regexp_word_boundary_anchor, [:anchor, :word_boundary, '\b'], ::Regexp::Expression::Anchor::WordBoundary],
100
- [:regexp_word_posixclass, [:posixclass, :word, '[:word:]'], ::Regexp::Expression::PosixClass],
101
- [:regexp_word_type, [:type, :word, '\w'], ::Regexp::Expression::CharacterType::Word],
102
- [:regexp_xdigit_posixclass, [:posixclass, :xdigit, '[:xdigit:]'], ::Regexp::Expression::PosixClass],
103
- [:regexp_xgrapheme_type, [:type, :xgrapheme, '\X'], ::Regexp::Expression::CharacterType::ExtendedGrapheme],
104
- [:regexp_zero_or_more_escape, [:escape, :zero_or_more, '\*'], ::Regexp::Expression::EscapeSequence::Literal],
105
- [:regexp_zero_or_one_escape, [:escape, :zero_or_one, '\?'], ::Regexp::Expression::EscapeSequence::Literal]
106
- )
107
-
108
- private
109
-
110
- # Transform ast into expression
111
- #
112
- # @return [Regexp::Expression]
113
- def transform
114
- expression_class.new(expression_token)
115
- end
116
- end # ASTToExpression
117
-
118
- ASTToExpression::TABLE.types.each(&method(:register))
119
- end # Direct
120
- end # Transformer
121
- end # Regexp
122
- end # AST
123
- end # Mutant
@@ -1,59 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Mutant
4
- module 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
- # Convert node into expression
31
- #
32
- # @return [Regexp::Expression::Group::Named]
33
- def transform
34
- named_group.tap do |expression|
35
- expression.expressions = subexpressions
36
- end
37
- end
38
-
39
- # Recursive mapping of children
40
- #
41
- # @return [Array<Regexp::Expression>]
42
- def subexpressions
43
- remaining_children.map(&Regexp.public_method(:to_expression))
44
- end
45
-
46
- # Named group instance constructed using name
47
- #
48
- # @return [Regexp::Expression::Group::Named]
49
- def named_group
50
- ::Regexp::Expression::Group::Named.new(
51
- ::Regexp::Token.new(:group, :named, "(?<#{name}>")
52
- )
53
- end
54
- end # ASTToExpression
55
- end # NamedGroup
56
- end # Transformer
57
- end # Regexp
58
- end # AST
59
- end # Mutant
@@ -1,83 +0,0 @@
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
- # Convert node into expression
32
- #
33
- # @return [Regexp::Expression::Group::Options]
34
- def transform
35
- options_group.tap do |expression|
36
- expression.expressions = subexpressions
37
- end
38
- end
39
-
40
- # Recursive mapping of children
41
- #
42
- # @return [Array<Regexp::Expression>]
43
- def subexpressions
44
- remaining_children.map(&Regexp.public_method(:to_expression))
45
- end
46
-
47
- # Options group instance constructed from options text
48
- #
49
- # @return [Regexp::Expression::Group::Options]
50
- def options_group
51
- ::Regexp::Expression::Group::Options.new(
52
- ::Regexp::Token.new(:group, type, text)
53
- )
54
- end
55
-
56
- # Options group type derived from node type
57
- #
58
- # @return [Symbol]
59
- def type
60
- {
61
- regexp_options_group: :options,
62
- regexp_options_switch_group: :options_switch
63
- }.fetch(node.type)
64
- end
65
-
66
- # Flag text constructed from enabled and disabled options
67
- #
68
- # @return [String]
69
- def text
70
- pos, neg = option_changes.partition { |_opt, val| val }.map do |arr|
71
- arr.map(&:first).join
72
- end
73
- neg_opt_sep = '-' unless neg.empty?
74
- content_sep = ':' unless type.equal?(:options_switch)
75
-
76
- "(?#{pos}#{neg_opt_sep}#{neg}#{content_sep}"
77
- end
78
- end # ASTToExpression
79
- end # OptionsGroup
80
- end # Transformer
81
- end # Regexp
82
- end # AST
83
- end # Mutant
@@ -1,114 +0,0 @@
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
- # Custom `type` for quantifiers which use `mode` instead of `type`
21
- #
22
- # @return [Symbol]
23
- def type
24
- :"regexp_#{expression.mode}_#{expression.token}"
25
- end
26
- end # ExpressionToAST
27
-
28
- # Mapper from `Parser::AST::Node` to `Regexp::Expression`
29
- class ASTToExpression < Transformer::ASTToExpression
30
- include NamedChildren
31
-
32
- children :min, :max, :subject
33
-
34
- Quantifier = Class.new.include(Concord::Public.new(:type, :suffix, :mode))
35
-
36
- QUANTIFIER_MAP = IceNine.deep_freeze({
37
- regexp_greedy_zero_or_more: [:zero_or_more, '*', :greedy],
38
- regexp_greedy_one_or_more: [:one_or_more, '+', :greedy],
39
- regexp_greedy_zero_or_one: [:zero_or_one, '?', :greedy],
40
- regexp_possessive_zero_or_one: [:zero_or_one, '?+', :possessive],
41
- regexp_reluctant_zero_or_more: [:zero_or_more, '*?', :reluctant],
42
- regexp_reluctant_one_or_more: [:one_or_more, '+?', :reluctant],
43
- regexp_possessive_zero_or_more: [:zero_or_more, '*+', :possessive],
44
- regexp_possessive_one_or_more: [:one_or_more, '++', :possessive],
45
- regexp_greedy_interval: [:interval, '', :greedy],
46
- regexp_reluctant_interval: [:interval, '?', :reluctant],
47
- regexp_possessive_interval: [:interval, '+', :possessive]
48
- }.map { |ast_type, arguments| [ast_type, Quantifier.new(*arguments)] }.to_h)
49
-
50
- private
51
-
52
- # Transform ast into quantifier attached to expression
53
- #
54
- # @return [Regexp::Expression]
55
- def transform
56
- Regexp.to_expression(subject).dup.tap do |expression|
57
- expression.quantify(type, text, min, max, mode)
58
- end
59
- end
60
-
61
- # Quantifier text
62
- #
63
- # @return [String]
64
- def text
65
- if type.equal?(:interval)
66
- interval_text + suffix
67
- else
68
- suffix
69
- end
70
- end
71
-
72
- # Type of quantifier
73
- #
74
- # @return [:zero_or_more,:one_or_more,:interval]
75
- def type
76
- quantifier.type
77
- end
78
-
79
- # Regexp symbols used to specify quantifier
80
- #
81
- # @return [String]
82
- def suffix
83
- quantifier.suffix
84
- end
85
-
86
- # The quantifier "mode"
87
- #
88
- # @return [:greedy,:possessive,:reluctant]
89
- def mode
90
- quantifier.mode
91
- end
92
-
93
- # Quantifier mapping information for current node
94
- #
95
- # @return [Quantifier]
96
- def quantifier
97
- QUANTIFIER_MAP.fetch(node.type)
98
- end
99
-
100
- # Interval text constructed from min and max
101
- #
102
- # @return [String]
103
- def interval_text
104
- interval = [min, max].map { |num| num if num.positive? }.uniq
105
- "{#{interval.join(',')}}"
106
- end
107
- end # ASTToExpression
108
-
109
- ASTToExpression::QUANTIFIER_MAP.keys.each(&method(:register))
110
- end # Quantifier
111
- end # Transformer
112
- end # Regexp
113
- end # AST
114
- end # Mutant
@@ -1,58 +0,0 @@
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
- # rubocop:disable LineLength
24
- # Expression::Sequence represents conditional branches, alternation branches, and intersection branches
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
-
41
- private
42
-
43
- # Transform nodes and their children into expressions
44
- #
45
- # @return [Regexp::Expression]
46
- def transform
47
- expression_class.new(expression_token).tap do |expression|
48
- expression.expressions = subexpressions
49
- end
50
- end
51
- end # ASTToExpression
52
-
53
- ASTToExpression::TABLE.types.each(&method(:register))
54
- end # Recursive
55
- end # Transformer
56
- end # Regexp
57
- end # AST
58
- end # Mutant
@@ -1,31 +0,0 @@
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
- # Transform node into root expression
19
- #
20
- # @return [Regexp::Expression::Root]
21
- def transform
22
- ::Regexp::Expression::Root.build.tap do |root|
23
- root.expressions = subexpressions
24
- end
25
- end
26
- end # ASTToExpression
27
- end # Root
28
- end # Transformer
29
- end # Regexp
30
- end # AST
31
- end # Mutant