deep-cover 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +13 -0
- data/.rspec +2 -0
- data/.travis.yml +10 -0
- data/CODE_OF_CONDUCT.md +74 -0
- data/Gemfile +8 -0
- data/LICENSE.txt +21 -0
- data/README.md +127 -0
- data/Rakefile +6 -0
- data/bin/console +14 -0
- data/bin/cov +43 -0
- data/bin/gemcov +8 -0
- data/bin/selfcov +21 -0
- data/bin/setup +8 -0
- data/bin/testall +88 -0
- data/deep_cover.gemspec +44 -0
- data/exe/deep-cover +6 -0
- data/future_read_me.md +108 -0
- data/lib/deep-cover.rb +1 -0
- data/lib/deep_cover.rb +11 -0
- data/lib/deep_cover/analyser.rb +24 -0
- data/lib/deep_cover/analyser/base.rb +51 -0
- data/lib/deep_cover/analyser/branch.rb +20 -0
- data/lib/deep_cover/analyser/covered_code_source.rb +31 -0
- data/lib/deep_cover/analyser/function.rb +12 -0
- data/lib/deep_cover/analyser/ignore_uncovered.rb +19 -0
- data/lib/deep_cover/analyser/node.rb +11 -0
- data/lib/deep_cover/analyser/per_char.rb +20 -0
- data/lib/deep_cover/analyser/per_line.rb +23 -0
- data/lib/deep_cover/analyser/statement.rb +31 -0
- data/lib/deep_cover/analyser/subset.rb +24 -0
- data/lib/deep_cover/auto_run.rb +49 -0
- data/lib/deep_cover/autoload_tracker.rb +75 -0
- data/lib/deep_cover/backports.rb +9 -0
- data/lib/deep_cover/base.rb +55 -0
- data/lib/deep_cover/builtin_takeover.rb +2 -0
- data/lib/deep_cover/cli/debugger.rb +93 -0
- data/lib/deep_cover/cli/deep_cover.rb +49 -0
- data/lib/deep_cover/cli/instrumented_clone_reporter.rb +105 -0
- data/lib/deep_cover/config.rb +52 -0
- data/lib/deep_cover/core_ext/autoload_overrides.rb +40 -0
- data/lib/deep_cover/core_ext/coverage_replacement.rb +26 -0
- data/lib/deep_cover/core_ext/load_overrides.rb +24 -0
- data/lib/deep_cover/core_ext/require_overrides.rb +36 -0
- data/lib/deep_cover/coverage.rb +198 -0
- data/lib/deep_cover/covered_code.rb +138 -0
- data/lib/deep_cover/custom_requirer.rb +93 -0
- data/lib/deep_cover/node.rb +8 -0
- data/lib/deep_cover/node/arguments.rb +50 -0
- data/lib/deep_cover/node/assignments.rb +250 -0
- data/lib/deep_cover/node/base.rb +99 -0
- data/lib/deep_cover/node/begin.rb +25 -0
- data/lib/deep_cover/node/block.rb +53 -0
- data/lib/deep_cover/node/boolean.rb +22 -0
- data/lib/deep_cover/node/branch.rb +28 -0
- data/lib/deep_cover/node/case.rb +94 -0
- data/lib/deep_cover/node/collections.rb +21 -0
- data/lib/deep_cover/node/const.rb +10 -0
- data/lib/deep_cover/node/def.rb +38 -0
- data/lib/deep_cover/node/empty_body.rb +21 -0
- data/lib/deep_cover/node/exceptions.rb +74 -0
- data/lib/deep_cover/node/if.rb +36 -0
- data/lib/deep_cover/node/keywords.rb +84 -0
- data/lib/deep_cover/node/literals.rb +77 -0
- data/lib/deep_cover/node/loops.rb +72 -0
- data/lib/deep_cover/node/mixin/can_augment_children.rb +65 -0
- data/lib/deep_cover/node/mixin/check_completion.rb +16 -0
- data/lib/deep_cover/node/mixin/child_can_be_empty.rb +25 -0
- data/lib/deep_cover/node/mixin/executed_after_children.rb +13 -0
- data/lib/deep_cover/node/mixin/execution_location.rb +56 -0
- data/lib/deep_cover/node/mixin/flow_accounting.rb +63 -0
- data/lib/deep_cover/node/mixin/has_child.rb +138 -0
- data/lib/deep_cover/node/mixin/has_child_handler.rb +73 -0
- data/lib/deep_cover/node/mixin/has_tracker.rb +44 -0
- data/lib/deep_cover/node/mixin/is_statement.rb +18 -0
- data/lib/deep_cover/node/mixin/rewriting.rb +32 -0
- data/lib/deep_cover/node/mixin/wrapper.rb +13 -0
- data/lib/deep_cover/node/module.rb +64 -0
- data/lib/deep_cover/node/root.rb +18 -0
- data/lib/deep_cover/node/send.rb +83 -0
- data/lib/deep_cover/node/splat.rb +13 -0
- data/lib/deep_cover/node/variables.rb +14 -0
- data/lib/deep_cover/parser_ext/range.rb +40 -0
- data/lib/deep_cover/reporter.rb +6 -0
- data/lib/deep_cover/reporter/istanbul.rb +151 -0
- data/lib/deep_cover/tools.rb +18 -0
- data/lib/deep_cover/tools/builtin_coverage.rb +50 -0
- data/lib/deep_cover/tools/camelize.rb +8 -0
- data/lib/deep_cover/tools/dump_covered_code.rb +32 -0
- data/lib/deep_cover/tools/execute_sample.rb +23 -0
- data/lib/deep_cover/tools/format.rb +16 -0
- data/lib/deep_cover/tools/format_char_cover.rb +18 -0
- data/lib/deep_cover/tools/format_generated_code.rb +25 -0
- data/lib/deep_cover/tools/number_lines.rb +18 -0
- data/lib/deep_cover/tools/our_coverage.rb +9 -0
- data/lib/deep_cover/tools/require_relative_dir.rb +10 -0
- data/lib/deep_cover/tools/silence_warnings.rb +15 -0
- data/lib/deep_cover/version.rb +3 -0
- metadata +326 -0
@@ -0,0 +1,25 @@
|
|
1
|
+
module DeepCover
|
2
|
+
class Node
|
3
|
+
class Begin < Node
|
4
|
+
has_extra_children expressions: Node,
|
5
|
+
is_statement: true
|
6
|
+
|
7
|
+
def is_statement
|
8
|
+
false
|
9
|
+
end
|
10
|
+
|
11
|
+
def executed_loc_keys
|
12
|
+
# Begin is a generic grouping used in different contexts.
|
13
|
+
case loc_hash[:begin] && loc_hash[:begin].source
|
14
|
+
when nil, '(', 'begin'
|
15
|
+
[]
|
16
|
+
when 'else', '#{'
|
17
|
+
%i[begin end]
|
18
|
+
else
|
19
|
+
warn "Unknown context for Begin node"
|
20
|
+
[]
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
require_relative 'send'
|
2
|
+
require_relative 'keywords'
|
3
|
+
|
4
|
+
module DeepCover
|
5
|
+
class Node
|
6
|
+
module WithBlock
|
7
|
+
def flow_completion_count
|
8
|
+
parent.flow_completion_count
|
9
|
+
end
|
10
|
+
|
11
|
+
def execution_count
|
12
|
+
last = children_nodes.last
|
13
|
+
return last.flow_completion_count if last
|
14
|
+
super
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
class SendWithBlock < Node
|
19
|
+
include WithBlock
|
20
|
+
has_child receiver: [Node, nil]
|
21
|
+
has_child method_name: Symbol
|
22
|
+
has_extra_children arguments: Node
|
23
|
+
end
|
24
|
+
|
25
|
+
class SuperWithBlock < Node
|
26
|
+
include WithBlock
|
27
|
+
has_extra_children arguments: Node
|
28
|
+
end
|
29
|
+
|
30
|
+
class Block < Node
|
31
|
+
check_completion
|
32
|
+
has_tracker :body
|
33
|
+
has_child call: {send: SendWithBlock, zsuper: SuperWithBlock, super: SuperWithBlock}
|
34
|
+
has_child args: Args
|
35
|
+
has_child body: Node,
|
36
|
+
can_be_empty: -> { base_node.loc.begin.end },
|
37
|
+
rewrite: '%{body_tracker};%{local}=nil;%{node}',
|
38
|
+
flow_entry_count: :body_tracker_hits,
|
39
|
+
is_statement: true
|
40
|
+
executed_loc_keys # none
|
41
|
+
|
42
|
+
def children_nodes_in_flow_order
|
43
|
+
[call, args] # Similarly to a def, the body is actually not part of the flow of this node...
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
# &foo
|
48
|
+
class BlockPass < Node
|
49
|
+
has_child block: Node
|
50
|
+
# TODO
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require_relative 'branch'
|
2
|
+
|
3
|
+
module DeepCover
|
4
|
+
class Node
|
5
|
+
class ShortCircuit < Node
|
6
|
+
include Branch
|
7
|
+
has_tracker :conditional
|
8
|
+
has_child first: Node
|
9
|
+
has_child conditional: Node, flow_entry_count: :conditional_tracker_hits,
|
10
|
+
rewrite: '((%{conditional_tracker};%{node}))'
|
11
|
+
|
12
|
+
def branches
|
13
|
+
[
|
14
|
+
conditional,
|
15
|
+
TrivialBranch.new(first, conditional)
|
16
|
+
]
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
And = Or = ShortCircuit
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module DeepCover
|
2
|
+
class Node
|
3
|
+
module Branch
|
4
|
+
def flow_completion_count
|
5
|
+
branches.map(&:flow_completion_count).inject(0, :+)
|
6
|
+
end
|
7
|
+
|
8
|
+
# Define in sublasses:
|
9
|
+
def branches
|
10
|
+
raise NotImplementedError
|
11
|
+
end
|
12
|
+
|
13
|
+
# Also define flow_entry_count
|
14
|
+
end
|
15
|
+
|
16
|
+
class TrivialBranch < Struct.new(:condition, :other_branch)
|
17
|
+
def flow_entry_count
|
18
|
+
condition.flow_completion_count - other_branch.flow_entry_count
|
19
|
+
end
|
20
|
+
alias_method :flow_completion_count, :flow_entry_count
|
21
|
+
alias_method :execution_count, :flow_entry_count
|
22
|
+
def executable?
|
23
|
+
true
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,94 @@
|
|
1
|
+
require_relative 'branch'
|
2
|
+
|
3
|
+
module DeepCover
|
4
|
+
class Node
|
5
|
+
class WhenCondition < Node
|
6
|
+
include Wrapper
|
7
|
+
has_tracker :entry
|
8
|
+
# Using && instead of ; solves a weird bug in jruby 9.1.7.0 and 9.1.9.0 (probably before too).
|
9
|
+
# The following will only print 'test' once
|
10
|
+
# class EqEqEq; def ===(other); puts 'test'; end; end
|
11
|
+
# eqeqeq = EqEqEq.new
|
12
|
+
# case 1; when eqeqeq; end
|
13
|
+
# case 1; when (3;eqeqeq); end
|
14
|
+
# See https://github.com/jruby/jruby/issues/4804
|
15
|
+
# This is solved in jruby 9.2.0.0, better keep the workaround
|
16
|
+
# for compatibility.
|
17
|
+
has_child condition: Node, rewrite: "(((%{entry_tracker}) && %{node}))",
|
18
|
+
flow_entry_count: :entry_tracker_hits
|
19
|
+
executed_loc_keys []
|
20
|
+
|
21
|
+
def flow_entry_count
|
22
|
+
entry_tracker_hits
|
23
|
+
end
|
24
|
+
|
25
|
+
def flow_completion_count
|
26
|
+
condition.flow_completion_count
|
27
|
+
end
|
28
|
+
|
29
|
+
def loc_hash
|
30
|
+
condition.loc_hash
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
class WhenSplatCondition < Node
|
35
|
+
has_tracker :entry
|
36
|
+
check_completion inner: '(%{entry_tracker};[%{node}])', outer: '*%{node}'
|
37
|
+
has_child receiver: Node
|
38
|
+
|
39
|
+
def flow_entry_count
|
40
|
+
entry_tracker_hits
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
class When < Node
|
45
|
+
has_tracker :body_entry
|
46
|
+
has_extra_children matches: { splat: WhenSplatCondition, Parser::AST::Node => WhenCondition }
|
47
|
+
has_child body: Node,
|
48
|
+
can_be_empty: -> { base_node.loc.expression.succ },
|
49
|
+
rewrite: ";%{body_entry_tracker};%{local}=nil;%{node}",
|
50
|
+
is_statement: true,
|
51
|
+
flow_entry_count: :body_entry_tracker_hits
|
52
|
+
|
53
|
+
def flow_entry_count
|
54
|
+
matches.first.flow_entry_count
|
55
|
+
end
|
56
|
+
|
57
|
+
def execution_count
|
58
|
+
matches.first.flow_completion_count
|
59
|
+
end
|
60
|
+
|
61
|
+
def flow_completion_count
|
62
|
+
body.flow_completion_count + next_sibling.flow_entry_count
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
class Case < Node
|
67
|
+
include Branch
|
68
|
+
has_tracker :else_entry
|
69
|
+
has_child evaluate: [Node, nil]
|
70
|
+
has_extra_children whens: When
|
71
|
+
has_child else: Node,
|
72
|
+
can_be_empty: -> { base_node.loc.end.begin },
|
73
|
+
rewrite: -> { "#{'else;' unless has_else?}((%{else_entry_tracker};%{local}=nil;%{node}))" },
|
74
|
+
executed_loc_keys: [:else],
|
75
|
+
is_statement: true,
|
76
|
+
flow_entry_count: :else_entry_tracker_hits
|
77
|
+
|
78
|
+
executed_loc_keys :begin, :keyword
|
79
|
+
|
80
|
+
def branches
|
81
|
+
whens.map(&:body) << self.else
|
82
|
+
end
|
83
|
+
|
84
|
+
def execution_count
|
85
|
+
return evaluate.flow_completion_count if evaluate
|
86
|
+
flow_entry_count
|
87
|
+
end
|
88
|
+
|
89
|
+
def has_else?
|
90
|
+
!!base_node.loc.to_hash[:else]
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require_relative 'splat'
|
2
|
+
|
3
|
+
module DeepCover
|
4
|
+
class Node
|
5
|
+
class Array < Node
|
6
|
+
has_extra_children elements: Node
|
7
|
+
executed_loc_keys :begin, :end
|
8
|
+
end
|
9
|
+
|
10
|
+
class Pair < Node
|
11
|
+
has_child key: Node
|
12
|
+
has_child value: Node
|
13
|
+
executed_loc_keys :operator
|
14
|
+
end
|
15
|
+
|
16
|
+
class Hash < Node
|
17
|
+
has_extra_children elements: [Pair, Kwsplat]
|
18
|
+
executed_loc_keys :begin, :end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require_relative 'arguments'
|
2
|
+
|
3
|
+
module DeepCover
|
4
|
+
class Node::Def < Node
|
5
|
+
check_completion
|
6
|
+
has_tracker :method_call
|
7
|
+
has_child method_name: Symbol
|
8
|
+
has_child signature: Args
|
9
|
+
has_child body: Node,
|
10
|
+
rewrite: '%{method_call_tracker};%{local}=nil;%{node};',
|
11
|
+
can_be_empty: -> { base_node.loc.end.begin },
|
12
|
+
is_statement: true,
|
13
|
+
flow_entry_count: :method_call_tracker_hits
|
14
|
+
executed_loc_keys :keyword, :name
|
15
|
+
|
16
|
+
def children_nodes_in_flow_order
|
17
|
+
[]
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
class Node::Defs < Node
|
22
|
+
check_completion
|
23
|
+
has_tracker :method_call
|
24
|
+
has_child singleton: Node, rewrite: '(%{node})'
|
25
|
+
has_child method_name: Symbol
|
26
|
+
has_child signature: Args
|
27
|
+
has_child body: Node,
|
28
|
+
rewrite: '%{method_call_tracker};%{local}=nil;%{node};',
|
29
|
+
can_be_empty: -> { base_node.loc.end.begin },
|
30
|
+
is_statement: true,
|
31
|
+
flow_entry_count: :method_call_tracker_hits
|
32
|
+
executed_loc_keys :keyword, :name, :operator
|
33
|
+
|
34
|
+
def children_nodes_in_flow_order
|
35
|
+
[singleton]
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module DeepCover
|
2
|
+
class Node::EmptyBody < Node
|
3
|
+
def initialize(base_node, parent: raise, index: 0, position: ChildCanBeEmpty.last_empty_position)
|
4
|
+
@position = position
|
5
|
+
@position = parent.expression.begin if @position == true # Some random position... don't rewrite!
|
6
|
+
super(base_node, parent: parent, index: index, base_children: [])
|
7
|
+
end
|
8
|
+
|
9
|
+
def type
|
10
|
+
:EmptyBody
|
11
|
+
end
|
12
|
+
|
13
|
+
def loc_hash
|
14
|
+
{expression: @position}
|
15
|
+
end
|
16
|
+
|
17
|
+
def is_statement
|
18
|
+
false
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,74 @@
|
|
1
|
+
require_relative 'variables'
|
2
|
+
require_relative 'collections'
|
3
|
+
|
4
|
+
module DeepCover
|
5
|
+
class Node
|
6
|
+
class Resbody < Node
|
7
|
+
has_tracker :entered_body
|
8
|
+
has_child exception: [Node::Array, nil]
|
9
|
+
has_child assignment: [Lvasgn, nil], flow_entry_count: :entered_body_tracker_hits
|
10
|
+
has_child body: Node,
|
11
|
+
can_be_empty: -> { base_node.loc.expression.succ },
|
12
|
+
flow_entry_count: :entered_body_tracker_hits,
|
13
|
+
is_statement: true,
|
14
|
+
rewrite: '((%{entered_body_tracker};%{local}=nil;%{node}))'
|
15
|
+
|
16
|
+
def is_statement
|
17
|
+
false
|
18
|
+
end
|
19
|
+
|
20
|
+
def execution_count
|
21
|
+
entered_body_tracker_hits
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
class Rescue < Node
|
26
|
+
has_child watched_body: Node,
|
27
|
+
can_be_empty: -> { base_node.loc.expression.begin },
|
28
|
+
is_statement: true
|
29
|
+
has_extra_children resbodies: Resbody
|
30
|
+
has_child else: Node,
|
31
|
+
can_be_empty: -> { base_node.loc.expression.succ },
|
32
|
+
flow_entry_count: :execution_count,
|
33
|
+
is_statement: true
|
34
|
+
executed_loc_keys :else
|
35
|
+
|
36
|
+
def is_statement
|
37
|
+
false
|
38
|
+
end
|
39
|
+
|
40
|
+
def flow_completion_count
|
41
|
+
resbodies.map(&:flow_completion_count).inject(0, :+) + self.else.flow_completion_count
|
42
|
+
end
|
43
|
+
|
44
|
+
def execution_count
|
45
|
+
watched_body.flow_completion_count
|
46
|
+
end
|
47
|
+
|
48
|
+
def resbodies_flow_entry_count(child)
|
49
|
+
prev = child.previous_sibling
|
50
|
+
|
51
|
+
if prev.equal? watched_body
|
52
|
+
prev.flow_entry_count - prev.flow_completion_count
|
53
|
+
else # RESBODIES
|
54
|
+
# TODO is this okay?
|
55
|
+
prev.exception.flow_completion_count - prev.execution_count
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
class Ensure < Node
|
61
|
+
has_child body: Node,
|
62
|
+
can_be_empty: -> { base_node.loc.expression.begin },
|
63
|
+
is_statement: true
|
64
|
+
has_child ensure: Node,
|
65
|
+
can_be_empty: -> { base_node.loc.expression.succ },
|
66
|
+
is_statement: true,
|
67
|
+
flow_entry_count: -> { body.flow_entry_count }
|
68
|
+
|
69
|
+
def flow_completion_count
|
70
|
+
body.flow_completion_count
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require_relative 'branch'
|
2
|
+
|
3
|
+
module DeepCover
|
4
|
+
class Node
|
5
|
+
class If < Node
|
6
|
+
include Branch
|
7
|
+
has_tracker :truthy
|
8
|
+
has_child condition: Node, rewrite: '((%{node}) && %{truthy_tracker})'
|
9
|
+
has_child true_branch: Node,
|
10
|
+
can_be_empty: true,
|
11
|
+
executed_loc_keys: -> { :else if style == :unless },
|
12
|
+
flow_entry_count: :truthy_tracker_hits,
|
13
|
+
is_statement: true
|
14
|
+
has_child false_branch: Node,
|
15
|
+
can_be_empty: true,
|
16
|
+
executed_loc_keys: -> { [:else, :colon] if style != :unless },
|
17
|
+
flow_entry_count: -> { condition.flow_completion_count - truthy_tracker_hits },
|
18
|
+
is_statement: true
|
19
|
+
executed_loc_keys :keyword, :question
|
20
|
+
|
21
|
+
def branches
|
22
|
+
[ true_branch, false_branch ]
|
23
|
+
end
|
24
|
+
|
25
|
+
def execution_count
|
26
|
+
condition.flow_completion_count
|
27
|
+
end
|
28
|
+
|
29
|
+
# returns on of %i[ternary if unless elsif]
|
30
|
+
def style
|
31
|
+
keyword = loc_hash[:keyword]
|
32
|
+
keyword ? keyword.source.to_sym : :ternary
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,84 @@
|
|
1
|
+
require_relative 'variables'
|
2
|
+
require_relative 'literals'
|
3
|
+
|
4
|
+
module DeepCover
|
5
|
+
class Node
|
6
|
+
class Kwbegin < Node
|
7
|
+
has_extra_children instructions: Node,
|
8
|
+
is_statement: true
|
9
|
+
|
10
|
+
def is_statement
|
11
|
+
false
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
class Return < Node
|
16
|
+
has_extra_children values: Node
|
17
|
+
# TODO
|
18
|
+
end
|
19
|
+
|
20
|
+
class Super < Node
|
21
|
+
check_completion
|
22
|
+
has_extra_children arguments: Node
|
23
|
+
# TODO
|
24
|
+
end
|
25
|
+
Zsuper = Super # Zsuper is super with no parenthesis (same arguments as caller)
|
26
|
+
|
27
|
+
class Yield < Node
|
28
|
+
has_extra_children arguments: Node
|
29
|
+
# TODO
|
30
|
+
end
|
31
|
+
|
32
|
+
class Break < Node
|
33
|
+
has_extra_children arguments: Node
|
34
|
+
# TODO Anything special needed for the arguments?
|
35
|
+
|
36
|
+
def flow_completion_count
|
37
|
+
0
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
class Next < Node
|
42
|
+
has_extra_children arguments: Node
|
43
|
+
# TODO Anything special needed for the arguments?
|
44
|
+
|
45
|
+
def flow_completion_count
|
46
|
+
0
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
class Alias < Node
|
51
|
+
check_completion
|
52
|
+
has_child alias: [Sym, Dsym, Gvar, BackRef]
|
53
|
+
has_child original: [Sym, Dsym, Gvar, BackRef]
|
54
|
+
# TODO: test
|
55
|
+
end
|
56
|
+
|
57
|
+
class NeverEvaluated < Node
|
58
|
+
has_extra_children whatever: [:any], remap: {Parser::AST::Node => NeverEvaluated}
|
59
|
+
|
60
|
+
def executable?
|
61
|
+
false
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
class Defined < Node
|
66
|
+
has_child code: {Parser::AST::Node => NeverEvaluated}
|
67
|
+
# TODO: test
|
68
|
+
end
|
69
|
+
|
70
|
+
class Undef < Node
|
71
|
+
check_completion
|
72
|
+
has_extra_children arguments: [Sym, Dsym]
|
73
|
+
# TODO: test
|
74
|
+
end
|
75
|
+
|
76
|
+
class Return < Node
|
77
|
+
include ExecutedAfterChildren
|
78
|
+
|
79
|
+
def flow_completion_count
|
80
|
+
0
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|