rshade 0.1.9 → 0.2.0
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 +2 -1
- data/Gemfile +6 -2
- data/Gemfile.lock +10 -1
- data/README.md +19 -3
- data/Rakefile +5 -3
- data/bin/console +4 -3
- data/lib/rshade/config/registry.rb +47 -0
- data/lib/rshade/config/stack_store.rb +58 -0
- data/lib/rshade/config/store.rb +14 -5
- data/lib/rshade/config.rb +9 -3
- data/lib/rshade/core_extensions/object/reveal.rb +34 -5
- data/lib/rshade/event.rb +15 -9
- data/lib/rshade/event_observer.rb +3 -1
- data/lib/rshade/event_processor.rb +14 -12
- data/lib/rshade/event_tree.rb +13 -15
- data/lib/rshade/filter/abstract_filter.rb +3 -1
- data/lib/rshade/filter/default.rb +3 -1
- data/lib/rshade/filter/exclude_path_filter.rb +10 -7
- data/lib/rshade/filter/filter_builder.rb +14 -3
- data/lib/rshade/filter/filter_composition.rb +26 -24
- data/lib/rshade/filter/include_path_filter.rb +5 -1
- data/lib/rshade/filter/variable_filter.rb +4 -1
- data/lib/rshade/formatter/stack/json.rb +51 -0
- data/lib/rshade/formatter/stack/stdout.rb +13 -0
- data/lib/rshade/formatter/stack/string.rb +41 -0
- data/lib/rshade/formatter/trace/file.rb +33 -0
- data/lib/rshade/formatter/trace/html.rb +38 -0
- data/lib/rshade/formatter/trace/json.rb +61 -0
- data/lib/rshade/formatter/trace/stdout.rb +14 -0
- data/lib/rshade/formatter/trace/string.rb +48 -0
- data/lib/rshade/rspec/rspec.rb +7 -6
- data/lib/rshade/serializer/traversal.rb +54 -0
- data/lib/rshade/stack.rb +26 -0
- data/lib/rshade/stack_frame.rb +60 -0
- data/lib/rshade/trace.rb +8 -5
- data/lib/rshade/trace_observable.rb +5 -0
- data/lib/rshade/version.rb +3 -1
- data/lib/rshade.rb +26 -10
- data/rshade.gemspec +24 -21
- metadata +44 -9
- data/lib/rshade/binding_serializer.rb +0 -35
- data/lib/rshade/formatter/file.rb +0 -28
- data/lib/rshade/formatter/html.rb +0 -33
- data/lib/rshade/formatter/json.rb +0 -59
- data/lib/rshade/formatter/stdout.rb +0 -10
- data/lib/rshade/formatter/string.rb +0 -36
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 39758f070ab0a6b6e7dc0bdc09aa03bb107130f84fe7115331189a31c0e013eb
|
4
|
+
data.tar.gz: 0331bdd526cd0155df7d210603bb07a15c9541bcce62197b2754731e640060c3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b0c97b53d02f997d05484e850655dfe561c82da1d110a111022885278ece826b5fc75b2e5d70260ff59095ca29178e681c85915301a6b171efe263aa42c82f64
|
7
|
+
data.tar.gz: ed9a95bceb71f94cd17587bd88086a6e26d77b5a19fe14ed96b4cfbd559fa1574ffaca380ec3fc49167e788197008bc08b581f83fb5997fb058dedba77e49bf8
|
data/.gitignore
CHANGED
data/Gemfile
CHANGED
@@ -1,10 +1,14 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
3
|
+
source 'https://rubygems.org'
|
4
|
+
|
5
|
+
git_source(:github) { |repo_name| "https://github.com/#{repo_name}" }
|
4
6
|
|
5
7
|
# Specify your gem's dependencies in rshade.gemspec
|
6
8
|
gemspec
|
7
9
|
|
8
10
|
group :development, :test do
|
11
|
+
gem 'binding_of_caller'
|
12
|
+
gem 'prism'
|
9
13
|
gem 'pry'
|
10
14
|
end
|
data/Gemfile.lock
CHANGED
@@ -1,16 +1,22 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
rshade (0.
|
4
|
+
rshade (0.2.0)
|
5
|
+
binding_of_caller
|
5
6
|
colorize
|
7
|
+
prism
|
6
8
|
|
7
9
|
GEM
|
8
10
|
remote: https://rubygems.org/
|
9
11
|
specs:
|
12
|
+
binding_of_caller (1.0.1)
|
13
|
+
debug_inspector (>= 1.2.0)
|
10
14
|
coderay (1.1.3)
|
11
15
|
colorize (0.8.1)
|
16
|
+
debug_inspector (1.2.0)
|
12
17
|
diff-lcs (1.5.0)
|
13
18
|
method_source (1.0.0)
|
19
|
+
prism (1.3.0)
|
14
20
|
pry (0.14.1)
|
15
21
|
coderay (~> 1.1)
|
16
22
|
method_source (~> 1.0)
|
@@ -32,9 +38,12 @@ GEM
|
|
32
38
|
PLATFORMS
|
33
39
|
x86_64-darwin-19
|
34
40
|
x86_64-darwin-20
|
41
|
+
x86_64-darwin-22
|
35
42
|
|
36
43
|
DEPENDENCIES
|
44
|
+
binding_of_caller
|
37
45
|
bundler (~> 2.2.33)
|
46
|
+
prism
|
38
47
|
pry
|
39
48
|
rake (>= 12.3.3)
|
40
49
|
rshade!
|
data/README.md
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
# RShade
|
2
|
-
|
3
|
-
|
2
|
+
<p align="center">
|
3
|
+
<img src="https://github.com/gingray/rshade/raw/master/shade.jpg">
|
4
|
+
</p>
|
4
5
|
|
5
6
|
RShade is a debugging/code exploration tool based on `TracePoint` functionality.
|
6
7
|
Recent years I've working with relatively huge legacy code and I need a tool which can help me to figure out what is going on due execution.
|
@@ -85,7 +86,7 @@ On such huge codebase as spree it's helpful to know what callbacks are triggered
|
|
85
86
|
context 'when cost currency is nil' do
|
86
87
|
before { variant.cost_currency = nil }
|
87
88
|
|
88
|
-
it 'populates cost currency with the default value on save'
|
89
|
+
it 'populates cost currency with the default value on save' do
|
89
90
|
RShade::Trace.reveal do
|
90
91
|
variant.save!
|
91
92
|
end
|
@@ -99,6 +100,21 @@ Below is example how output will look like.
|
|
99
100
|
As you can see all code that have been in use is printed.
|
100
101
|
[](https://asciinema.org/a/MR5KL7TmHmYRUhwBUWQjBI373)
|
101
102
|
|
103
|
+
## Stack reveal
|
104
|
+
Config
|
105
|
+
```ruby
|
106
|
+
::RShade::Config::Registry.instance.stack_config do |config|
|
107
|
+
config.exclude_gems!
|
108
|
+
filepath = File.join(Rails.root, 'log', 'rshade-stack.json.log')
|
109
|
+
config.set_formatter(:json, { filepath: filepath, pretty: false })
|
110
|
+
end
|
111
|
+
```
|
112
|
+
|
113
|
+
Execute (put in any place where you want reveal stack)
|
114
|
+
```ruby
|
115
|
+
::RShade::Stack.trace
|
116
|
+
```
|
117
|
+
|
102
118
|
## TODO
|
103
119
|
Use stack to keep connections between current method and caller
|
104
120
|
take a look on https://github.com/matugm/visual-call-graph
|
data/Rakefile
CHANGED
data/bin/console
CHANGED
@@ -1,7 +1,8 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
2
3
|
|
3
|
-
require
|
4
|
-
require
|
4
|
+
require 'bundler/setup'
|
5
|
+
require 'rshade'
|
5
6
|
|
6
7
|
# You can add fixtures and/or initialization code here to make experimenting
|
7
8
|
# with your gem easier. You can also use a different console, if you like.
|
@@ -10,5 +11,5 @@ require "rshade"
|
|
10
11
|
# require "pry"
|
11
12
|
# Pry.start
|
12
13
|
|
13
|
-
require
|
14
|
+
require 'irb'
|
14
15
|
IRB.start(__FILE__)
|
@@ -0,0 +1,47 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RShade
|
4
|
+
class Config
|
5
|
+
class Registry
|
6
|
+
attr_reader :map, :mutex
|
7
|
+
|
8
|
+
include Singleton
|
9
|
+
|
10
|
+
def initialize
|
11
|
+
@map = {}
|
12
|
+
@mutex = Mutex.new
|
13
|
+
defaults
|
14
|
+
end
|
15
|
+
|
16
|
+
def set_default_stack(config)
|
17
|
+
mutex.synchronize do
|
18
|
+
map[:store_default] = config
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def default_stack_config
|
23
|
+
val = nil
|
24
|
+
mutex.synchronize do
|
25
|
+
val = map[:store_default]
|
26
|
+
end
|
27
|
+
val
|
28
|
+
end
|
29
|
+
|
30
|
+
def stack_config(&block)
|
31
|
+
val = nil
|
32
|
+
mutex.synchronize do
|
33
|
+
val = ::RShade::Config::StackStore.new
|
34
|
+
block.call(val)
|
35
|
+
map[:store_default] = val
|
36
|
+
end
|
37
|
+
val
|
38
|
+
end
|
39
|
+
|
40
|
+
def defaults
|
41
|
+
mutex.synchronize do
|
42
|
+
map[:store_default] = ::RShade::Config::StackStore.new
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RShade
|
4
|
+
class Config
|
5
|
+
class StackStore
|
6
|
+
attr_reader :filter, :formatter, :custom_serializers
|
7
|
+
|
8
|
+
DEFAULT_FORMATTER = {
|
9
|
+
json: ::RShade::Formatter::Stack::Json
|
10
|
+
}.freeze
|
11
|
+
|
12
|
+
# @param [Hash] options
|
13
|
+
# @option options [::RShade::Filter::FilterComposition] :filter_composition
|
14
|
+
# @option options [#call(event_store)] :formatter
|
15
|
+
def initialize(options = {})
|
16
|
+
@filter = options.fetch(:filter, default_filter_composition)
|
17
|
+
@formatter = options.fetch(:formatter, ::RShade::Formatter::Stack::Stdout.new)
|
18
|
+
@custom_serializers = options.fetch(:custom_serializers, {})
|
19
|
+
end
|
20
|
+
|
21
|
+
def add_custom_serializers(hash)
|
22
|
+
custom_serializers.merge!(hash)
|
23
|
+
self
|
24
|
+
end
|
25
|
+
|
26
|
+
def config_filter(filter_type, &block)
|
27
|
+
filter.config_filter(filter_type, &block)
|
28
|
+
self
|
29
|
+
end
|
30
|
+
|
31
|
+
def set_formatter(formatter, opts = {})
|
32
|
+
@formatter = formatter.is_a?(Symbol) ? set_symbol_formatter(formatter, opts) : formatter
|
33
|
+
self
|
34
|
+
end
|
35
|
+
|
36
|
+
def exclude_gems!
|
37
|
+
config_filter(::RShade::Filter::ExcludePathFilter) do |paths|
|
38
|
+
paths.concat(RShade::Config.default_excluded_path)
|
39
|
+
end
|
40
|
+
self
|
41
|
+
end
|
42
|
+
|
43
|
+
private
|
44
|
+
|
45
|
+
def set_symbol_formatter(type, opts)
|
46
|
+
formatter_class = DEFAULT_FORMATTER[type]
|
47
|
+
return formatter_class unless formatter_class
|
48
|
+
|
49
|
+
@formatter = formatter_class.new(**opts)
|
50
|
+
end
|
51
|
+
|
52
|
+
def default_filter_composition
|
53
|
+
RShade::Filter::FilterBuilder.build([:or,
|
54
|
+
[:or, RShade::Filter::VariableFilter.new, RShade::Filter::IncludePathFilter.new], RShade::Filter::ExcludePathFilter.new])
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
data/lib/rshade/config/store.rb
CHANGED
@@ -1,21 +1,29 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
|
2
3
|
module RShade
|
3
4
|
class Config
|
4
5
|
class Store
|
5
|
-
attr_reader :filter_composition, :formatter, :tp_events
|
6
|
+
attr_reader :filter_composition, :formatter, :tp_events, :custom_serializers
|
6
7
|
|
7
8
|
# @param [Hash] options
|
8
9
|
# @option options [RShade::Filter::FilterComposition] :filter_composition
|
9
10
|
# @option options [#call(event_store)] :formatter
|
10
11
|
# @option options [Array<Symbol>] :tp_events
|
11
|
-
def initialize(options={})
|
12
|
+
def initialize(options = {})
|
12
13
|
@filter_composition = options.fetch(:filter_composition, default_filter_composition)
|
13
|
-
@formatter = options.fetch(:formatter, ::RShade::Formatter::Stdout)
|
14
|
-
@tp_events = options.fetch(:tp_events, [
|
14
|
+
@formatter = options.fetch(:formatter, ::RShade::Formatter::Trace::Stdout)
|
15
|
+
@tp_events = options.fetch(:tp_events, %i[call return])
|
16
|
+
@custom_serializers = options.fetch(:custom_serializers, {})
|
15
17
|
end
|
16
18
|
|
17
19
|
def set_tp_events(tp_events)
|
18
20
|
@tp_events = tp_events
|
21
|
+
self
|
22
|
+
end
|
23
|
+
|
24
|
+
def add_custom_serializers(hash)
|
25
|
+
custom_serializers.merge!(hash)
|
26
|
+
self
|
19
27
|
end
|
20
28
|
|
21
29
|
def config_filter(filter_type, &block)
|
@@ -31,7 +39,8 @@ module RShade
|
|
31
39
|
private
|
32
40
|
|
33
41
|
def default_filter_composition
|
34
|
-
RShade::Filter::FilterBuilder.build([:or,
|
42
|
+
RShade::Filter::FilterBuilder.build([:or,
|
43
|
+
[:or, RShade::Filter::VariableFilter.new, RShade::Filter::IncludePathFilter.new], RShade::Filter::ExcludePathFilter.new])
|
35
44
|
end
|
36
45
|
end
|
37
46
|
end
|
data/lib/rshade/config.rb
CHANGED
@@ -1,9 +1,11 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module RShade
|
2
4
|
class Config
|
3
5
|
RUBY_VERSION_PATTERN = /ruby-[0-9.]*/
|
4
6
|
|
5
7
|
def self.default
|
6
|
-
::RShade::Config::Store.new.set_formatter(::RShade::Formatter::Stdout.new)
|
8
|
+
::RShade::Config::Store.new.set_formatter(::RShade::Formatter::Trace::Stdout.new)
|
7
9
|
.config_filter(::RShade::Filter::ExcludePathFilter) do |paths|
|
8
10
|
default_excluded_path.each do |path|
|
9
11
|
paths << path
|
@@ -20,7 +22,7 @@ module RShade
|
|
20
22
|
# @option options [RShade::Filter::FilterComposition] :filter_composition
|
21
23
|
# @option options [#call(event_store)] :formatter
|
22
24
|
# @option options [Array<Symbol>] :tp_events
|
23
|
-
def self.create(options={})
|
25
|
+
def self.create(options = {})
|
24
26
|
new(Config::Store.new(options))
|
25
27
|
end
|
26
28
|
|
@@ -51,6 +53,11 @@ module RShade
|
|
51
53
|
self
|
52
54
|
end
|
53
55
|
|
56
|
+
def add_custom_serializers(hash)
|
57
|
+
@config_store.add_custom_serializers(hash)
|
58
|
+
self
|
59
|
+
end
|
60
|
+
|
54
61
|
def value
|
55
62
|
@config_store
|
56
63
|
end
|
@@ -63,7 +70,6 @@ module RShade
|
|
63
70
|
@root_dir ||= File.expand_path('../../', __dir__)
|
64
71
|
end
|
65
72
|
|
66
|
-
private
|
67
73
|
def self.default_excluded_path
|
68
74
|
[ENV['GEM_PATH'].split(':'), RUBY_VERSION_PATTERN, /internal/].flatten.compact
|
69
75
|
end
|
@@ -1,8 +1,37 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
class Object
|
2
|
-
def reveal(&block)
|
3
|
-
|
4
|
-
|
4
|
+
def reveal(method_name = nil, **opts, &block)
|
5
|
+
if method_name
|
6
|
+
@__cache_rshade_reveal ||= {}
|
7
|
+
config = opts.fetch(:config, ::RShade::Config.default)
|
8
|
+
@__cache_rshade_reveal[method_name] = config
|
9
|
+
instance_eval do
|
10
|
+
def method_added(name)
|
11
|
+
return unless @__cache_rshade_reveal[name]
|
12
|
+
|
13
|
+
if @__reveal_rewrite
|
14
|
+
@__reveal_rewrite = false
|
15
|
+
return
|
16
|
+
end
|
17
|
+
@__reveal_rewrite = true
|
18
|
+
config = @__cache_rshade_reveal[name]
|
19
|
+
origin_method = instance_method(name)
|
20
|
+
define_method(name) do |*args, &fn|
|
21
|
+
val = nil
|
22
|
+
trace = ::RShade::Trace.reveal(config) do
|
23
|
+
val = origin_method.bind(self).call(*args, &fn)
|
24
|
+
end
|
25
|
+
trace.show
|
26
|
+
val
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
else
|
31
|
+
trace = ::RShade::Trace.reveal do
|
32
|
+
block.call if block_given?
|
33
|
+
end
|
34
|
+
trace.show
|
5
35
|
end
|
6
|
-
trace.show
|
7
36
|
end
|
8
|
-
end
|
37
|
+
end
|
data/lib/rshade/event.rb
CHANGED
@@ -1,15 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module RShade
|
2
4
|
# nodoc
|
3
5
|
class Event
|
4
6
|
attr_reader :hash, :skipped
|
5
|
-
RETURN_EVENTS = [:return, :b_return, :c_return]
|
6
7
|
|
8
|
+
RETURN_EVENTS = %i[return b_return c_return].freeze
|
7
9
|
|
8
10
|
def initialize(hash)
|
9
11
|
@hash = hash
|
10
12
|
end
|
11
13
|
|
12
|
-
[
|
14
|
+
%i[klass path lineno method_name vars level return_value].each do |method_name|
|
13
15
|
define_method method_name do
|
14
16
|
fetch method_name
|
15
17
|
end
|
@@ -38,17 +40,21 @@ module RShade
|
|
38
40
|
def self.from_trace_point(evt)
|
39
41
|
vars = {}
|
40
42
|
evt.binding.local_variables.each do |var_name|
|
41
|
-
|
43
|
+
local_val = evt.binding.local_variable_get(var_name)
|
44
|
+
local_val_type = local_val.is_a?(Class) ? local_val : local_val.class
|
45
|
+
hash = { name: var_name, value: local_val, type: local_val_type }
|
46
|
+
vars[var_name] = hash
|
42
47
|
end
|
43
48
|
|
44
|
-
hash = { path: evt.path, lineno: evt.lineno, klass: evt.defined_class, method_name: evt.method_id, vars
|
49
|
+
hash = { path: evt.path, lineno: evt.lineno, klass: evt.defined_class, method_name: evt.method_id, vars:,
|
45
50
|
event_type: evt.event }
|
46
|
-
hash.merge!({return_value: evt.return_value}) if RETURN_EVENTS.include?(evt.event)
|
47
|
-
new(hash)
|
48
|
-
end
|
49
51
|
|
50
|
-
|
51
|
-
|
52
|
+
if RETURN_EVENTS.include?(evt.event)
|
53
|
+
ret_val = evt.return_value
|
54
|
+
ret_val_type = evt.return_value.is_a?(Class) ? evt.return_value : evt.return_value.class
|
55
|
+
hash.merge!({ return_value: { value: ret_val, type: ret_val_type } })
|
56
|
+
end
|
57
|
+
new(hash)
|
52
58
|
end
|
53
59
|
|
54
60
|
private
|
@@ -1,35 +1,37 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module RShade
|
2
4
|
# nodoc
|
3
5
|
class EventProcessor
|
4
|
-
attr_reader :store
|
6
|
+
attr_reader :store, :serializer
|
5
7
|
|
6
|
-
def initialize(store)
|
8
|
+
def initialize(store, config)
|
7
9
|
@store = store
|
8
|
-
|
10
|
+
custom_serializers = config.custom_serializers
|
11
|
+
@serializer = ::RShade::Serializer::Traversal.new(custom_serializers)
|
9
12
|
end
|
10
13
|
|
11
14
|
# @param [RShade::Event] event
|
12
15
|
# @param [Integer] level
|
13
16
|
def enter(event, level)
|
14
|
-
event.with_serialized_vars!(
|
17
|
+
event.with_serialized_vars!(serializer).with_level!(level)
|
15
18
|
store.add(event, level)
|
16
19
|
end
|
17
20
|
|
18
21
|
# @param [RShade::Event] event
|
19
22
|
# @param [Integer] level
|
20
|
-
def leave(event,
|
23
|
+
def leave(event, _level)
|
21
24
|
store.current! do |node|
|
22
|
-
|
23
|
-
|
25
|
+
node.value.set_return_value!(event.return_value)
|
26
|
+
.with_serialized_return!(serializer)
|
24
27
|
end
|
25
|
-
rescue
|
28
|
+
rescue StandardError
|
26
29
|
# this rescue here due this issue which reproduce in ruby-2.6.6 at least
|
27
30
|
# https://bugs.ruby-lang.org/issues/18060
|
28
31
|
end
|
32
|
+
|
29
33
|
# @param [RShade::Event] event
|
30
34
|
# @param [Integer] level
|
31
|
-
def other(event, level)
|
32
|
-
|
33
|
-
end
|
35
|
+
def other(event, level); end
|
34
36
|
end
|
35
|
-
end
|
37
|
+
end
|
data/lib/rshade/event_tree.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module RShade
|
2
4
|
class EventTree
|
3
5
|
include Enumerable
|
@@ -16,21 +18,17 @@ module RShade
|
|
16
18
|
if current.level + 1 < level
|
17
19
|
|
18
20
|
last = current.children.last
|
19
|
-
unless last
|
20
|
-
current.children << EventTreeNode.new(nil, current.level + 1 , current)
|
21
|
-
end
|
21
|
+
current.children << EventTreeNode.new(nil, current.level + 1, current) unless last
|
22
22
|
@current = current.children.last
|
23
23
|
add(value, level)
|
24
24
|
return
|
25
25
|
end
|
26
26
|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
add(value, level)
|
33
|
-
end
|
27
|
+
return unless current.level + 1 > level
|
28
|
+
return unless current.parent
|
29
|
+
|
30
|
+
@current = current.parent
|
31
|
+
add(value, level)
|
34
32
|
end
|
35
33
|
|
36
34
|
def current!(&block)
|
@@ -47,7 +45,7 @@ module RShade
|
|
47
45
|
attr_reader :children, :level, :vlevel, :value
|
48
46
|
attr_accessor :parent
|
49
47
|
|
50
|
-
def initialize(value, level, parent=nil)
|
48
|
+
def initialize(value, level, parent = nil)
|
51
49
|
@children = []
|
52
50
|
@level = level
|
53
51
|
@parent = parent
|
@@ -56,20 +54,20 @@ module RShade
|
|
56
54
|
end
|
57
55
|
|
58
56
|
def each(&block)
|
59
|
-
block.call(self) if parent
|
57
|
+
block.call(self) if !parent.nil? || !value.nil?
|
60
58
|
children.each { |item| item.each(&block) }
|
61
59
|
end
|
62
60
|
|
63
61
|
private
|
64
62
|
|
65
63
|
def set_vlevel(node)
|
66
|
-
return 0 if node
|
64
|
+
return 0 if node.nil?
|
67
65
|
|
68
|
-
if node.value || node.level
|
66
|
+
if node.value || node.level.zero?
|
69
67
|
node.vlevel + 1
|
70
68
|
else
|
71
69
|
set_vlevel(node.parent)
|
72
70
|
end
|
73
71
|
end
|
74
72
|
end
|
75
|
-
end
|
73
|
+
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module RShade
|
2
4
|
module Filter
|
3
5
|
class ExcludePathFilter < IncludePathFilter
|
@@ -11,14 +13,15 @@ module RShade
|
|
11
13
|
0
|
12
14
|
end
|
13
15
|
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
16
|
+
def call(event)
|
17
|
+
event_path = event.path
|
18
|
+
paths.none? do |path|
|
19
|
+
next str?(path, event_path) if path.is_a? String
|
20
|
+
next regexp?(path, event_path) if path.is_a? Regexp
|
18
21
|
|
19
|
-
|
20
|
-
|
22
|
+
false
|
23
|
+
end
|
21
24
|
end
|
22
25
|
end
|
23
26
|
end
|
24
|
-
end
|
27
|
+
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module RShade
|
2
4
|
module Filter
|
3
5
|
class FilterBuilder
|
@@ -18,11 +20,20 @@ module RShade
|
|
18
20
|
arg1 = arr[1]
|
19
21
|
arg2 = nil
|
20
22
|
arg2 = arr[2] if arity == 2
|
21
|
-
arg1 =
|
22
|
-
|
23
|
+
arg1 = if arg1.is_a?(Array)
|
24
|
+
traverse(arg1)
|
25
|
+
else
|
26
|
+
RShade::Filter::FilterComposition.new(arg1)
|
27
|
+
end
|
28
|
+
|
29
|
+
arg2 = if arg2.is_a?(Array)
|
30
|
+
traverse(arg2)
|
31
|
+
else
|
32
|
+
RShade::Filter::FilterComposition.new(arg2)
|
33
|
+
end
|
23
34
|
|
24
35
|
RShade::Filter::FilterComposition.new(op, arg1, arg2)
|
25
36
|
end
|
26
37
|
end
|
27
38
|
end
|
28
|
-
end
|
39
|
+
end
|