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 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.