class DeepCover::CoveredCode
Attributes
buffer[RW]
local_var[RW]
path[RW]
Public Class Methods
new( path: nil, source: nil, lineno: 1, local_var: '_temp', tracker_hits: nil )
click to toggle source
# File lib/deep_cover/covered_code.rb, line 10 def initialize( path: nil, source: nil, lineno: 1, local_var: '_temp', tracker_hits: nil ) raise 'Must provide either path or source' unless path || source @path = path &&= Pathname(path) @buffer = Parser::Source::Buffer.new('', lineno) @buffer.source = source || path.read @index = nil # Set in #instrument_source @local_var = local_var @covered_source = nil # Set in #covered_source @tracker_hits = tracker_hits # Loaded from global in #tracker_hits, or when received right away when loading data @nb_allocated_trackers = 0 # We parse the code now so that problems happen early covered_ast @tracker_hits = Array.new(@nb_allocated_trackers, 0) if @tracker_hits == :zeroes end
next_global_index()
click to toggle source
# File lib/deep_cover/covered_code.rb, line 168 def self.next_global_index @last_allocated_global_index ||= -1 @last_allocated_global_index += 1 end
Public Instance Methods
allocate_trackers(nb_needed)
click to toggle source
# File lib/deep_cover/covered_code.rb, line 94 def allocate_trackers(nb_needed) return @nb_allocated_trackers...@nb_allocated_trackers if nb_needed == 0 prev = @nb_allocated_trackers @nb_allocated_trackers += nb_needed prev...@nb_allocated_trackers end
char_cover(**options)
click to toggle source
# File lib/deep_cover/covered_code.rb, line 60 def char_cover(**options) Analyser::PerChar.new(self, **options).results end
comments()
click to toggle source
# File lib/deep_cover/covered_code.rb, line 68 def comments root @comments end
compile()
click to toggle source
# File lib/deep_cover/covered_code.rb, line 133 def compile RubyVM::InstructionSequence.compile(covered_source, path.to_s, path.to_s) end
compile_or_warn()
click to toggle source
# File lib/deep_cover/covered_code.rb, line 137 def compile_or_warn warn_instead_of_syntax_error do compile end end
covered_ast()
click to toggle source
# File lib/deep_cover/covered_code.rb, line 64 def covered_ast root.main end
covered_source()
click to toggle source
# File lib/deep_cover/covered_code.rb, line 114 def covered_source @covered_source ||= instrument_source end
each_node(*args, &block)
click to toggle source
# File lib/deep_cover/covered_code.rb, line 80 def each_node(*args, &block) covered_ast.each_node(*args, &block) end
execute_code(binding: DeepCover::GLOBAL_BINDING.dup)
click to toggle source
# File lib/deep_cover/covered_code.rb, line 45 def execute_code(binding: DeepCover::GLOBAL_BINDING.dup) eval(covered_source, binding, (@path || '<raw_code>').to_s, lineno) # rubocop:disable Security/Eval self end
execute_code_or_warn(*args)
click to toggle source
# File lib/deep_cover/covered_code.rb, line 50 def execute_code_or_warn(*args) warn_instead_of_syntax_error do execute_code(*args) end end
freeze()
click to toggle source
Calls superclass method
# File lib/deep_cover/covered_code.rb, line 143 def freeze unless frozen? # Guard against reentrance tracker_hits super root.each_node(&:freeze) end self end
increment_tracker_source(tracker_id)
click to toggle source
# File lib/deep_cover/covered_code.rb, line 90 def increment_tracker_source(tracker_id) "#{DeepCover.config.tracker_global}[#{@index}][#{tracker_id}]+=1" end
inspect()
click to toggle source
# File lib/deep_cover/covered_code.rb, line 152 def inspect %{#<DeepCover::CoveredCode "#{path}">} end
Also aliased as: to_s
instrument_source() { |prefix, node, begin, :prefix| ... }
click to toggle source
# File lib/deep_cover/covered_code.rb, line 118 def instrument_source @index ||= self.class.next_global_index rewriter = Parser::Source::TreeRewriter.new(@buffer) covered_ast.each_node do |node| node.rewriting_rules.each do |range, rule| prefix, _node, suffix = rule.partition('%{node}') prefix = yield prefix, node, range.begin, :prefix if block_given? && !prefix.empty? suffix = yield suffix, node, range.end, :suffix if block_given? && !suffix.empty? rewriter.wrap(range, prefix, suffix) end end rewriter.process end
line_coverage(**options)
click to toggle source
# File lib/deep_cover/covered_code.rb, line 56 def line_coverage(**options) Analyser::PerLine.new(self, **options).results end
lineno()
click to toggle source
# File lib/deep_cover/covered_code.rb, line 32 def lineno @buffer.first_line end
nb_lines()
click to toggle source
# File lib/deep_cover/covered_code.rb, line 36 def nb_lines lines = buffer.source_lines if lines.empty? 0 else lines.size - (lines.last.empty? ? 1 : 0) end end
root()
click to toggle source
# File lib/deep_cover/covered_code.rb, line 73 def root @root ||= begin ast, @comments = parser.parse_with_comments(@buffer) Node::Root.new(ast, self) end end
setup_tracking_source()
click to toggle source
# File lib/deep_cover/covered_code.rb, line 84 def setup_tracking_source src = "(#{DeepCover.config.tracker_global}||={})[#{@index}]||=Array.new(#{@nb_allocated_trackers},0)" src += ";(#{DeepCover.config.tracker_global}_p||={})[#{@index}]=#{path.to_s.inspect}" if path src end
tracker_hits()
click to toggle source
# File lib/deep_cover/covered_code.rb, line 101 def tracker_hits return @tracker_hits if @tracker_hits global_trackers = DeepCover::GlobalVariables.trackers[@index] return unless global_trackers if global_trackers.size != @nb_allocated_trackers raise "Cannot sync path: #{path.inspect}, global[#{@index}] is of size #{global_trackers.size} instead of expected #{@nb_allocated_trackers}" end @tracker_hits = global_trackers end
warn_instead_of_syntax_error() { || ... }
click to toggle source
# File lib/deep_cover/covered_code.rb, line 157 def warn_instead_of_syntax_error # &block yield rescue ::SyntaxError => e warn Tools.strip_heredoc(<<-MSG) DeepCover is getting confused with the file #{path} and it won't be instrumented. Please report this error and provide the source code around the following lines: #{e} MSG nil end
Private Instance Methods
parser()
click to toggle source
# File lib/deep_cover/covered_code.rb, line 175 def parser Parser::CurrentRuby.new.tap do |parser| parser.diagnostics.all_errors_are_fatal = true parser.diagnostics.ignore_warnings = true end end