deep-cover 0.5.2 → 0.5.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/.deep_cover.rb +8 -0
- data/.gitignore +1 -0
- data/.rubocop.yml +15 -1
- data/.travis.yml +1 -0
- data/README.md +30 -1
- data/Rakefile +10 -1
- data/bin/cov +1 -1
- data/deep_cover.gemspec +4 -5
- data/exe/deep-cover +5 -3
- data/lib/deep_cover.rb +1 -1
- data/lib/deep_cover/analyser/node.rb +1 -1
- data/lib/deep_cover/analyser/ruby25_like_branch.rb +209 -0
- data/lib/deep_cover/auto_run.rb +19 -19
- data/lib/deep_cover/autoload_tracker.rb +181 -44
- data/lib/deep_cover/backports.rb +3 -1
- data/lib/deep_cover/base.rb +13 -8
- data/lib/deep_cover/basics.rb +1 -1
- data/lib/deep_cover/cli/debugger.rb +2 -2
- data/lib/deep_cover/cli/instrumented_clone_reporter.rb +21 -8
- data/lib/deep_cover/cli/runner.rb +126 -0
- data/lib/deep_cover/config_setter.rb +1 -0
- data/lib/deep_cover/core_ext/autoload_overrides.rb +82 -14
- data/lib/deep_cover/core_ext/coverage_replacement.rb +34 -5
- data/lib/deep_cover/core_ext/exec_callbacks.rb +27 -0
- data/lib/deep_cover/core_ext/load_overrides.rb +4 -6
- data/lib/deep_cover/core_ext/require_overrides.rb +1 -3
- data/lib/deep_cover/coverage.rb +105 -2
- data/lib/deep_cover/coverage/analysis.rb +30 -28
- data/lib/deep_cover/coverage/persistence.rb +60 -70
- data/lib/deep_cover/covered_code.rb +16 -49
- data/lib/deep_cover/custom_requirer.rb +112 -51
- data/lib/deep_cover/load.rb +10 -6
- data/lib/deep_cover/memoize.rb +1 -3
- data/lib/deep_cover/module_override.rb +7 -0
- data/lib/deep_cover/node/assignments.rb +2 -1
- data/lib/deep_cover/node/base.rb +6 -6
- data/lib/deep_cover/node/block.rb +10 -8
- data/lib/deep_cover/node/case.rb +3 -3
- data/lib/deep_cover/node/collections.rb +8 -0
- data/lib/deep_cover/node/if.rb +19 -3
- data/lib/deep_cover/node/literals.rb +28 -7
- data/lib/deep_cover/node/mixin/can_augment_children.rb +4 -4
- data/lib/deep_cover/node/mixin/child_can_be_empty.rb +1 -1
- data/lib/deep_cover/node/mixin/filters.rb +6 -2
- data/lib/deep_cover/node/mixin/has_child.rb +8 -8
- data/lib/deep_cover/node/mixin/has_child_handler.rb +3 -3
- data/lib/deep_cover/node/mixin/has_tracker.rb +7 -3
- data/lib/deep_cover/node/root.rb +1 -1
- data/lib/deep_cover/node/send.rb +53 -7
- data/lib/deep_cover/node/short_circuit.rb +11 -3
- data/lib/deep_cover/parser_ext/range.rb +11 -27
- data/lib/deep_cover/problem_with_diagnostic.rb +1 -1
- data/lib/deep_cover/reporter.rb +0 -1
- data/lib/deep_cover/reporter/base.rb +68 -0
- data/lib/deep_cover/reporter/html.rb +1 -1
- data/lib/deep_cover/reporter/html/index.rb +4 -8
- data/lib/deep_cover/reporter/html/site.rb +10 -18
- data/lib/deep_cover/reporter/html/source.rb +3 -3
- data/lib/deep_cover/reporter/html/template/source.html.erb +1 -1
- data/lib/deep_cover/reporter/istanbul.rb +86 -56
- data/lib/deep_cover/reporter/text.rb +5 -13
- data/lib/deep_cover/reporter/{util/tree.rb → tree/util.rb} +19 -21
- data/lib/deep_cover/tools/blank.rb +25 -0
- data/lib/deep_cover/tools/builtin_coverage.rb +8 -8
- data/lib/deep_cover/tools/dump_covered_code.rb +2 -9
- data/lib/deep_cover/tools/execute_sample.rb +17 -6
- data/lib/deep_cover/tools/format_generated_code.rb +1 -1
- data/lib/deep_cover/tools/indent_string.rb +26 -0
- data/lib/deep_cover/tools/our_coverage.rb +2 -2
- data/lib/deep_cover/tools/strip_heredoc.rb +18 -0
- data/lib/deep_cover/tracker_bucket.rb +50 -0
- data/lib/deep_cover/tracker_hits_per_path.rb +35 -0
- data/lib/deep_cover/tracker_storage.rb +76 -0
- data/lib/deep_cover/tracker_storage_per_path.rb +34 -0
- data/lib/deep_cover/version.rb +1 -1
- data/lib/deep_cover_entry.rb +3 -0
- metadata +30 -37
- data/bin/gemcov +0 -8
- data/bin/selfcov +0 -21
- data/lib/deep_cover/cli/deep_cover.rb +0 -126
- data/lib/deep_cover/coverage/base.rb +0 -81
- data/lib/deep_cover/coverage/istanbul.rb +0 -34
- data/lib/deep_cover/tools/transform_keys.rb +0 -9
@@ -2,6 +2,7 @@
|
|
2
2
|
|
3
3
|
require_relative 'const'
|
4
4
|
require_relative 'literals'
|
5
|
+
require_relative 'keywords'
|
5
6
|
|
6
7
|
module DeepCover
|
7
8
|
class Node
|
@@ -18,7 +19,7 @@ module DeepCover
|
|
18
19
|
Cvasgn = Gvasgn = Ivasgn = Lvasgn = VariableAssignment
|
19
20
|
|
20
21
|
class Casgn < Node
|
21
|
-
has_child cbase: [Cbase, Const, nil, Self]
|
22
|
+
has_child cbase: [Cbase, Const, nil, Self, Begin, Kwbegin]
|
22
23
|
has_child var_name: Symbol
|
23
24
|
has_child value: [Node, nil]
|
24
25
|
|
data/lib/deep_cover/node/base.rb
CHANGED
@@ -52,18 +52,18 @@ module DeepCover
|
|
52
52
|
end
|
53
53
|
|
54
54
|
# Shortcut to access children
|
55
|
-
def [](
|
56
|
-
if
|
57
|
-
children.fetch(
|
55
|
+
def [](lookup)
|
56
|
+
if lookup.is_a?(Integer)
|
57
|
+
children.fetch(lookup)
|
58
58
|
else
|
59
|
-
found = find_all(
|
59
|
+
found = find_all(lookup)
|
60
60
|
case found.size
|
61
61
|
when 1
|
62
62
|
found.first
|
63
63
|
when 0
|
64
|
-
raise "No children of type #{
|
64
|
+
raise "No children of type #{lookup}"
|
65
65
|
else
|
66
|
-
raise "Ambiguous lookup #{
|
66
|
+
raise "Ambiguous lookup #{lookup}, found #{found}."
|
67
67
|
end
|
68
68
|
end
|
69
69
|
end
|
@@ -21,11 +21,6 @@ module DeepCover
|
|
21
21
|
include WithBlock
|
22
22
|
end
|
23
23
|
|
24
|
-
class CsendWithBlock < Csend
|
25
|
-
include WithBlock
|
26
|
-
refine_child actual_send: {safe_send: SendWithBlock}
|
27
|
-
end
|
28
|
-
|
29
24
|
class SuperWithBlock < Node
|
30
25
|
include WithBlock
|
31
26
|
has_extra_children arguments: Node
|
@@ -34,9 +29,7 @@ module DeepCover
|
|
34
29
|
class Block < Node
|
35
30
|
check_completion
|
36
31
|
has_tracker :body
|
37
|
-
has_child call: {send: SendWithBlock, csend:
|
38
|
-
zsuper: SuperWithBlock, super: SuperWithBlock,
|
39
|
-
}
|
32
|
+
has_child call: {send: SendWithBlock, zsuper: SuperWithBlock, super: SuperWithBlock, csend: Csend}
|
40
33
|
has_child args: Args
|
41
34
|
has_child body: Node,
|
42
35
|
can_be_empty: -> { base_node.loc.end.begin },
|
@@ -48,6 +41,15 @@ module DeepCover
|
|
48
41
|
def children_nodes_in_flow_order
|
49
42
|
[call, args] # Similarly to a def, the body is actually not part of the flow of this node...
|
50
43
|
end
|
44
|
+
|
45
|
+
alias_method :rewrite_for_completion, :rewrite
|
46
|
+
def rewrite
|
47
|
+
if call.is_a?(Csend)
|
48
|
+
rewrite_for_completion.gsub('%{node}', Csend::REWRITE_SUFFIX)
|
49
|
+
else
|
50
|
+
rewrite_for_completion
|
51
|
+
end
|
52
|
+
end
|
51
53
|
end
|
52
54
|
|
53
55
|
# &foo
|
data/lib/deep_cover/node/case.rb
CHANGED
@@ -89,10 +89,10 @@ module DeepCover
|
|
89
89
|
whens.map(&:body) << self.else
|
90
90
|
end
|
91
91
|
|
92
|
-
def branches_summary(
|
92
|
+
def branches_summary(of_branches = branches)
|
93
93
|
texts = []
|
94
|
-
n =
|
95
|
-
if
|
94
|
+
n = of_branches.size
|
95
|
+
if of_branches.include? self.else
|
96
96
|
texts << "#{'implicit ' unless has_else?}else"
|
97
97
|
n -= 1
|
98
98
|
end
|
@@ -4,7 +4,14 @@ require_relative 'splat'
|
|
4
4
|
|
5
5
|
module DeepCover
|
6
6
|
class Node
|
7
|
+
module SimpleIfEmpty
|
8
|
+
def simple_literal?
|
9
|
+
children.empty?
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
7
13
|
class Array < Node
|
14
|
+
include SimpleIfEmpty
|
8
15
|
has_extra_children elements: Node
|
9
16
|
executed_loc_keys :begin, :end
|
10
17
|
end
|
@@ -16,6 +23,7 @@ module DeepCover
|
|
16
23
|
end
|
17
24
|
|
18
25
|
class Hash < Node
|
26
|
+
include SimpleIfEmpty
|
19
27
|
has_extra_children elements: [Pair, Kwsplat]
|
20
28
|
executed_loc_keys :begin, :end
|
21
29
|
end
|
data/lib/deep_cover/node/if.rb
CHANGED
@@ -20,7 +20,7 @@ module DeepCover
|
|
20
20
|
|
21
21
|
def child_can_be_empty(child, name)
|
22
22
|
return false if name == :condition || style == :ternary
|
23
|
-
if (name == :true_branch) == (style
|
23
|
+
if (name == :true_branch) == [:if, :elsif].include?(style)
|
24
24
|
(base_node.loc.begin || base_node.children[0].loc.expression.succ).end
|
25
25
|
elsif has_else?
|
26
26
|
base_node.loc.else.end.succ
|
@@ -33,8 +33,8 @@ module DeepCover
|
|
33
33
|
[true_branch, false_branch]
|
34
34
|
end
|
35
35
|
|
36
|
-
def branches_summary(
|
37
|
-
|
36
|
+
def branches_summary(of_branches = branches)
|
37
|
+
of_branches.map do |jump|
|
38
38
|
"#{'implicit ' if jump.is_a?(EmptyBody) && !has_else?}#{jump == false_branch ? 'falsy' : 'truthy'} branch"
|
39
39
|
end.join(' and ')
|
40
40
|
end
|
@@ -49,6 +49,22 @@ module DeepCover
|
|
49
49
|
keyword ? keyword.source.to_sym : :ternary
|
50
50
|
end
|
51
51
|
|
52
|
+
def root_if_node
|
53
|
+
if style != :elsif
|
54
|
+
self
|
55
|
+
else
|
56
|
+
parent.root_if_node
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def deepest_elsif_node
|
61
|
+
return if style != :elsif
|
62
|
+
return self if loc_hash[:else] && loc_hash[:else].source == 'else'
|
63
|
+
return self if false_branch.is_a?(EmptyBody)
|
64
|
+
false_branch.deepest_elsif_node
|
65
|
+
end
|
66
|
+
|
67
|
+
|
52
68
|
def has_else?
|
53
69
|
!!base_node.loc.to_hash[:else]
|
54
70
|
end
|
@@ -2,19 +2,30 @@
|
|
2
2
|
|
3
3
|
require_relative 'begin'
|
4
4
|
require_relative 'variables'
|
5
|
+
require_relative 'collections'
|
5
6
|
module DeepCover
|
6
7
|
class Node
|
7
|
-
|
8
|
-
|
8
|
+
def simple_literal?
|
9
|
+
false
|
10
|
+
end
|
11
|
+
|
12
|
+
class StaticLiteral < Node
|
9
13
|
executed_loc_keys :expression
|
14
|
+
|
15
|
+
def simple_literal?
|
16
|
+
true
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
# Singletons
|
21
|
+
class SingletonLiteral < StaticLiteral
|
10
22
|
end
|
11
23
|
True = False = Nil = Self = SingletonLiteral
|
12
24
|
|
13
25
|
# Atoms
|
14
26
|
def self.atom(type)
|
15
|
-
::Class.new(
|
27
|
+
::Class.new(StaticLiteral) do
|
16
28
|
has_child value: type
|
17
|
-
executed_loc_keys :expression
|
18
29
|
end
|
19
30
|
end
|
20
31
|
Sym = atom(::Symbol)
|
@@ -22,12 +33,11 @@ module DeepCover
|
|
22
33
|
Float = atom(::Float)
|
23
34
|
Complex = atom(::Complex)
|
24
35
|
Rational = atom(::Rational)
|
25
|
-
class Regopt <
|
36
|
+
class Regopt < StaticLiteral
|
26
37
|
has_extra_children options: [::Symbol]
|
27
|
-
executed_loc_keys :expression
|
28
38
|
end
|
29
39
|
|
30
|
-
class Str <
|
40
|
+
class Str < StaticLiteral
|
31
41
|
has_child value: ::String
|
32
42
|
|
33
43
|
def executed_loc_keys
|
@@ -43,8 +53,17 @@ module DeepCover
|
|
43
53
|
end
|
44
54
|
end
|
45
55
|
|
56
|
+
# (Potentially) dynamic
|
57
|
+
module SimpleIfItsChildrenAre
|
58
|
+
def simple_literal?
|
59
|
+
children.all?(&:simple_literal?)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
46
63
|
# Di-atomic
|
47
64
|
class Range < Node
|
65
|
+
include SimpleIfItsChildrenAre
|
66
|
+
|
48
67
|
has_child from: Node
|
49
68
|
has_child to: Node
|
50
69
|
end
|
@@ -67,6 +86,8 @@ module DeepCover
|
|
67
86
|
DynamicLiteral.has_evaluated_segments
|
68
87
|
|
69
88
|
class Regexp < Node
|
89
|
+
include SimpleIfItsChildrenAre
|
90
|
+
|
70
91
|
has_evaluated_segments
|
71
92
|
has_child option: Regopt
|
72
93
|
end
|
@@ -41,12 +41,12 @@ module DeepCover
|
|
41
41
|
# same as:
|
42
42
|
# has_child foo: [NodeClass, ...], remap: {type: NodeClass, ...}
|
43
43
|
#
|
44
|
-
def has_child(remap: nil, **
|
45
|
-
name, types =
|
44
|
+
def has_child(remap: nil, **args)
|
45
|
+
name, types = args.first
|
46
46
|
if types.is_a? Hash
|
47
47
|
raise 'Use either remap or a hash as type but not both' if remap
|
48
48
|
remap = types
|
49
|
-
|
49
|
+
args[name] = types = []
|
50
50
|
end
|
51
51
|
if remap.is_a? Hash
|
52
52
|
type_map = remap
|
@@ -57,7 +57,7 @@ module DeepCover
|
|
57
57
|
end
|
58
58
|
types.concat(type_map.values).uniq!
|
59
59
|
end
|
60
|
-
super(**
|
60
|
+
super(**args, remap: remap)
|
61
61
|
end
|
62
62
|
end
|
63
63
|
end
|
@@ -26,8 +26,12 @@ module DeepCover
|
|
26
26
|
is_a?(Node::Send) && RAISING_MESSAGES.include?(message) && receiver == nil
|
27
27
|
end
|
28
28
|
|
29
|
+
def is_warn?
|
30
|
+
is_a?(Node::Send) && message == :warn
|
31
|
+
end
|
32
|
+
|
29
33
|
def is_default_argument?
|
30
|
-
parent.is_a?(Node::Optarg)
|
34
|
+
parent.is_a?(Node::Optarg) && simple_literal?
|
31
35
|
end
|
32
36
|
|
33
37
|
def is_case_implicit_else?
|
@@ -36,7 +40,7 @@ module DeepCover
|
|
36
40
|
|
37
41
|
def is_trivial_if?
|
38
42
|
# Supports only node being a branch or the fork itself
|
39
|
-
parent.is_a?(Node::If) && parent.condition.
|
43
|
+
parent.is_a?(Node::If) && parent.condition.simple_literal?
|
40
44
|
end
|
41
45
|
end
|
42
46
|
end
|
@@ -22,9 +22,9 @@ module DeepCover
|
|
22
22
|
end
|
23
23
|
|
24
24
|
module ClassMethods
|
25
|
-
def has_child(rest_: false, refine_: false, **
|
26
|
-
raise "Needs exactly one custom named argument, got #{
|
27
|
-
name, types =
|
25
|
+
def has_child(rest_: false, refine_: false, **args)
|
26
|
+
raise "Needs exactly one custom named argument, got #{args.size}" if args.size != 1
|
27
|
+
name, types = args.first
|
28
28
|
raise TypeError, "Expect a Symbol for name, got a #{name.class} (#{name.inspect})" unless name.is_a?(Symbol)
|
29
29
|
update_children_const(name, rest: rest_) unless refine_
|
30
30
|
define_accessor(name) unless refine_
|
@@ -32,15 +32,15 @@ module DeepCover
|
|
32
32
|
self
|
33
33
|
end
|
34
34
|
|
35
|
-
def has_extra_children(**
|
36
|
-
has_child(**
|
35
|
+
def has_extra_children(**args)
|
36
|
+
has_child(**args, rest_: true)
|
37
37
|
end
|
38
38
|
|
39
|
-
def refine_child(child_name = nil, **
|
39
|
+
def refine_child(child_name = nil, **args)
|
40
40
|
if child_name
|
41
|
-
|
41
|
+
args = {child_name => self::CHILDREN_TYPES.fetch(child_name), **args}
|
42
42
|
end
|
43
|
-
has_child(**
|
43
|
+
has_child(**args, refine_: true)
|
44
44
|
end
|
45
45
|
|
46
46
|
def child_index_to_name(index, nb_children)
|
@@ -30,11 +30,11 @@ module DeepCover
|
|
30
30
|
class_eval <<-EVAL, __FILE__, __LINE__ + 1
|
31
31
|
module #{const_name} # module RewriteHandler
|
32
32
|
module ClassMethods # module ClassMethods
|
33
|
-
def has_child(#{action}: nil, **
|
34
|
-
name, _types =
|
33
|
+
def has_child(#{action}: nil, **args) # def has_child(rewrite: nil, **args)
|
34
|
+
name, _types = args.first # name, _types = args.first
|
35
35
|
define_child_handler(#{template.inspect}, # define_child_handler('rewrite_%{child}',
|
36
36
|
name, #{action}) # name, rewrite)
|
37
|
-
super(**
|
37
|
+
super(**args) # super(**args)
|
38
38
|
end # end
|
39
39
|
end # end
|
40
40
|
|
@@ -9,10 +9,14 @@ module DeepCover
|
|
9
9
|
TRACKERS = {}
|
10
10
|
|
11
11
|
def initialize(*)
|
12
|
-
@tracker_offset =
|
12
|
+
@tracker_offset = tracker_storage.allocate_trackers(self.class::TRACKERS.size).begin
|
13
13
|
super
|
14
14
|
end
|
15
15
|
|
16
|
+
def tracker_storage
|
17
|
+
covered_code.tracker_storage
|
18
|
+
end
|
19
|
+
|
16
20
|
def tracker_sources
|
17
21
|
self.class::TRACKERS.map do |name, _|
|
18
22
|
[:"#{name}_tracker", send(:"#{name}_tracker_source")]
|
@@ -29,10 +33,10 @@ module DeepCover
|
|
29
33
|
i = self::TRACKERS[name] = self::TRACKERS.size
|
30
34
|
class_eval <<-EVAL, __FILE__, __LINE__ + 1
|
31
35
|
def #{name}_tracker_source
|
32
|
-
|
36
|
+
tracker_storage.tracker_source(@tracker_offset + #{i})
|
33
37
|
end
|
34
38
|
def #{name}_tracker_hits
|
35
|
-
|
39
|
+
tracker_storage[@tracker_offset + #{i}]
|
36
40
|
end
|
37
41
|
EVAL
|
38
42
|
end
|
data/lib/deep_cover/node/root.rb
CHANGED
@@ -7,7 +7,7 @@ module DeepCover
|
|
7
7
|
can_be_empty: -> { Parser::Source::Range.new(covered_code.buffer, 0, 0) },
|
8
8
|
is_statement: true,
|
9
9
|
rewrite: -> {
|
10
|
-
"#{
|
10
|
+
"#{tracker_storage.setup_source};%{root_tracker};%{local}=nil;%{node}"
|
11
11
|
}
|
12
12
|
attr_reader :covered_code
|
13
13
|
alias_method :flow_entry_count, :root_tracker_hits
|
data/lib/deep_cover/node/send.rb
CHANGED
@@ -67,16 +67,54 @@ module DeepCover
|
|
67
67
|
check_completion
|
68
68
|
end
|
69
69
|
|
70
|
+
class CsendInnerSend < SendBase
|
71
|
+
has_tracker :completion
|
72
|
+
include ExecutedAfterChildren
|
73
|
+
|
74
|
+
def has_block?
|
75
|
+
parent.parent.is_a?(Block)
|
76
|
+
end
|
77
|
+
|
78
|
+
def rewrite
|
79
|
+
# All the rest of the rewriting logic is in Csend
|
80
|
+
'%{node};%{completion_tracker};' unless has_block?
|
81
|
+
end
|
82
|
+
|
83
|
+
def flow_completion_count
|
84
|
+
return parent.parent.flow_completion_count if has_block?
|
85
|
+
completion_tracker_hits
|
86
|
+
end
|
87
|
+
|
88
|
+
def loc_hash
|
89
|
+
# This is only a partial Send, the receiver param and the dot are actually handled by the parent Csend.
|
90
|
+
h = super.dup
|
91
|
+
h[:expression] = h[:expression].with(begin_pos: h[:selector_begin].begin_pos)
|
92
|
+
h
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
70
96
|
class Csend < Node
|
97
|
+
# The overall rewriting goal is this:
|
98
|
+
# temp = *receiver*;
|
99
|
+
# if nil != temp
|
100
|
+
# TRACK_my_NOT_NIL
|
101
|
+
# temp = temp&.*actual_send*{block}
|
102
|
+
# TRACK_actual_send_COMPLETION
|
103
|
+
# t
|
104
|
+
# else
|
105
|
+
# nil
|
106
|
+
# end
|
107
|
+
# This is split across the children and the CsendInnerSend
|
71
108
|
include Branch
|
72
|
-
has_tracker :
|
109
|
+
has_tracker :not_nil
|
73
110
|
has_child receiver: Node,
|
74
|
-
rewrite: '(%{local}=%{node}
|
111
|
+
rewrite: '(%{local}=%{node};if nil != %{local};%{not_nil_tracker};%{local}=%{local}'
|
112
|
+
REWRITE_SUFFIX = '%{node};%{local};else;nil;end)'
|
75
113
|
|
76
|
-
has_child actual_send: {safe_send:
|
77
|
-
flow_entry_count: :
|
114
|
+
has_child actual_send: {safe_send: CsendInnerSend},
|
115
|
+
flow_entry_count: :not_nil_tracker_hits
|
78
116
|
|
79
|
-
def initialize(base_node, base_children: base_node.children, **)
|
117
|
+
def initialize(base_node, base_children: base_node.children, **) # rubocop:disable Naming/UncommunicativeMethodParamName [#5436]
|
80
118
|
send_without_receiver = base_node.updated(:safe_send, [nil, *base_node.children.drop(1)])
|
81
119
|
base_children = [base_children.first, send_without_receiver]
|
82
120
|
super
|
@@ -84,6 +122,14 @@ module DeepCover
|
|
84
122
|
|
85
123
|
executed_loc_keys :dot
|
86
124
|
|
125
|
+
def has_block?
|
126
|
+
parent.is_a?(Block)
|
127
|
+
end
|
128
|
+
|
129
|
+
def rewrite
|
130
|
+
REWRITE_SUFFIX unless has_block?
|
131
|
+
end
|
132
|
+
|
87
133
|
def execution_count
|
88
134
|
receiver.flow_completion_count
|
89
135
|
end
|
@@ -98,8 +144,8 @@ module DeepCover
|
|
98
144
|
]
|
99
145
|
end
|
100
146
|
|
101
|
-
def branches_summary(
|
102
|
-
|
147
|
+
def branches_summary(of_branches = branches)
|
148
|
+
of_branches.map do |jump|
|
103
149
|
jump == actual_send ? 'safe send' : 'nil shortcut'
|
104
150
|
end.join(' and ')
|
105
151
|
end
|