rshade 0.1.9 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
[![asciicast](https://asciinema.org/a/MR5KL7TmHmYRUhwBUWQjBI373.svg)](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
|