mutant 0.11.13 → 0.11.14
Sign up to get free protection for your applications and to get access to all the features.
- 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: ''
|