rshade 0.1.9.1 → 0.2.1
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/.rubocop.yml +31 -0
- data/Gemfile +9 -2
- data/Gemfile.lock +11 -2
- data/README.md +20 -3
- data/Rakefile +5 -3
- data/bin/console +4 -3
- data/lib/rshade/config/registry.rb +40 -0
- data/lib/rshade/config/stack_store.rb +63 -0
- data/lib/rshade/config/store.rb +12 -7
- data/lib/rshade/config.rb +8 -7
- data/lib/rshade/core_extensions/object/reveal.rb +37 -5
- data/lib/rshade/event.rb +15 -5
- data/lib/rshade/event_observer.rb +3 -1
- data/lib/rshade/event_processor.rb +12 -11
- data/lib/rshade/event_tree.rb +18 -18
- data/lib/rshade/filter/abstract_filter.rb +3 -1
- data/lib/rshade/filter/default.rb +4 -2
- data/lib/rshade/filter/exclude_path_filter.rb +5 -3
- data/lib/rshade/filter/filter_builder.rb +14 -3
- data/lib/rshade/filter/filter_composition.rb +29 -25
- data/lib/rshade/filter/include_path_filter.rb +6 -1
- data/lib/rshade/filter/variable_filter.rb +5 -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 +53 -0
- data/lib/rshade/formatter/trace/file.rb +31 -0
- data/lib/rshade/formatter/trace/html.rb +36 -0
- data/lib/rshade/formatter/trace/json.rb +60 -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 +8 -5
- data/lib/rshade/serializer/traversal.rb +10 -8
- data/lib/rshade/stack.rb +26 -0
- data/lib/rshade/stack_frame.rb +61 -0
- data/lib/rshade/trace.rb +7 -4
- data/lib/rshade/trace_observable.rb +10 -5
- data/lib/rshade/version.rb +3 -1
- data/lib/rshade.rb +25 -8
- data/rshade.gemspec +24 -22
- metadata +29 -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
- data/lib/rshade/rails/rails.rb +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: efdbfc08fca88589c49b580abbbeb36687b68986e365291c2c4758633b33943d
|
4
|
+
data.tar.gz: 78e8147a5539bb79216281763274c676d916729b62af681b2811caa1772f7031
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 39fad4c1cb0663e510aaee89100090a10e689880da9f2fb2422fc404094337bad4bcbd5bb72a96270b284a3709392d4d9879cb1410d8f912d8e55db2962a8e4f
|
7
|
+
data.tar.gz: de5d785cfe183f5a7109aeebb128086e0173ce126788165b7dc18b818de066909830e628b5322c84ff6c9655696cb34cc8c7d289aafff036965f6a7caeb7bda0
|
data/.gitignore
CHANGED
data/.rubocop.yml
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
# The behavior of RuboCop can be controlled via the .rubocop.yml
|
2
|
+
# configuration file. It makes it possible to enable/disable
|
3
|
+
# certain cops (checks) and to alter their behavior if they accept
|
4
|
+
# any parameters. The file can be placed either in your home
|
5
|
+
# directory or in some project directory.
|
6
|
+
#
|
7
|
+
# RuboCop will start looking for the configuration file in the directory
|
8
|
+
# where the inspected file is and continue its way up to the root directory.
|
9
|
+
#
|
10
|
+
# See https://docs.rubocop.org/rubocop/configuration
|
11
|
+
AllCops:
|
12
|
+
NewCops: enable
|
13
|
+
Exclude:
|
14
|
+
- 'spec/fixture/**/*'
|
15
|
+
Style/HashSyntax:
|
16
|
+
EnforcedShorthandSyntax: never
|
17
|
+
|
18
|
+
Naming/MethodParameterName:
|
19
|
+
Exclude:
|
20
|
+
- spec/**/*
|
21
|
+
- test.rb
|
22
|
+
Style/Documentation:
|
23
|
+
Enabled: false
|
24
|
+
Metrics/BlockLength:
|
25
|
+
Max: 75
|
26
|
+
Metrics/MethodLength:
|
27
|
+
Max: 30
|
28
|
+
Metrics/PerceivedComplexity:
|
29
|
+
Max: 10
|
30
|
+
Metrics/AbcSize:
|
31
|
+
Max: 30
|
data/Gemfile
CHANGED
@@ -1,10 +1,17 @@
|
|
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 'bundler', '~> 2.2.33'
|
13
|
+
gem 'prism'
|
9
14
|
gem 'pry'
|
15
|
+
gem 'rake', '>= 12.3.3'
|
16
|
+
gem 'rspec', '~> 3.0'
|
10
17
|
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.1)
|
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
|
-
colorize (
|
15
|
+
colorize (1.1.0)
|
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,22 @@ 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
|
+
|
106
|
+
```ruby
|
107
|
+
::RShade::Config::Registry.instance.stack_config do |config|
|
108
|
+
config.exclude_gems!
|
109
|
+
filepath = File.join(Rails.root, 'log', 'rshade-stack.json.log')
|
110
|
+
config.formatter!(:json, { filepath: filepath, pretty: false })
|
111
|
+
end
|
112
|
+
```
|
113
|
+
|
114
|
+
Execute (put in any place where you want reveal stack)
|
115
|
+
```ruby
|
116
|
+
::RShade::Stack.trace
|
117
|
+
```
|
118
|
+
|
102
119
|
## TODO
|
103
120
|
Use stack to keep connections between current method and caller
|
104
121
|
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,40 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RShade
|
4
|
+
class Config
|
5
|
+
class Registry
|
6
|
+
include Singleton
|
7
|
+
attr_reader :map, :mutex
|
8
|
+
|
9
|
+
def initialize
|
10
|
+
@map = {}
|
11
|
+
@mutex = Mutex.new
|
12
|
+
defaults
|
13
|
+
end
|
14
|
+
|
15
|
+
def default_stack_config
|
16
|
+
val = nil
|
17
|
+
mutex.synchronize do
|
18
|
+
val = map[:store_default]
|
19
|
+
end
|
20
|
+
val
|
21
|
+
end
|
22
|
+
|
23
|
+
def stack_config(&block)
|
24
|
+
val = nil
|
25
|
+
mutex.synchronize do
|
26
|
+
val = ::RShade::Config::StackStore.new
|
27
|
+
block.call(val)
|
28
|
+
map[:store_default] = val
|
29
|
+
end
|
30
|
+
val
|
31
|
+
end
|
32
|
+
|
33
|
+
def defaults
|
34
|
+
mutex.synchronize do
|
35
|
+
map[:store_default] = ::RShade::Config::StackStore.new
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,63 @@
|
|
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
|
+
stdout: ::RShade::Formatter::Stack::Stdout
|
11
|
+
}.freeze
|
12
|
+
|
13
|
+
# @param [Hash] options
|
14
|
+
# @option options [::RShade::Filter::FilterComposition] :filter_composition
|
15
|
+
# @option options [#call(event_store)] :formatter
|
16
|
+
def initialize(options = {})
|
17
|
+
@filter = options.fetch(:filter, default_filter_composition)
|
18
|
+
@formatter = options.fetch(:formatter, ::RShade::Formatter::Stack::Stdout.new)
|
19
|
+
@custom_serializers = options.fetch(:custom_serializers, {})
|
20
|
+
end
|
21
|
+
|
22
|
+
def add_custom_serializers(hash)
|
23
|
+
custom_serializers.merge!(hash)
|
24
|
+
self
|
25
|
+
end
|
26
|
+
|
27
|
+
def config_filter(filter_type, &block)
|
28
|
+
filter.config_filter(filter_type, &block)
|
29
|
+
self
|
30
|
+
end
|
31
|
+
|
32
|
+
def formatter!(formatter, opts = {})
|
33
|
+
@formatter = formatter.is_a?(Symbol) ? set_symbol_formatter(formatter, opts) : formatter
|
34
|
+
self
|
35
|
+
end
|
36
|
+
|
37
|
+
def exclude_gems!
|
38
|
+
config_filter(::RShade::Filter::ExcludePathFilter) do |paths|
|
39
|
+
paths.concat(RShade::Config.default_excluded_path)
|
40
|
+
end
|
41
|
+
self
|
42
|
+
end
|
43
|
+
|
44
|
+
private
|
45
|
+
|
46
|
+
def set_symbol_formatter(type, opts)
|
47
|
+
formatter_class = DEFAULT_FORMATTER[type]
|
48
|
+
return formatter_class unless formatter_class
|
49
|
+
|
50
|
+
@formatter = formatter_class.new(**opts)
|
51
|
+
end
|
52
|
+
|
53
|
+
def default_filter_composition
|
54
|
+
variable_filter = RShade::Filter::VariableFilter.new
|
55
|
+
include_filter = RShade::Filter::IncludePathFilter.new
|
56
|
+
exclude_filter = RShade::Filter::ExcludePathFilter.new
|
57
|
+
|
58
|
+
RShade::Filter::FilterBuilder.build([:or,
|
59
|
+
[:or, variable_filter, include_filter], exclude_filter])
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
data/lib/rshade/config/store.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
|
2
3
|
module RShade
|
3
4
|
class Config
|
@@ -8,14 +9,14 @@ module RShade
|
|
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])
|
15
16
|
@custom_serializers = options.fetch(:custom_serializers, {})
|
16
17
|
end
|
17
18
|
|
18
|
-
def
|
19
|
+
def tp_events!(tp_events)
|
19
20
|
@tp_events = tp_events
|
20
21
|
self
|
21
22
|
end
|
@@ -25,13 +26,12 @@ module RShade
|
|
25
26
|
self
|
26
27
|
end
|
27
28
|
|
28
|
-
|
29
29
|
def config_filter(filter_type, &block)
|
30
30
|
filter_composition.config_filter(filter_type, &block)
|
31
31
|
self
|
32
32
|
end
|
33
33
|
|
34
|
-
def
|
34
|
+
def formatter!(formatter)
|
35
35
|
@formatter = formatter
|
36
36
|
self
|
37
37
|
end
|
@@ -39,7 +39,12 @@ module RShade
|
|
39
39
|
private
|
40
40
|
|
41
41
|
def default_filter_composition
|
42
|
-
|
42
|
+
variable_filter = RShade::Filter::VariableFilter.new
|
43
|
+
include_filter = RShade::Filter::IncludePathFilter.new
|
44
|
+
exclude_filter = RShade::Filter::ExcludePathFilter.new
|
45
|
+
|
46
|
+
RShade::Filter::FilterBuilder.build([:or,
|
47
|
+
[:or, variable_filter, include_filter], exclude_filter])
|
43
48
|
end
|
44
49
|
end
|
45
50
|
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
|
-
RUBY_VERSION_PATTERN = /ruby-[0-9.]
|
5
|
+
RUBY_VERSION_PATTERN = /ruby-[0-9.]*/.freeze
|
4
6
|
|
5
7
|
def self.default
|
6
|
-
::RShade::Config::Store.new.
|
8
|
+
::RShade::Config::Store.new.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,13 +22,13 @@ 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
|
|
27
29
|
def tp_events(&block)
|
28
30
|
events = block.call
|
29
|
-
@config_store.
|
31
|
+
@config_store.tp_events!(events)
|
30
32
|
self
|
31
33
|
end
|
32
34
|
|
@@ -47,7 +49,7 @@ module RShade
|
|
47
49
|
|
48
50
|
def formatter(&block)
|
49
51
|
formatter = block.call
|
50
|
-
@config_store.
|
52
|
+
@config_store.formatter!(formatter)
|
51
53
|
self
|
52
54
|
end
|
53
55
|
|
@@ -68,9 +70,8 @@ module RShade
|
|
68
70
|
@root_dir ||= File.expand_path('../../', __dir__)
|
69
71
|
end
|
70
72
|
|
71
|
-
private
|
72
73
|
def self.default_excluded_path
|
73
|
-
[ENV['GEM_PATH'].split(':'), RUBY_VERSION_PATTERN, /internal/].flatten.compact
|
74
|
+
[ENV['GEM_PATH'].split(':'), RUBY_VERSION_PATTERN, /internal/, %r{/gems/}].flatten.compact
|
74
75
|
end
|
75
76
|
end
|
76
77
|
end
|
@@ -1,8 +1,40 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
class Object
|
2
|
-
|
3
|
-
|
4
|
-
|
4
|
+
# rubocop:disable Metrics/MethodLength
|
5
|
+
def reveal(method_name = nil, **opts, &block)
|
6
|
+
if method_name
|
7
|
+
@__cache_rshade_reveal ||= {}
|
8
|
+
config = opts.fetch(:config, ::RShade::Config.default)
|
9
|
+
@__cache_rshade_reveal[method_name] = config
|
10
|
+
instance_eval do
|
11
|
+
def method_added(name)
|
12
|
+
super
|
13
|
+
return unless @__cache_rshade_reveal[name]
|
14
|
+
|
15
|
+
if @__reveal_rewrite
|
16
|
+
@__reveal_rewrite = false
|
17
|
+
return
|
18
|
+
end
|
19
|
+
@__reveal_rewrite = true
|
20
|
+
config = @__cache_rshade_reveal[name]
|
21
|
+
origin_method = instance_method(name)
|
22
|
+
define_method(name) do |*args, &fn|
|
23
|
+
val = nil
|
24
|
+
trace = ::RShade::Trace.reveal(config) do
|
25
|
+
val = origin_method.bind(self).call(*args, &fn)
|
26
|
+
end
|
27
|
+
trace.show
|
28
|
+
val
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
else
|
33
|
+
trace = ::RShade::Trace.reveal do
|
34
|
+
block.call if block_given?
|
35
|
+
end
|
36
|
+
trace.show
|
5
37
|
end
|
6
|
-
trace.show
|
7
38
|
end
|
8
|
-
|
39
|
+
# rubocop:enable Metrics/MethodLength
|
40
|
+
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
|
@@ -20,7 +22,7 @@ module RShade
|
|
20
22
|
self
|
21
23
|
end
|
22
24
|
|
23
|
-
def
|
25
|
+
def return_value!(return_value)
|
24
26
|
@hash[:return_value] = return_value
|
25
27
|
self
|
26
28
|
end
|
@@ -38,12 +40,20 @@ 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
49
|
hash = { path: evt.path, lineno: evt.lineno, klass: evt.defined_class, method_name: evt.method_id, vars: vars,
|
45
50
|
event_type: evt.event }
|
46
|
-
|
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
|
47
57
|
new(hash)
|
48
58
|
end
|
49
59
|
|
@@ -1,36 +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
8
|
def initialize(store, config)
|
7
9
|
@store = store
|
8
10
|
custom_serializers = config.custom_serializers
|
9
|
-
@
|
11
|
+
@serializer = ::RShade::Serializer::Traversal.new(custom_serializers)
|
10
12
|
end
|
11
13
|
|
12
14
|
# @param [RShade::Event] event
|
13
15
|
# @param [Integer] level
|
14
16
|
def enter(event, level)
|
15
|
-
event.with_serialized_vars!(
|
17
|
+
event.with_serialized_vars!(serializer).with_level!(level)
|
16
18
|
store.add(event, level)
|
17
19
|
end
|
18
20
|
|
19
21
|
# @param [RShade::Event] event
|
20
22
|
# @param [Integer] level
|
21
|
-
def leave(event,
|
23
|
+
def leave(event, _level)
|
22
24
|
store.current! do |node|
|
23
|
-
|
24
|
-
|
25
|
+
node.value.return_value!(event.return_value)
|
26
|
+
.with_serialized_return!(serializer)
|
25
27
|
end
|
26
|
-
rescue
|
28
|
+
rescue StandardError
|
27
29
|
# this rescue here due this issue which reproduce in ruby-2.6.6 at least
|
28
30
|
# https://bugs.ruby-lang.org/issues/18060
|
29
31
|
end
|
32
|
+
|
30
33
|
# @param [RShade::Event] event
|
31
34
|
# @param [Integer] level
|
32
|
-
def other(event, level)
|
33
|
-
|
34
|
-
end
|
35
|
+
def other(event, level); end
|
35
36
|
end
|
36
|
-
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
|
@@ -8,6 +10,7 @@ module RShade
|
|
8
10
|
@current = @head = EventTreeNode.new(nil, 0, nil)
|
9
11
|
end
|
10
12
|
|
13
|
+
# rubocop:disable Metrics/AbcSize
|
11
14
|
def add(value, level)
|
12
15
|
if current.level + 1 == level
|
13
16
|
current.children << EventTreeNode.new(value, level, current)
|
@@ -16,22 +19,19 @@ module RShade
|
|
16
19
|
if current.level + 1 < level
|
17
20
|
|
18
21
|
last = current.children.last
|
19
|
-
unless last
|
20
|
-
current.children << EventTreeNode.new(nil, current.level + 1 , current)
|
21
|
-
end
|
22
|
+
current.children << EventTreeNode.new(nil, current.level + 1, current) unless last
|
22
23
|
@current = current.children.last
|
23
24
|
add(value, level)
|
24
25
|
return
|
25
26
|
end
|
26
27
|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
add(value, level)
|
33
|
-
end
|
28
|
+
return unless current.level + 1 > level
|
29
|
+
return unless current.parent
|
30
|
+
|
31
|
+
@current = current.parent
|
32
|
+
add(value, level)
|
34
33
|
end
|
34
|
+
# rubocop:enable Metrics/AbcSize
|
35
35
|
|
36
36
|
def current!(&block)
|
37
37
|
block.call(current.children.last) if current.children.last
|
@@ -47,29 +47,29 @@ module RShade
|
|
47
47
|
attr_reader :children, :level, :vlevel, :value
|
48
48
|
attr_accessor :parent
|
49
49
|
|
50
|
-
def initialize(value, level, parent=nil)
|
50
|
+
def initialize(value, level, parent = nil)
|
51
51
|
@children = []
|
52
52
|
@level = level
|
53
53
|
@parent = parent
|
54
54
|
@value = value
|
55
|
-
@vlevel =
|
55
|
+
@vlevel = vlevel!(parent)
|
56
56
|
end
|
57
57
|
|
58
58
|
def each(&block)
|
59
|
-
block.call(self) if parent
|
59
|
+
block.call(self) if !parent.nil? || !value.nil?
|
60
60
|
children.each { |item| item.each(&block) }
|
61
61
|
end
|
62
62
|
|
63
63
|
private
|
64
64
|
|
65
|
-
def
|
66
|
-
return 0 if node
|
65
|
+
def vlevel!(node)
|
66
|
+
return 0 if node.nil?
|
67
67
|
|
68
|
-
if node.value || node.level
|
68
|
+
if node.value || node.level.zero?
|
69
69
|
node.vlevel + 1
|
70
70
|
else
|
71
|
-
|
71
|
+
vlevel!(node.parent)
|
72
72
|
end
|
73
73
|
end
|
74
74
|
end
|
75
|
-
end
|
75
|
+
end
|
@@ -1,7 +1,9 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module RShade
|
2
4
|
module Filter
|
3
5
|
class Default
|
4
|
-
RUBY_VERSION_PATTERN = /ruby-[0-9.]
|
6
|
+
RUBY_VERSION_PATTERN = /ruby-[0-9.]*/.freeze
|
5
7
|
|
6
8
|
def self.create
|
7
9
|
new.create
|
@@ -25,4 +27,4 @@ module RShade
|
|
25
27
|
end
|
26
28
|
end
|
27
29
|
end
|
28
|
-
end
|
30
|
+
end
|