deep-cover 0.6.2 → 0.6.3.pre

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.
Files changed (139) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +3 -1
  3. data/.rspec +2 -1
  4. data/.rspec_all +2 -1
  5. data/.rubocop.yml +8 -9
  6. data/Gemfile +2 -0
  7. data/Rakefile +32 -6
  8. data/bin/cov +3 -3
  9. data/deep_cover.gemspec +3 -16
  10. data/exe/deep-cover +5 -0
  11. data/lib/deep_cover/cli/debugger.rb +1 -1
  12. data/lib/deep_cover/cli/exec.rb +1 -1
  13. data/lib/deep_cover/cli/instrumented_clone_reporter.rb +5 -3
  14. data/lib/deep_cover/cli/runner.rb +2 -2
  15. data/lib/deep_cover/{tools/dump_covered_code.rb → dump_covered_code.rb} +2 -0
  16. metadata +10 -203
  17. data/lib/deep-cover.rb +0 -3
  18. data/lib/deep_cover.rb +0 -22
  19. data/lib/deep_cover/analyser.rb +0 -23
  20. data/lib/deep_cover/analyser/base.rb +0 -104
  21. data/lib/deep_cover/analyser/branch.rb +0 -41
  22. data/lib/deep_cover/analyser/covered_code_source.rb +0 -21
  23. data/lib/deep_cover/analyser/function.rb +0 -14
  24. data/lib/deep_cover/analyser/node.rb +0 -54
  25. data/lib/deep_cover/analyser/per_char.rb +0 -38
  26. data/lib/deep_cover/analyser/per_line.rb +0 -41
  27. data/lib/deep_cover/analyser/ruby25_like_branch.rb +0 -211
  28. data/lib/deep_cover/analyser/statement.rb +0 -33
  29. data/lib/deep_cover/analyser/stats.rb +0 -54
  30. data/lib/deep_cover/analyser/subset.rb +0 -27
  31. data/lib/deep_cover/auto_run.rb +0 -71
  32. data/lib/deep_cover/autoload_tracker.rb +0 -215
  33. data/lib/deep_cover/backports.rb +0 -22
  34. data/lib/deep_cover/base.rb +0 -117
  35. data/lib/deep_cover/basics.rb +0 -22
  36. data/lib/deep_cover/builtin_takeover.rb +0 -10
  37. data/lib/deep_cover/config.rb +0 -104
  38. data/lib/deep_cover/config_setter.rb +0 -33
  39. data/lib/deep_cover/core_ext/autoload_overrides.rb +0 -112
  40. data/lib/deep_cover/core_ext/coverage_replacement.rb +0 -61
  41. data/lib/deep_cover/core_ext/exec_callbacks.rb +0 -27
  42. data/lib/deep_cover/core_ext/instruction_sequence_load_iseq.rb +0 -32
  43. data/lib/deep_cover/core_ext/load_overrides.rb +0 -19
  44. data/lib/deep_cover/core_ext/require_overrides.rb +0 -28
  45. data/lib/deep_cover/coverage.rb +0 -125
  46. data/lib/deep_cover/coverage/analysis.rb +0 -42
  47. data/lib/deep_cover/coverage/persistence.rb +0 -84
  48. data/lib/deep_cover/covered_code.rb +0 -145
  49. data/lib/deep_cover/custom_requirer.rb +0 -187
  50. data/lib/deep_cover/flag_comment_associator.rb +0 -68
  51. data/lib/deep_cover/load.rb +0 -66
  52. data/lib/deep_cover/memoize.rb +0 -48
  53. data/lib/deep_cover/module_override.rb +0 -39
  54. data/lib/deep_cover/node.rb +0 -23
  55. data/lib/deep_cover/node/arguments.rb +0 -51
  56. data/lib/deep_cover/node/assignments.rb +0 -273
  57. data/lib/deep_cover/node/base.rb +0 -155
  58. data/lib/deep_cover/node/begin.rb +0 -27
  59. data/lib/deep_cover/node/block.rb +0 -61
  60. data/lib/deep_cover/node/branch.rb +0 -32
  61. data/lib/deep_cover/node/case.rb +0 -113
  62. data/lib/deep_cover/node/collections.rb +0 -31
  63. data/lib/deep_cover/node/const.rb +0 -12
  64. data/lib/deep_cover/node/def.rb +0 -40
  65. data/lib/deep_cover/node/empty_body.rb +0 -32
  66. data/lib/deep_cover/node/exceptions.rb +0 -79
  67. data/lib/deep_cover/node/if.rb +0 -73
  68. data/lib/deep_cover/node/keywords.rb +0 -86
  69. data/lib/deep_cover/node/literals.rb +0 -100
  70. data/lib/deep_cover/node/loops.rb +0 -74
  71. data/lib/deep_cover/node/mixin/can_augment_children.rb +0 -65
  72. data/lib/deep_cover/node/mixin/check_completion.rb +0 -18
  73. data/lib/deep_cover/node/mixin/child_can_be_empty.rb +0 -27
  74. data/lib/deep_cover/node/mixin/executed_after_children.rb +0 -15
  75. data/lib/deep_cover/node/mixin/execution_location.rb +0 -66
  76. data/lib/deep_cover/node/mixin/filters.rb +0 -47
  77. data/lib/deep_cover/node/mixin/flow_accounting.rb +0 -71
  78. data/lib/deep_cover/node/mixin/has_child.rb +0 -145
  79. data/lib/deep_cover/node/mixin/has_child_handler.rb +0 -75
  80. data/lib/deep_cover/node/mixin/has_tracker.rb +0 -46
  81. data/lib/deep_cover/node/mixin/is_statement.rb +0 -20
  82. data/lib/deep_cover/node/mixin/rewriting.rb +0 -35
  83. data/lib/deep_cover/node/mixin/wrapper.rb +0 -15
  84. data/lib/deep_cover/node/module.rb +0 -66
  85. data/lib/deep_cover/node/root.rb +0 -20
  86. data/lib/deep_cover/node/send.rb +0 -161
  87. data/lib/deep_cover/node/short_circuit.rb +0 -42
  88. data/lib/deep_cover/node/splat.rb +0 -15
  89. data/lib/deep_cover/node/variables.rb +0 -16
  90. data/lib/deep_cover/parser_ext/range.rb +0 -21
  91. data/lib/deep_cover/problem_with_diagnostic.rb +0 -63
  92. data/lib/deep_cover/reporter.rb +0 -10
  93. data/lib/deep_cover/reporter/base.rb +0 -68
  94. data/lib/deep_cover/reporter/html.rb +0 -15
  95. data/lib/deep_cover/reporter/html/base.rb +0 -14
  96. data/lib/deep_cover/reporter/html/index.rb +0 -59
  97. data/lib/deep_cover/reporter/html/site.rb +0 -70
  98. data/lib/deep_cover/reporter/html/source.rb +0 -136
  99. data/lib/deep_cover/reporter/html/template/assets/32px.png +0 -0
  100. data/lib/deep_cover/reporter/html/template/assets/40px.png +0 -0
  101. data/lib/deep_cover/reporter/html/template/assets/deep_cover.css.sass +0 -336
  102. data/lib/deep_cover/reporter/html/template/assets/jquery-3.2.1.min.js +0 -4
  103. data/lib/deep_cover/reporter/html/template/assets/jquery-3.2.1.min.map +0 -1
  104. data/lib/deep_cover/reporter/html/template/assets/jstree.css +0 -1108
  105. data/lib/deep_cover/reporter/html/template/assets/jstree.js +0 -8424
  106. data/lib/deep_cover/reporter/html/template/assets/jstreetable.js +0 -1069
  107. data/lib/deep_cover/reporter/html/template/assets/throbber.gif +0 -0
  108. data/lib/deep_cover/reporter/html/template/index.html.erb +0 -75
  109. data/lib/deep_cover/reporter/html/template/source.html.erb +0 -35
  110. data/lib/deep_cover/reporter/istanbul.rb +0 -184
  111. data/lib/deep_cover/reporter/text.rb +0 -58
  112. data/lib/deep_cover/reporter/tree/util.rb +0 -86
  113. data/lib/deep_cover/tools.rb +0 -22
  114. data/lib/deep_cover/tools/blank.rb +0 -25
  115. data/lib/deep_cover/tools/builtin_coverage.rb +0 -55
  116. data/lib/deep_cover/tools/camelize.rb +0 -13
  117. data/lib/deep_cover/tools/content_tag.rb +0 -11
  118. data/lib/deep_cover/tools/covered.rb +0 -9
  119. data/lib/deep_cover/tools/execute_sample.rb +0 -34
  120. data/lib/deep_cover/tools/format.rb +0 -18
  121. data/lib/deep_cover/tools/format_char_cover.rb +0 -19
  122. data/lib/deep_cover/tools/format_generated_code.rb +0 -27
  123. data/lib/deep_cover/tools/indent_string.rb +0 -26
  124. data/lib/deep_cover/tools/merge.rb +0 -16
  125. data/lib/deep_cover/tools/number_lines.rb +0 -22
  126. data/lib/deep_cover/tools/our_coverage.rb +0 -11
  127. data/lib/deep_cover/tools/profiling.rb +0 -68
  128. data/lib/deep_cover/tools/render_template.rb +0 -13
  129. data/lib/deep_cover/tools/require_relative_dir.rb +0 -12
  130. data/lib/deep_cover/tools/scan_match_datas.rb +0 -10
  131. data/lib/deep_cover/tools/silence_warnings.rb +0 -18
  132. data/lib/deep_cover/tools/slice.rb +0 -9
  133. data/lib/deep_cover/tools/strip_heredoc.rb +0 -18
  134. data/lib/deep_cover/tools/truncate_backtrace.rb +0 -32
  135. data/lib/deep_cover/tracker_bucket.rb +0 -50
  136. data/lib/deep_cover/tracker_hits_per_path.rb +0 -35
  137. data/lib/deep_cover/tracker_storage.rb +0 -76
  138. data/lib/deep_cover/tracker_storage_per_path.rb +0 -34
  139. data/lib/deep_cover/version.rb +0 -5
@@ -1,68 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module DeepCover
4
- ##
5
- # A processor which computes which lines to be considered flagged with the
6
- # given lookup
7
- #
8
- class FlagCommentAssociator
9
- ##
10
- # @param [DeepCover::RootNode] ast
11
- # @param [Array(Parser::Source::Comment)] comments
12
- def initialize(covered_code, lookup = 'nocov')
13
- @covered_code = covered_code
14
- @lookup = /^#[\s#*-]*#{lookup}[\s#*-]*$/
15
- @ranges = nil
16
- end
17
-
18
- def include?(range)
19
- return false unless (exp = range.expression)
20
- lineno = exp.line
21
- ranges.any? { |r| r.cover? lineno }
22
- end
23
-
24
- def ranges
25
- @ranges ||= compute_ranges
26
- end
27
-
28
- private
29
-
30
- def compute_ranges
31
- @ranges = []
32
- @flag_start = nil
33
- index_ast_lines
34
- @covered_code.comments.each { |comment| process(comment) }
35
- toggle_flag(@covered_code.buffer.last_line) # handle end of file in case of opened flag
36
- @ranges
37
- end
38
-
39
- def process(comment)
40
- return unless comment.text =~ @lookup
41
- ln = comment.location.expression.line
42
- toggle_flag(ln) unless line_has_only_comments?(ln)
43
- toggle_flag(ln + 1)
44
- end
45
-
46
- def toggle_flag(lineno)
47
- if @flag_start
48
- @ranges << (@flag_start..(lineno - 1))
49
- @flag_start = nil
50
- else
51
- @flag_start = lineno
52
- end
53
- end
54
-
55
- def index_ast_lines
56
- @starts = []
57
- @covered_code.each_node do |node|
58
- if (exp = node.expression)
59
- @starts[exp.line] = true
60
- end
61
- end
62
- end
63
-
64
- def line_has_only_comments?(line)
65
- !@starts[line]
66
- end
67
- end
68
- end
@@ -1,66 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module DeepCover
4
- module Load
5
- AUTOLOAD = %i[analyser autoload_tracker auto_run config
6
- coverage covered_code custom_requirer
7
- tracker_hits_per_path tracker_storage_per_path
8
- flag_comment_associator memoize module_override node
9
- problem_with_diagnostic reporter tracker_bucket
10
- ]
11
-
12
- def load_absolute_basics
13
- require_relative 'base'
14
- require_relative 'basics'
15
- require_relative 'config_setter'
16
- require_relative 'tools/camelize'
17
- AUTOLOAD.each do |module_name|
18
- DeepCover.autoload(Tools::Camelize.camelize(module_name), "#{__dir__}/#{module_name}")
19
- end
20
- DeepCover.autoload :VERSION, "#{__dir__}/version"
21
- Object.autoload :Term, 'term/ansicolor'
22
- Object.autoload :Terminal, 'terminal-table'
23
- Object.autoload :YAML, 'yaml'
24
- Object.autoload :Forwardable, 'forwardable'
25
- end
26
-
27
- def bootstrap
28
- @bootstrapped ||= false # Avoid warning
29
- return if @bootstrapped
30
- require_relative 'backports'
31
- require_relative 'tools'
32
- @bootstrapped = true
33
- end
34
-
35
- def load_parser
36
- @parser_loaded ||= false # Avoid warning
37
- return if @parser_loaded
38
- silence_warnings do
39
- require 'parser'
40
- require 'parser/current'
41
- end
42
- require_relative_dir 'parser_ext'
43
- @parser_loaded = true
44
- end
45
-
46
- def load_pry
47
- silence_warnings do # Avoid "WARN: Unresolved specs during Gem::Specification.reset"
48
- require 'pry' # after `pry` calls `Gem.refresh`
49
- end
50
- end
51
-
52
- def load_all
53
- @all_loaded ||= false
54
- return if @all_loaded
55
- bootstrap
56
- load_parser
57
- AUTOLOAD.each do |module_name|
58
- DeepCover.const_get(Tools::Camelize.camelize(module_name))
59
- end
60
- DeepCover.const_get(:VERSION)
61
- @all_loaded = true
62
- end
63
- end
64
-
65
- extend Load
66
- end
@@ -1,48 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module DeepCover
4
- bootstrap
5
-
6
- # Memoize is a quick way to prepend a module that defines
7
- # the memoized methods as `@_cache ||= super.freeze`
8
- # It also refines `freeze` to precache memoized methods
9
- #
10
- module Memoize
11
- def self.included(base)
12
- base.extend ClassMethods
13
- end
14
-
15
- def freeze
16
- self.class.memoized.each do |method|
17
- send method
18
- end
19
- super
20
- end
21
-
22
- module ClassMethods
23
- def memoized
24
- @memoized ||= [].freeze
25
- end
26
-
27
- def memoizer_module
28
- @memoizer_module ||= begin
29
- mod = const_set(:Memoizer, Module.new)
30
- prepend mod
31
- mod
32
- end
33
- end
34
-
35
- def memoize(*methods)
36
- @memoized = (memoized | methods).freeze
37
-
38
- methods.each do |method|
39
- memoizer_module.module_eval <<-RUBY, __FILE__, __LINE__ + 1
40
- def #{method} # def foo
41
- @_#{method} ||= super.freeze # @_foo ||= super.freeze
42
- end # end
43
- RUBY
44
- end
45
- end
46
- end
47
- end
48
- end
@@ -1,39 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module DeepCover
4
- # Helps redefine methods in overriden_modules.
5
- # For each methods in Mod, this defines `<method>_with{out}_deep_cover`.
6
- # Set `active` to true or false to alias <method> to one or the other.
7
- module ModuleOverride
8
- attr_reader :overriden_modules
9
-
10
- def active=(active)
11
- each do |mod, method_name|
12
- mod.send :alias_method, method_name, :"#{method_name}_#{active ? 'with' : 'without'}_deep_cover"
13
- if mod == ::Kernel
14
- mod.send :private, method_name
15
- end
16
- end
17
- end
18
-
19
- def override(*modules)
20
- @overriden_modules = modules
21
- each do |mod, method_name|
22
- mod.send :alias_method, :"#{method_name}_without_deep_cover", method_name
23
- mod.send :define_method, :"#{method_name}_with_deep_cover", instance_method(method_name)
24
- if mod == ::Kernel
25
- mod.send :private, :"#{method_name}_without_deep_cover"
26
- mod.send :private, :"#{method_name}_with_deep_cover"
27
- end
28
- end
29
- end
30
-
31
- def each(&block)
32
- overriden_modules.each do |mod|
33
- instance_methods(false).each do |method_name|
34
- yield mod, method_name
35
- end
36
- end
37
- end
38
- end
39
- end
@@ -1,23 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module DeepCover
4
- bootstrap
5
- load_parser
6
-
7
- class Node
8
- # Reopened in base
9
- CLASSES = []
10
- def self.inherited(parent)
11
- CLASSES << parent
12
- super
13
- end
14
- end
15
- require_relative_dir 'node/mixin'
16
- require_relative 'node/base'
17
- require_relative_dir 'node'
18
-
19
- Node.include Memoize
20
- Node::CLASSES.freeze.each do |klass|
21
- klass.memoize :flow_entry_count, :flow_completion_count, :execution_count, :loc_hash
22
- end
23
- end
@@ -1,51 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative 'assignments'
4
-
5
- module DeepCover
6
- class Node
7
- class Arg < Node
8
- has_child name: Symbol
9
- def executable?
10
- false
11
- end
12
- end
13
- Kwarg = Arg
14
-
15
- class Restarg < Node
16
- has_child name: [Symbol, nil]
17
- def executable?
18
- false
19
- end
20
- end
21
- Kwrestarg = Restarg
22
-
23
- class Optarg < Node
24
- has_tracker :default
25
- has_child name: Symbol
26
- has_child default: Node, flow_entry_count: :default_tracker_hits, rewrite: '(%{default_tracker};%{node})'
27
-
28
- def executable?
29
- false
30
- end
31
- end
32
- Kwoptarg = Optarg
33
-
34
- # foo(&block)
35
- class Blockarg < Node
36
- has_child name: Symbol
37
-
38
- def executable?
39
- false
40
- end
41
- end
42
-
43
- class Args < Node
44
- has_extra_children arguments: [Arg, Optarg, Restarg, Kwarg, Kwoptarg, Kwrestarg, Blockarg, Mlhs]
45
-
46
- def executable?
47
- false
48
- end
49
- end
50
- end
51
- end
@@ -1,273 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative 'const'
4
- require_relative 'literals'
5
- require_relative 'keywords'
6
-
7
- module DeepCover
8
- class Node
9
- class VariableAssignment < Node
10
- has_child var_name: Symbol
11
- has_child value: [Node, nil]
12
- executed_loc_keys :name, :operator
13
-
14
- def execution_count
15
- return super unless value
16
- value.flow_completion_count
17
- end
18
- end
19
- Cvasgn = Gvasgn = Ivasgn = Lvasgn = VariableAssignment
20
-
21
- class Casgn < Node
22
- has_child cbase: [Cbase, Const, nil, Self, Begin, Kwbegin]
23
- has_child var_name: Symbol
24
- has_child value: [Node, nil]
25
-
26
- def execution_count
27
- return super unless value
28
- value.flow_completion_count
29
- end
30
- end
31
-
32
- class Mlhs < Node
33
- has_extra_children being_set: Node
34
- # TODO
35
- end
36
-
37
- module BackwardsStrategy
38
- # Instead of assuming our parent tracks our entry and we are responsible
39
- # for tracking our completion, we go the other way and assume our parent
40
- # tracks our completion and we are responsible for our entry.
41
- def flow_completion_count
42
- if (s = next_sibling)
43
- s.flow_entry_count
44
- else
45
- parent.flow_completion_count
46
- end
47
- end
48
-
49
- def flow_entry_count
50
- if (first_child = children_nodes.first)
51
- first_child.flow_entry_count
52
- else
53
- flow_completion_count
54
- end
55
- end
56
- end
57
-
58
- # Some multiple assignments are the only cases where Ruby
59
- # syntax rules won't allow us to insert tracking code
60
- # where we'd like it to be run.
61
- #
62
- # For example:
63
- #
64
- # method.a, b, method_2.c = [...]
65
- #
66
- # We'd like to add a tracker after the call to `a=` and
67
- # before the assignment to b and the call to `method_2`.
68
- #
69
- # We can't really do this with simple insertions, so
70
- # we temporarily of strategy for BackwardsStrategy
71
- #
72
- class Masgn < Node
73
- class BackwardsNode < Node
74
- include BackwardsStrategy
75
- end
76
-
77
- # We can't rewrite `self.bar` within a multiple assignment in the
78
- # case that `bar=` is private, so remain conservative and don't add
79
- # trackers.
80
- class SelfReceiver < BackwardsNode
81
- executed_loc_keys :expression
82
- end
83
-
84
- class ConstantCbase < BackwardsNode
85
- end
86
-
87
- class DynamicReceiverWrap < Node
88
- include Wrapper
89
- has_tracker :entry
90
- has_child actual_receiver: Node
91
- def rewrite
92
- '(%{entry_tracker};%{node})'
93
- end
94
- alias_method :flow_entry_count, :entry_tracker_hits
95
- end
96
-
97
- class Setter < Node
98
- include BackwardsStrategy
99
- has_child receiver: {self: SelfReceiver, Parser::AST::Node => DynamicReceiverWrap}
100
- has_child method_name: Symbol
101
- has_child arg: [Node, nil] # When method is :[]=
102
- executed_loc_keys :dot, :selector_begin, :selector_end
103
-
104
- def loc_hash
105
- base = super
106
- if method_name == :[]=
107
- selector = base[:selector]
108
- {
109
- expression: base[:expression],
110
- selector_begin: selector.resize(1),
111
- # The = is implicit, so only backtrack the end by one
112
- selector_end: Parser::Source::Range.new(selector.source_buffer, selector.end_pos - 1, selector.end_pos),
113
- }
114
- else
115
- {
116
- dot: base[:dot],
117
- expression: base[:expression],
118
- selector_begin: base[:selector],
119
- selector_end: nil, # ,
120
- }
121
- end
122
- end
123
-
124
- def execution_count
125
- receiver.flow_completion_count
126
- end
127
- end
128
-
129
- class ConstantScopeWrapper < Node
130
- include Wrapper
131
- has_tracker :entry
132
- has_child actual_node: Node
133
-
134
- def rewrite
135
- '(%{entry_tracker};%{node})'
136
- end
137
-
138
- def flow_entry_count
139
- entry_tracker_hits
140
- end
141
- end
142
-
143
- class ConstantAssignment < Node
144
- include BackwardsStrategy
145
- has_child scope: [nil], remap: {cbase: ConstantCbase, Parser::AST::Node => ConstantScopeWrapper}
146
- has_child constant_name: Symbol
147
-
148
- def execution_count
149
- scope ? scope.flow_completion_count : super
150
- end
151
- end
152
-
153
- class VariableAssignment < Node
154
- include BackwardsStrategy
155
- has_child var_name: Symbol
156
- end
157
-
158
- BASE_MAP = {
159
- cvasgn: VariableAssignment, gvasgn: VariableAssignment,
160
- ivasgn: VariableAssignment, lvasgn: VariableAssignment,
161
- casgn: ConstantAssignment,
162
- send: Setter,
163
- }.freeze
164
- class Splat < Node
165
- include BackwardsStrategy
166
- has_child rest_arg: [nil], remap: BASE_MAP
167
- executed_loc_keys :operator
168
- end
169
-
170
- class LeftSide < Node
171
- include BackwardsStrategy
172
- has_extra_children receivers: {
173
- splat: Splat,
174
- mlhs: LeftSide,
175
- **BASE_MAP,
176
- }
177
- executed_loc_keys # none
178
-
179
- def flow_completion_count
180
- parent.flow_completion_count
181
- end
182
- end
183
-
184
- check_completion
185
-
186
- has_child left: {mlhs: LeftSide}
187
- has_child value: Node
188
-
189
- executed_loc_keys :operator
190
-
191
- def execution_count
192
- value.flow_completion_count
193
- end
194
-
195
- def children_nodes_in_flow_order
196
- [value, left]
197
- end
198
- end
199
-
200
- class VariableOperatorAssign < Node
201
- has_child var_name: Symbol
202
- end
203
-
204
- class ConstantOperatorAssign < Node
205
- has_child scope: [Node, nil]
206
- has_child const_name: Symbol
207
- def execution_count
208
- flow_completion_count
209
- end
210
- end
211
-
212
- class SendOperatorAssign < Node
213
- has_child receiver: [Node, nil]
214
- has_child method_name: Symbol
215
- has_extra_children arguments: Node
216
- executed_loc_keys :dot, :selector_begin, :selector_end, :operator
217
-
218
- def loc_hash
219
- base = super
220
- hash = {expression: base[:expression], begin: base[:begin], end: base[:end], dot: base[:dot]}
221
- selector = base[:selector]
222
-
223
- if [:[], :[]=].include?(method_name)
224
- hash[:selector_begin] = selector.resize(1)
225
- hash[:selector_end] = Parser::Source::Range.new(selector.source_buffer, selector.end_pos - 1, selector.end_pos)
226
- else
227
- hash[:selector_begin] = base[:selector]
228
- end
229
-
230
- hash
231
- end
232
- end
233
-
234
- # foo += bar
235
- class OpAsgn < Node
236
- check_completion
237
- has_tracker :reader
238
- has_child receiver: {
239
- lvasgn: VariableOperatorAssign, ivasgn: VariableOperatorAssign,
240
- cvasgn: VariableOperatorAssign, gvasgn: VariableOperatorAssign,
241
- casgn: Casgn, # TODO
242
- send: SendOperatorAssign,
243
- }
244
- has_child operator: Symbol
245
- has_child value: Node, rewrite: '(%{reader_tracker};%{node})', flow_entry_count: :reader_tracker_hits
246
- executed_loc_keys :operator
247
-
248
- def execution_count
249
- flow_completion_count
250
- end
251
- end
252
-
253
- # foo ||= bar, foo &&= base
254
- class BooleanAssignment < Node
255
- check_completion
256
- has_tracker :long_branch
257
- has_child receiver: {
258
- lvasgn: VariableOperatorAssign, ivasgn: VariableOperatorAssign,
259
- cvasgn: VariableOperatorAssign, gvasgn: VariableOperatorAssign,
260
- casgn: ConstantOperatorAssign,
261
- send: SendOperatorAssign,
262
- }
263
- has_child value: Node, rewrite: '(%{long_branch_tracker};%{node})', flow_entry_count: :long_branch_tracker_hits
264
- executed_loc_keys :operator
265
-
266
- def execution_count
267
- flow_completion_count
268
- end
269
- end
270
-
271
- OrAsgn = AndAsgn = BooleanAssignment
272
- end
273
- end