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