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.
- checksums.yaml +4 -4
- data/.gitignore +3 -1
- data/.rspec +2 -1
- data/.rspec_all +2 -1
- data/.rubocop.yml +8 -9
- data/Gemfile +2 -0
- data/Rakefile +32 -6
- data/bin/cov +3 -3
- data/deep_cover.gemspec +3 -16
- data/exe/deep-cover +5 -0
- data/lib/deep_cover/cli/debugger.rb +1 -1
- data/lib/deep_cover/cli/exec.rb +1 -1
- data/lib/deep_cover/cli/instrumented_clone_reporter.rb +5 -3
- data/lib/deep_cover/cli/runner.rb +2 -2
- data/lib/deep_cover/{tools/dump_covered_code.rb → dump_covered_code.rb} +2 -0
- metadata +10 -203
- data/lib/deep-cover.rb +0 -3
- data/lib/deep_cover.rb +0 -22
- data/lib/deep_cover/analyser.rb +0 -23
- data/lib/deep_cover/analyser/base.rb +0 -104
- data/lib/deep_cover/analyser/branch.rb +0 -41
- data/lib/deep_cover/analyser/covered_code_source.rb +0 -21
- data/lib/deep_cover/analyser/function.rb +0 -14
- data/lib/deep_cover/analyser/node.rb +0 -54
- data/lib/deep_cover/analyser/per_char.rb +0 -38
- data/lib/deep_cover/analyser/per_line.rb +0 -41
- data/lib/deep_cover/analyser/ruby25_like_branch.rb +0 -211
- data/lib/deep_cover/analyser/statement.rb +0 -33
- data/lib/deep_cover/analyser/stats.rb +0 -54
- data/lib/deep_cover/analyser/subset.rb +0 -27
- data/lib/deep_cover/auto_run.rb +0 -71
- data/lib/deep_cover/autoload_tracker.rb +0 -215
- data/lib/deep_cover/backports.rb +0 -22
- data/lib/deep_cover/base.rb +0 -117
- data/lib/deep_cover/basics.rb +0 -22
- data/lib/deep_cover/builtin_takeover.rb +0 -10
- data/lib/deep_cover/config.rb +0 -104
- data/lib/deep_cover/config_setter.rb +0 -33
- data/lib/deep_cover/core_ext/autoload_overrides.rb +0 -112
- data/lib/deep_cover/core_ext/coverage_replacement.rb +0 -61
- data/lib/deep_cover/core_ext/exec_callbacks.rb +0 -27
- data/lib/deep_cover/core_ext/instruction_sequence_load_iseq.rb +0 -32
- data/lib/deep_cover/core_ext/load_overrides.rb +0 -19
- data/lib/deep_cover/core_ext/require_overrides.rb +0 -28
- data/lib/deep_cover/coverage.rb +0 -125
- data/lib/deep_cover/coverage/analysis.rb +0 -42
- data/lib/deep_cover/coverage/persistence.rb +0 -84
- data/lib/deep_cover/covered_code.rb +0 -145
- data/lib/deep_cover/custom_requirer.rb +0 -187
- data/lib/deep_cover/flag_comment_associator.rb +0 -68
- data/lib/deep_cover/load.rb +0 -66
- data/lib/deep_cover/memoize.rb +0 -48
- data/lib/deep_cover/module_override.rb +0 -39
- data/lib/deep_cover/node.rb +0 -23
- data/lib/deep_cover/node/arguments.rb +0 -51
- data/lib/deep_cover/node/assignments.rb +0 -273
- data/lib/deep_cover/node/base.rb +0 -155
- data/lib/deep_cover/node/begin.rb +0 -27
- data/lib/deep_cover/node/block.rb +0 -61
- data/lib/deep_cover/node/branch.rb +0 -32
- data/lib/deep_cover/node/case.rb +0 -113
- data/lib/deep_cover/node/collections.rb +0 -31
- data/lib/deep_cover/node/const.rb +0 -12
- data/lib/deep_cover/node/def.rb +0 -40
- data/lib/deep_cover/node/empty_body.rb +0 -32
- data/lib/deep_cover/node/exceptions.rb +0 -79
- data/lib/deep_cover/node/if.rb +0 -73
- data/lib/deep_cover/node/keywords.rb +0 -86
- data/lib/deep_cover/node/literals.rb +0 -100
- data/lib/deep_cover/node/loops.rb +0 -74
- data/lib/deep_cover/node/mixin/can_augment_children.rb +0 -65
- data/lib/deep_cover/node/mixin/check_completion.rb +0 -18
- data/lib/deep_cover/node/mixin/child_can_be_empty.rb +0 -27
- data/lib/deep_cover/node/mixin/executed_after_children.rb +0 -15
- data/lib/deep_cover/node/mixin/execution_location.rb +0 -66
- data/lib/deep_cover/node/mixin/filters.rb +0 -47
- data/lib/deep_cover/node/mixin/flow_accounting.rb +0 -71
- data/lib/deep_cover/node/mixin/has_child.rb +0 -145
- data/lib/deep_cover/node/mixin/has_child_handler.rb +0 -75
- data/lib/deep_cover/node/mixin/has_tracker.rb +0 -46
- data/lib/deep_cover/node/mixin/is_statement.rb +0 -20
- data/lib/deep_cover/node/mixin/rewriting.rb +0 -35
- data/lib/deep_cover/node/mixin/wrapper.rb +0 -15
- data/lib/deep_cover/node/module.rb +0 -66
- data/lib/deep_cover/node/root.rb +0 -20
- data/lib/deep_cover/node/send.rb +0 -161
- data/lib/deep_cover/node/short_circuit.rb +0 -42
- data/lib/deep_cover/node/splat.rb +0 -15
- data/lib/deep_cover/node/variables.rb +0 -16
- data/lib/deep_cover/parser_ext/range.rb +0 -21
- data/lib/deep_cover/problem_with_diagnostic.rb +0 -63
- data/lib/deep_cover/reporter.rb +0 -10
- data/lib/deep_cover/reporter/base.rb +0 -68
- data/lib/deep_cover/reporter/html.rb +0 -15
- data/lib/deep_cover/reporter/html/base.rb +0 -14
- data/lib/deep_cover/reporter/html/index.rb +0 -59
- data/lib/deep_cover/reporter/html/site.rb +0 -70
- data/lib/deep_cover/reporter/html/source.rb +0 -136
- data/lib/deep_cover/reporter/html/template/assets/32px.png +0 -0
- data/lib/deep_cover/reporter/html/template/assets/40px.png +0 -0
- data/lib/deep_cover/reporter/html/template/assets/deep_cover.css.sass +0 -336
- data/lib/deep_cover/reporter/html/template/assets/jquery-3.2.1.min.js +0 -4
- data/lib/deep_cover/reporter/html/template/assets/jquery-3.2.1.min.map +0 -1
- data/lib/deep_cover/reporter/html/template/assets/jstree.css +0 -1108
- data/lib/deep_cover/reporter/html/template/assets/jstree.js +0 -8424
- data/lib/deep_cover/reporter/html/template/assets/jstreetable.js +0 -1069
- data/lib/deep_cover/reporter/html/template/assets/throbber.gif +0 -0
- data/lib/deep_cover/reporter/html/template/index.html.erb +0 -75
- data/lib/deep_cover/reporter/html/template/source.html.erb +0 -35
- data/lib/deep_cover/reporter/istanbul.rb +0 -184
- data/lib/deep_cover/reporter/text.rb +0 -58
- data/lib/deep_cover/reporter/tree/util.rb +0 -86
- data/lib/deep_cover/tools.rb +0 -22
- data/lib/deep_cover/tools/blank.rb +0 -25
- data/lib/deep_cover/tools/builtin_coverage.rb +0 -55
- data/lib/deep_cover/tools/camelize.rb +0 -13
- data/lib/deep_cover/tools/content_tag.rb +0 -11
- data/lib/deep_cover/tools/covered.rb +0 -9
- data/lib/deep_cover/tools/execute_sample.rb +0 -34
- data/lib/deep_cover/tools/format.rb +0 -18
- data/lib/deep_cover/tools/format_char_cover.rb +0 -19
- data/lib/deep_cover/tools/format_generated_code.rb +0 -27
- data/lib/deep_cover/tools/indent_string.rb +0 -26
- data/lib/deep_cover/tools/merge.rb +0 -16
- data/lib/deep_cover/tools/number_lines.rb +0 -22
- data/lib/deep_cover/tools/our_coverage.rb +0 -11
- data/lib/deep_cover/tools/profiling.rb +0 -68
- data/lib/deep_cover/tools/render_template.rb +0 -13
- data/lib/deep_cover/tools/require_relative_dir.rb +0 -12
- data/lib/deep_cover/tools/scan_match_datas.rb +0 -10
- data/lib/deep_cover/tools/silence_warnings.rb +0 -18
- data/lib/deep_cover/tools/slice.rb +0 -9
- data/lib/deep_cover/tools/strip_heredoc.rb +0 -18
- data/lib/deep_cover/tools/truncate_backtrace.rb +0 -32
- data/lib/deep_cover/tracker_bucket.rb +0 -50
- data/lib/deep_cover/tracker_hits_per_path.rb +0 -35
- data/lib/deep_cover/tracker_storage.rb +0 -76
- data/lib/deep_cover/tracker_storage_per_path.rb +0 -34
- 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
|
data/lib/deep_cover/load.rb
DELETED
@@ -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
|
data/lib/deep_cover/memoize.rb
DELETED
@@ -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
|
data/lib/deep_cover/node.rb
DELETED
@@ -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
|