deep-cover 0.1.1
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 +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
|