overrider 0.1.4 → 0.1.5

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d52cf24ae854860de785dbab4e6d9c2750290482f4691c902304fb9faed1a089
4
- data.tar.gz: c1fb2a74aae5d70ac65790546808ae113e82ff3912307007835d8c582fa46108
3
+ metadata.gz: 01ce5703f96a82103f4b181db23f0bc11aa0ffb6106a20328ae1c0d0cf87dc69
4
+ data.tar.gz: 6de0b11afc0073bcb87b65d38c220677d0c1d41fffe25b46607c72b3c7f2f787
5
5
  SHA512:
6
- metadata.gz: 196bb7a40efa56f4a8e0de5490b175e302fdfd39edc6f48d388367580eba66434abc65cc85d8b4a02d93bacfc6b950640e97019bf8a74c6049da2bcdb250150f
7
- data.tar.gz: 9b441aa900a934993379f30f21caa95241221e96cdbf0b6bb1fe8b2dc4889db831bed33076ccc7591487fa41ffe1a7e4a86282382b3f34a174f4a425b58d1a6a
6
+ metadata.gz: da98dc68e05c9aec19bf4a04cf1efe689945da6620614448e5d84b24e9ad1f1be7c506f784fee246659f2a4c81cac410c9c2a6c205a7702951d152def063e0dd
7
+ data.tar.gz: bdcde88a049176513dda1f897c8aac950546690b599702c12db14ff0dc8db1ce269dd943d3a277359a1f57729d949a164737d23c10c238f35b51587fb1943382
data/README.md CHANGED
@@ -1,5 +1,6 @@
1
1
  # Overrider
2
2
  [![Build Status](https://travis-ci.org/joker1007/overrider.svg?branch=master)](https://travis-ci.org/joker1007/overrider)
3
+ [![Gem Version](https://badge.fury.io/rb/overrider.svg)](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:
@@ -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("#{method} requires super method.")
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 override(symbol)
66
- return if Overrider.disabled?
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
- @__overrider_trace_point ||= TracePoint.trace(:end, :c_return, :return, :return, :raise) do |t|
77
- if t.event == :raise
78
- @__overrider_trace_point.disable
79
- @__overrider_trace_point = nil
80
- next
81
- end
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
- klass = t.self
84
-
85
- target_outer_override = false
86
- if t.event == :return && klass == self && t.method_id == :override
87
- c = caller_locations(2, 1)[0]
88
- traverser = SexpTraverser.new(Overrider.sexps[c.absolute_path])
89
- traverser.traverse do |n, parent|
90
- if n[0] == :@ident && n[1] == "override" && n[2][0] == c.lineno
91
- if parent[0] == :command || parent[0] == :fcall
92
- # override :foo
93
- elsif parent[0] == :command_call || parent[0] == :call
94
- if parent[1][0] == :var_ref && parent[1][1][0] == :@kw && parent[1][1][1] == "self"
95
- # self.override :foo
96
- else
97
- # unknown case
98
- target_outer_override = true
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
- target_end_event = klass == self && t.event == :end
108
- target_c_return_event = (klass == Class || klass == Module) && t.event == :c_return && t.method_id == :new
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
- if target_end_event || target_c_return_event || target_outer_override
111
- @ensure_overrides.each do |meth|
112
- unless meth.super_method
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
- @ensure_overrides ||= Set.new
130
- @ensure_overrides.add(singleton_class.instance_method(symbol))
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
- @__overrider_singleton_trace_point ||= TracePoint.trace(:end, :c_return, :return, :raise) do |t|
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
@@ -1,3 +1,3 @@
1
1
  module Overrider
2
- VERSION = "0.1.4"
2
+ VERSION = "0.1.5"
3
3
  end
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
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-01-26 00:00:00.000000000 Z
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.4
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.