overrider 0.1.4 → 0.1.5
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/README.md +7 -0
- data/lib/overrider.rb +64 -94
- data/lib/overrider/version.rb +1 -1
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 01ce5703f96a82103f4b181db23f0bc11aa0ffb6106a20328ae1c0d0cf87dc69
|
4
|
+
data.tar.gz: 6de0b11afc0073bcb87b65d38c220677d0c1d41fffe25b46607c72b3c7f2f787
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: da98dc68e05c9aec19bf4a04cf1efe689945da6620614448e5d84b24e9ad1f1be7c506f784fee246659f2a4c81cac410c9c2a6c205a7702951d152def063e0dd
|
7
|
+
data.tar.gz: bdcde88a049176513dda1f897c8aac950546690b599702c12db14ff0dc8db1ce269dd943d3a277359a1f57729d949a164737d23c10c238f35b51587fb1943382
|
data/README.md
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
# Overrider
|
2
2
|
[](https://travis-ci.org/joker1007/overrider)
|
3
|
+
[](https://badge.fury.io/rb/overrider)
|
3
4
|
|
4
5
|
This gem adds `override` syntax that is similar to Java's one.
|
5
6
|
`override` syntax ensures that a modified method has super method.
|
@@ -7,8 +8,14 @@ This gem adds `override` syntax that is similar to Java's one.
|
|
7
8
|
Unless the method has super method, this gem raise `Overrider::NoSuperMethodError`.
|
8
9
|
|
9
10
|
This gem is pseudo static code analyzer by `TracePoint` and `Ripper`.
|
11
|
+
|
10
12
|
it detect abstract violation when class(module) is defined, not runtime.
|
11
13
|
|
14
|
+
### My similar gems
|
15
|
+
|
16
|
+
- [finalist](https://github.com/joker1007/finalist) (`final` implementation)
|
17
|
+
- [abstriker](https://github.com/joker1007/abstriker) (`abstract` implementation)
|
18
|
+
|
12
19
|
## Installation
|
13
20
|
|
14
21
|
Add this line to your application's Gemfile:
|
data/lib/overrider.rb
CHANGED
@@ -6,10 +6,11 @@ module Overrider
|
|
6
6
|
class NoSuperMethodError < StandardError
|
7
7
|
attr_reader :override_class, :unbound_method
|
8
8
|
|
9
|
-
def initialize(klass, method)
|
10
|
-
super("
|
9
|
+
def initialize(klass, method, backtrace = nil)
|
10
|
+
super("`#{method.owner}##{method.name}` requires super method.")
|
11
11
|
@override_class = klass
|
12
12
|
@unbound_method = method
|
13
|
+
set_backtrace(backtrace) if backtrace
|
13
14
|
end
|
14
15
|
end
|
15
16
|
|
@@ -62,123 +63,92 @@ module Overrider
|
|
62
63
|
|
63
64
|
private
|
64
65
|
|
65
|
-
def
|
66
|
-
|
67
|
-
|
68
|
-
@ensure_overrides ||= Set.new
|
69
|
-
@ensure_overrides.add(instance_method(symbol))
|
70
|
-
|
71
|
-
caller_info = caller_locations(1, 1)[0]
|
72
|
-
unless Overrider.sexps[caller_info.absolute_path]
|
73
|
-
Overrider.sexps[caller_info.absolute_path] ||= Ripper.sexp(File.read(caller_info.absolute_path))
|
74
|
-
end
|
66
|
+
def override_methods
|
67
|
+
@override_methods ||= Set.new
|
68
|
+
end
|
75
69
|
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
@__overrider_trace_point
|
80
|
-
|
81
|
-
|
70
|
+
using Module.new {
|
71
|
+
refine Module do
|
72
|
+
def trace_for_override(owner)
|
73
|
+
@__overrider_trace_point ||= TracePoint.trace(:end, :c_return, :return, :raise) do |t|
|
74
|
+
if t.event == :raise
|
75
|
+
@__overrider_trace_point.disable
|
76
|
+
@__overrider_trace_point = nil
|
77
|
+
next
|
78
|
+
end
|
82
79
|
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
80
|
+
klass = t.self
|
81
|
+
|
82
|
+
override_at_outer = false
|
83
|
+
if t.event == :return && klass == self && (t.method_id == :override || t.method_id == :override_singleton_method)
|
84
|
+
c = caller_locations(2, 1)[0]
|
85
|
+
traverser = SexpTraverser.new(Overrider.sexps[c.absolute_path])
|
86
|
+
traverser.traverse do |n, parent|
|
87
|
+
if n[0] == :@ident && (n[1] == "override" || n[1] == "override_singleton_method") && n[2][0] == c.lineno
|
88
|
+
if parent[0] == :command || parent[0] == :fcall
|
89
|
+
# override :foo
|
90
|
+
elsif parent[0] == :command_call || parent[0] == :call
|
91
|
+
if parent[1][0] == :var_ref && parent[1][1][0] == :@kw && parent[1][1][1] == "self"
|
92
|
+
# self.override :foo
|
93
|
+
else
|
94
|
+
# unknown case
|
95
|
+
warn "call `override` method by unknown way"
|
96
|
+
override_at_outer = true
|
97
|
+
end
|
98
|
+
else
|
99
|
+
override_at_outer = true
|
100
|
+
end
|
99
101
|
end
|
100
|
-
else
|
101
|
-
target_outer_override = true
|
102
102
|
end
|
103
103
|
end
|
104
|
-
end
|
105
|
-
end
|
106
104
|
|
107
|
-
|
108
|
-
|
105
|
+
target_class_end = klass == owner && t.event == :end
|
106
|
+
target_class_new_end = (klass == Class || klass == Module) && t.event == :c_return && t.method_id == :new && t.return_value == owner
|
109
107
|
|
110
|
-
|
111
|
-
|
112
|
-
|
108
|
+
if target_class_end || target_class_new_end || override_at_outer
|
109
|
+
override_methods.each do |meth|
|
110
|
+
unless meth.super_method
|
111
|
+
@__overrider_trace_point.disable
|
112
|
+
@__overrider_trace_point = nil
|
113
|
+
raise NoSuperMethodError.new(self, meth, caller(4))
|
114
|
+
end
|
115
|
+
end
|
113
116
|
@__overrider_trace_point.disable
|
114
117
|
@__overrider_trace_point = nil
|
115
|
-
raise NoSuperMethodError.new(self, meth)
|
116
118
|
end
|
117
119
|
end
|
118
|
-
@__overrider_trace_point.disable
|
119
|
-
@__overrider_trace_point = nil
|
120
120
|
end
|
121
121
|
end
|
122
|
+
}
|
123
|
+
|
124
|
+
def override(symbol)
|
125
|
+
return symbol if Overrider.disabled?
|
126
|
+
|
127
|
+
owner = self
|
128
|
+
override_methods.add(instance_method(symbol))
|
129
|
+
|
130
|
+
caller_info = caller_locations(1, 1)[0]
|
131
|
+
unless Overrider.sexps[caller_info.absolute_path]
|
132
|
+
Overrider.sexps[caller_info.absolute_path] ||= Ripper.sexp(File.read(caller_info.absolute_path))
|
133
|
+
end
|
134
|
+
|
135
|
+
trace_for_override(owner)
|
122
136
|
|
123
137
|
symbol
|
124
138
|
end
|
125
139
|
|
126
140
|
def override_singleton_method(symbol)
|
127
|
-
return if Overrider.disabled?
|
141
|
+
return symbol if Overrider.disabled?
|
128
142
|
|
129
|
-
|
130
|
-
|
143
|
+
owner = self
|
144
|
+
override_methods.add(singleton_class.instance_method(symbol))
|
131
145
|
|
132
146
|
caller_info = caller_locations(1, 1)[0]
|
133
147
|
unless Overrider.sexps[caller_info.absolute_path]
|
134
148
|
Overrider.sexps[caller_info.absolute_path] ||= Ripper.sexp(File.read(caller_info.absolute_path))
|
135
149
|
end
|
136
150
|
|
137
|
-
|
138
|
-
if t.event == :raise
|
139
|
-
@__overrider_singleton_trace_point.disable
|
140
|
-
@__overrider_singleton_trace_point = nil
|
141
|
-
next
|
142
|
-
end
|
143
|
-
|
144
|
-
klass = t.self
|
145
|
-
|
146
|
-
target_outer_override_singleton_method = false
|
147
|
-
if t.event == :return && klass == self && t.method_id == :override_singleton_method
|
148
|
-
c = caller_locations(2, 1)[0]
|
149
|
-
traverser = SexpTraverser.new(Overrider.sexps[c.absolute_path])
|
150
|
-
traverser.traverse do |n, parent|
|
151
|
-
if n[0] == :@ident && n[1] == "override_singleton_method" && n[2][0] == c.lineno
|
152
|
-
if parent[0] == :command || parent[0] == :fcall
|
153
|
-
# override_singleton_method :foo
|
154
|
-
elsif parent[0] == :command_call || parent[0] == :call
|
155
|
-
if parent[1][0] == :var_ref && parent[1][1][0] == :@kw && parent[1][1][1] == "self"
|
156
|
-
# self.override_singleton_method :foo
|
157
|
-
else
|
158
|
-
# unknown case
|
159
|
-
target_outer_override_singleton_method = true
|
160
|
-
end
|
161
|
-
else
|
162
|
-
target_outer_override_singleton_method = true
|
163
|
-
end
|
164
|
-
end
|
165
|
-
end
|
166
|
-
end
|
167
|
-
|
168
|
-
target_end_event = klass == self && t.event == :end
|
169
|
-
target_c_return_event = (klass == Class || klass == Module) && t.event == :c_return && t.method_id == :new
|
170
|
-
if target_end_event || target_c_return_event || target_outer_override_singleton_method
|
171
|
-
@ensure_overrides.each do |meth|
|
172
|
-
unless meth.super_method
|
173
|
-
@__overrider_singleton_trace_point.disable
|
174
|
-
@__overrider_singleton_trace_point = nil
|
175
|
-
raise NoSuperMethodError.new(self, meth)
|
176
|
-
end
|
177
|
-
end
|
178
|
-
@__overrider_singleton_trace_point.disable
|
179
|
-
@__overrider_singleton_trace_point = nil
|
180
|
-
end
|
181
|
-
end
|
151
|
+
trace_for_override(owner)
|
182
152
|
|
183
153
|
symbol
|
184
154
|
end
|
data/lib/overrider/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: overrider
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- joker1007
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-
|
11
|
+
date: 2018-07-10 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -91,7 +91,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
91
91
|
version: '0'
|
92
92
|
requirements: []
|
93
93
|
rubyforge_project:
|
94
|
-
rubygems_version: 2.7.
|
94
|
+
rubygems_version: 2.7.7
|
95
95
|
signing_key:
|
96
96
|
specification_version: 4
|
97
97
|
summary: Add override syntax that ensures that target method has super method.
|