Skip to content

Commit

Permalink
Merge pull request #19 from alpaca-tc/refactor-methods
Browse files Browse the repository at this point in the history
Refactor gem
  • Loading branch information
alpaca-tc authored Apr 24, 2024
2 parents feed044 + 7603df8 commit 0c3ed94
Show file tree
Hide file tree
Showing 6 changed files with 49 additions and 58 deletions.
15 changes: 0 additions & 15 deletions lib/diver_down/helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -62,20 +62,5 @@ def self.class?(obj)
def self.constantize(str)
::ActiveSupport::Inflector.constantize(str)
end

# @param hash [Hash]
# @return [Hash]
def self.deep_symbolize_keys(object)
case object
when Hash
object.each_with_object({}) do |(key, value), memo|
memo[key.to_sym] = deep_symbolize_keys(value)
end
when Array
object.map { deep_symbolize_keys(_1) }
else
object
end
end
end
end
19 changes: 12 additions & 7 deletions lib/diver_down/trace/call_stack.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,24 +14,29 @@ class StackEmptyError < RuntimeError; end
def initialize
@ignored_stack_size = nil
@stack_size = 0
@stack = {}
@context_stack = {}
end

# @return [Boolean]
def empty?
@stack.empty?
def empty_context_stack?
@context_stack.empty?
end

# @return [Array<Integer>]
def context_stack_size
@context_stack.keys
end

# @return [Array<Object>]
def stack
@stack.values
def context_stack
@context_stack.values
end

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

Expand All @@ -46,7 +51,7 @@ def ignored?
def pop
raise StackEmptyError if @stack_size.zero?

@stack.delete(@stack_size) if @stack.key?(@stack_size)
@context_stack.delete(@stack_size) if @context_stack.key?(@stack_size)
@ignored_stack_size = nil if @ignored_stack_size && @ignored_stack_size == @stack_size
@stack_size -= 1
end
Expand Down
25 changes: 19 additions & 6 deletions lib/diver_down/trace/session.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ class Session

# @param [DiverDown::Trace::ModuleSet, nil] module_set
# @param [DiverDown::Trace::IgnoredMethodIds, nil] ignored_method_ids
# @param [Set<String>, nil] target_file_set
# @param [Set<String>, nil] List of paths to finish traversing when searching for a caller. If nil, all paths are finished.
# @param [#call, nil] filter_method_id_path
def initialize(module_set: DiverDown::Trace::ModuleSet.new, ignored_method_ids: nil, target_file_set: nil, filter_method_id_path: nil, definition: DiverDown::Definition.new)
@module_set = module_set
Expand Down Expand Up @@ -55,21 +55,26 @@ def build_trace_point

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

if mod.nil?
call_stack.push
next
end

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)
source_name = DiverDown::Helper.normalize_module_name(mod) if @module_set.include?(mod)
pushed = false

unless source_name.nil?
# If the call stack contains a call to a module to be traced
# `@ignored_call_stack` is not nil means the call stack contains a call to a module to be ignored
unless call_stack.empty?
unless call_stack.empty_context_stack?
# Add dependency to called source
called_stack_context = call_stack.stack[-1]
called_stack_context = call_stack.context_stack[-1]
called_source = called_stack_context.source
dependency = called_source.find_or_build_dependency(source_name)

Expand All @@ -84,9 +89,17 @@ def build_trace_point
end
end

# `caller_location` is nil if it is filtered by target_files
caller_location = find_neast_caller_location(call_stack.stack_size)
# Search is a heavy process and should be terminated early.
# The position of the most recently found caller or the start of trace is used as the maximum value.
maximum_back_stack_size = if call_stack.empty_context_stack?
call_stack.stack_size
else
call_stack.stack_size - call_stack.context_stack_size[-1]
end

caller_location = find_neast_caller_location(maximum_back_stack_size)

# `caller_location` is nil if it is filtered by target_files
if caller_location
pushed = true
source = @definition.find_or_build_source(source_name)
Expand Down
18 changes: 0 additions & 18 deletions spec/diver_down/helper_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -169,23 +169,5 @@ def self.name
expect(described_class.constantize('String')).to eq(String)
end
end

describe '.deep_symbolize_keys' do
it 'returns symbolized hash' do
hash = {
'a' => 1,
'b' => {
'c' => 2,
},
}

expect(described_class.deep_symbolize_keys(hash)).to eq(
a: 1,
b: {
c: 2,
}
)
end
end
end
end
28 changes: 17 additions & 11 deletions spec/diver_down/trace/call_stack_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
end
end

describe '#stack/push/pop' do
describe '#context_stack/#context_stack_size/push/pop' do
it 'pushes and pops' do
stack = described_class.new

Expand All @@ -23,20 +23,26 @@
stack.push
stack.push('C')

expect(stack.stack).to eq(['A', 'B', 'C'])
expect(stack.context_stack).to eq(['A', 'B', 'C'])
expect(stack.context_stack_size).to eq([2, 4, 6])
stack.pop

expect(stack.stack).to eq(['A', 'B'])
expect(stack.context_stack).to eq(['A', 'B'])
expect(stack.context_stack_size).to eq([2, 4])
stack.pop
expect(stack.stack).to eq(['A', 'B'])
expect(stack.context_stack).to eq(['A', 'B'])
expect(stack.context_stack_size).to eq([2, 4])
stack.pop

expect(stack.stack).to eq(['A'])
expect(stack.context_stack).to eq(['A'])
expect(stack.context_stack_size).to eq([2])
stack.pop
expect(stack.stack).to eq(['A'])
expect(stack.context_stack).to eq(['A'])
expect(stack.context_stack_size).to eq([2])
stack.pop

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

context 'with _ignored: true' do
Expand All @@ -58,16 +64,16 @@
end
end

describe '#empty?' do
describe '#empty_context_stack?' do
it 'returns true if stack is not empty' do
stack = described_class.new
expect(stack.empty?).to eq(true)
expect(stack.empty_context_stack?).to eq(true)

stack.push
expect(stack.empty?).to eq(true)
expect(stack.empty_context_stack?).to eq(true)

stack.push('A')
expect(stack.empty?).to eq(false)
expect(stack.empty_context_stack?).to eq(false)
end
end
end
Expand Down
2 changes: 1 addition & 1 deletion spec/diver_down/trace/tracer_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -786,7 +786,7 @@ def self.call
# }
# )
#
# tracer.trace(title: '') do
# tracer.trace do
# antipollution_environment.send(:run)
# end
# end
Expand Down

0 comments on commit 0c3ed94

Please sign in to comment.