Skip to content

Commit

Permalink
Moved concerns about the ignored call stack into CallStack.
Browse files Browse the repository at this point in the history
  • Loading branch information
alpaca-tc committed Apr 22, 2024
1 parent e4f378c commit 7f394c3
Show file tree
Hide file tree
Showing 4 changed files with 43 additions and 14 deletions.
12 changes: 11 additions & 1 deletion lib/diver_down/trace/call_stack.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ class StackEmptyError < RuntimeError; end
attr_reader :stack_size

def initialize
@ignored_stack_size = nil
@stack_size = 0
@stack = {}
end
Expand All @@ -28,16 +29,25 @@ def stack

# @param context [Object, nil] User defined stack context.
# @return [void]
def push(context = nil)
def push(context = nil, ignored: false)
@stack_size += 1
@stack[@stack_size] = context unless context.nil?
@ignored_stack_size ||= @stack_size if ignored
end

# If a stack is not already a tracing target, some conditions are unnecessary so that it can be easily ignored.
#
# @return [Boolean]
def ignored?
!@ignored_stack_size.nil?
end

# @return [void]
def pop
raise StackEmptyError if @stack_size.zero?

@stack.delete(@stack_size) if @stack.key?(@stack_size)
@ignored_stack_size = nil if @ignored_stack_size && @ignored_stack_size == @stack_size
@stack_size -= 1
end
end
Expand Down
24 changes: 13 additions & 11 deletions lib/diver_down/trace/tracer/session.rb
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@ def stop

def build_trace_point
call_stack = DiverDown::Trace::CallStack.new
ignored_stack_size = nil

TracePoint.new(*DiverDown::Trace::Tracer.trace_events) do |tp|
# Skip the trace of the library itself
Expand All @@ -45,13 +44,23 @@ def build_trace_point
case tp.event
when :call, :c_call
# puts "#{tp.method_id} #{tp.path}:#{tp.lineno}"
if call_stack.ignored?
call_stack.push
next
end

mod = DiverDown::Helper.resolve_module(tp.self)

if !@ignored_method_ids.nil? && @ignored_method_ids.ignored?(mod, DiverDown::Helper.module?(tp.self), tp.method_id)
# If this method is ignored, the call stack is ignored until the method returns.
call_stack.push(ignored: true)
next
end

source_name = DiverDown::Helper.normalize_module_name(mod) if !mod.nil? && @module_set.include?(mod)
already_ignored = !ignored_stack_size.nil? # If the current method_id is ignored
current_ignored = !@ignored_method_ids.nil? && @ignored_method_ids.ignored?(mod, DiverDown::Helper.module?(tp.self), tp.method_id)
pushed = false

if !source_name.nil? && !(already_ignored || current_ignored)
unless source_name.nil?
source = @definition.find_or_build_source(source_name)

# If the call stack contains a call to a module to be traced
Expand Down Expand Up @@ -90,14 +99,7 @@ def build_trace_point
end

call_stack.push unless pushed

# If a value is already stored, it means that call stack already determined to be ignored at the shallower call stack size.
# Since stacks deeper than the shallowest stack size are ignored, priority is given to already stored values.
if !already_ignored && current_ignored
ignored_stack_size = call_stack.stack_size
end
when :return, :c_return
ignored_stack_size = nil if ignored_stack_size == call_stack.stack_size
call_stack.pop
end
rescue StandardError
Expand Down
18 changes: 18 additions & 0 deletions spec/diver_down/trace/call_stack_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,24 @@

expect(stack.stack).to eq([])
end

context 'with _ignored: true' do
it 'marks current stack as ignored' do
stack = described_class.new

stack.push
stack.push(ignored: true)
stack.push

expect(stack.ignored?).to be(true)
stack.pop
expect(stack.ignored?).to be(true)
stack.pop
expect(stack.ignored?).to be(false)
stack.pop
expect(stack.ignored?).to be(false)
end
end
end

describe '#empty?' do
Expand Down
3 changes: 1 addition & 2 deletions spec/diver_down/trace/tracer_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -686,12 +686,11 @@ def trace_fixture(path, module_set: {}, target_files: nil, ignored_method_ids: [
# antipollution_environment = AntipollutionKlass.allocate
#
# tracer = described_class.new(
# title: 'title',
# module_set: {
# modules: [
# AntipollutionModule::A,
# AntipollutionModule::D,
# ]
# ],
# }
# )
#
Expand Down

0 comments on commit 7f394c3

Please sign in to comment.