rtype-legacy 0.0.2

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.
@@ -0,0 +1,24 @@
1
+ module Rtype
2
+ module Behavior
3
+ class Not < Base
4
+ def initialize(*types)
5
+ @types = types
6
+ end
7
+
8
+ def valid?(value)
9
+ @types.all? do |e|
10
+ !Rtype::valid?(e, value)
11
+ end
12
+ end
13
+
14
+ def error_message(value)
15
+ arr = @types.map { |e| "NOT " + Rtype::type_error_message(e, value) }
16
+ arr.join "\nAND "
17
+ end
18
+ end
19
+ end
20
+
21
+ def not(*args)
22
+ Behavior::Not[*args]
23
+ end
24
+ end
@@ -0,0 +1,25 @@
1
+ module Rtype
2
+ module Behavior
3
+ class TypedArray < Base
4
+ def initialize(type)
5
+ @type = type
6
+ Rtype.assert_valid_argument_type_sig_element(@type)
7
+ end
8
+
9
+ def valid?(value)
10
+ if value.is_a?(Array)
11
+ any = value.any? do |e|
12
+ !Rtype::valid?(@type, e)
13
+ end
14
+ !any
15
+ else
16
+ false
17
+ end
18
+ end
19
+
20
+ def error_message(value)
21
+ "Expected #{value.inspect} to be an array with type #{@type.inspect}"
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,25 @@
1
+ module Rtype
2
+ module Behavior
3
+ class Xor < Base
4
+ def initialize(*types)
5
+ @types = types
6
+ end
7
+
8
+ def valid?(value)
9
+ result = @types.map do |e|
10
+ Rtype::valid? e, value
11
+ end
12
+ result.count(true) == 1
13
+ end
14
+
15
+ def error_message(value)
16
+ arr = @types.map { |e| Rtype::type_error_message(e, value) }
17
+ arr.join "\nXOR "
18
+ end
19
+ end
20
+ end
21
+
22
+ def xor(*args)
23
+ Behavior::Xor[*args]
24
+ end
25
+ end
@@ -0,0 +1,12 @@
1
+ module Rtype
2
+ module Behavior
3
+ end
4
+ end
5
+
6
+ require_relative 'behavior/base'
7
+ require_relative 'behavior/and'
8
+ require_relative 'behavior/xor'
9
+ require_relative 'behavior/not'
10
+ require_relative 'behavior/nilable'
11
+ require_relative 'behavior/typed_array'
12
+ require_relative 'behavior/core_ext'
@@ -0,0 +1,137 @@
1
+ # true or false
2
+ module Boolean; end
3
+ class TrueClass; include Boolean; end
4
+ class FalseClass; include Boolean; end
5
+
6
+ Any = BasicObject
7
+
8
+ class Object
9
+ include ::Rtype::MethodAnnotator
10
+ end
11
+
12
+ module Kernel
13
+ private
14
+ def _rtype_component
15
+ unless @_rtype_component
16
+ @_rtype_component = ::Rtype::RtypeComponent.new
17
+ end
18
+ @_rtype_component
19
+ end
20
+
21
+ # Makes the method typed
22
+ #
23
+ # With 'annotation mode', this method works for both instance method and singleton method (class method).
24
+ # Without it (specifying method name), this method only works for instance method.
25
+ #
26
+ # @param [#to_sym, nil] method_name The name of method. If nil, annotation mode works
27
+ # @param [Hash] type_sig_info A type signature. e.g. [Integer] => Any
28
+ # @return [void]
29
+ #
30
+ # @note Annotation mode doesn't work in the outside of module
31
+ # @raise [RuntimeError] If called outside of module
32
+ # @raise [TypeSignatureError] If type_sig_info is invalid
33
+ def rtype(method_name=nil, type_sig_info)
34
+ if is_a?(Module)
35
+ if method_name.nil?
36
+ ::Rtype::assert_valid_type_sig(type_sig_info)
37
+ _rtype_component.annotation_mode = true
38
+ _rtype_component.annotation_type_sig = type_sig_info
39
+ nil
40
+ else
41
+ ::Rtype::define_typed_method(self, method_name, type_sig_info, false)
42
+ end
43
+ else
44
+ raise "rtype doesn't work in the outside of module"
45
+ end
46
+ end
47
+
48
+ # Makes the singleton method (class method) typed
49
+ #
50
+ # @param [#to_sym] method_name
51
+ # @param [Hash] type_sig_info A type signature. e.g. [Integer] => Any
52
+ # @return [void]
53
+ #
54
+ # @raise [ArgumentError] If method_name is nil
55
+ # @raise [TypeSignatureError] If type_sig_info is invalid
56
+ def rtype_self(method_name, type_sig_info)
57
+ ::Rtype.define_typed_method(self, method_name, type_sig_info, true)
58
+ end
59
+
60
+ # Makes the accessor methods (getter and setter) typed
61
+ #
62
+ # @param [Array<#to_sym>] accessor_names
63
+ # @param type_behavior A type behavior
64
+ # @return [void]
65
+ #
66
+ # @raise [ArgumentError] If accessor_names contains nil
67
+ # @raise [TypeSignatureError] If type_behavior is invalid
68
+ # @raise [RuntimeError] If called outside of module
69
+ # @see #rtype
70
+ def rtype_accessor(*accessor_names, type_behavior)
71
+ accessor_names.each do |accessor_name|
72
+ raise ArgumentError, "accessor_names contains nil" if accessor_name.nil?
73
+
74
+ accessor_name = accessor_name.to_sym
75
+ if !respond_to?(accessor_name) || !respond_to?(:"#{accessor_name}=")
76
+ attr_accessor accessor_name
77
+ end
78
+
79
+ if is_a?(Module)
80
+ ::Rtype::define_typed_accessor(self, accessor_name, type_behavior, false)
81
+ else
82
+ raise "rtype_accessor doesn't work in the outside of module"
83
+ end
84
+ end
85
+ nil
86
+ end
87
+
88
+ # Makes the accessor methods (getter and setter) typed
89
+ #
90
+ # @param [Array<#to_sym>] accessor_names
91
+ # @param type_behavior A type behavior
92
+ # @return [void]
93
+ #
94
+ # @raise [ArgumentError] If accessor_names contains nil
95
+ # @raise [TypeSignatureError] If type_behavior is invalid
96
+ # @see #rtype_self
97
+ def rtype_accessor_self(*accessor_names, type_behavior)
98
+ accessor_names.each do |accessor_name|
99
+ raise ArgumentError, "accessor_names contains nil" if accessor_name.nil?
100
+
101
+ accessor_name = accessor_name.to_sym
102
+ if !respond_to?(accessor_name) || !respond_to?(:"#{accessor_name}=")
103
+ singleton_class.send(:attr_accessor, accessor_name)
104
+ end
105
+ ::Rtype::define_typed_accessor(self, accessor_name, type_behavior, true)
106
+ end
107
+ nil
108
+ end
109
+ end
110
+
111
+ class Method
112
+ # @return [Boolean] Whether the method is typed with rtype
113
+ def typed?
114
+ !!::Rtype.type_signatures[owner][name]
115
+ end
116
+
117
+ # @return [TypeSignature]
118
+ def type_signature
119
+ ::Rtype.type_signatures[owner][name]
120
+ end
121
+
122
+ # @return [Hash]
123
+ # @see TypeSignature#info
124
+ def type_info
125
+ ::Rtype.type_signatures[owner][name].info
126
+ end
127
+
128
+ # @return [Array, Hash]
129
+ def argument_type
130
+ ::Rtype.type_signatures[owner][name].argument_type
131
+ end
132
+
133
+ # @return A type behavior
134
+ def return_type
135
+ ::Rtype.type_signatures[owner][name].return_type
136
+ end
137
+ end
@@ -0,0 +1,9 @@
1
+ module Rtype
2
+ module Legacy
3
+ VERSION = "0.0.2".freeze
4
+ # rtype java extension version. nil If the extension is not used
5
+ JAVA_EXT_VERSION = nil unless const_defined?(:JAVA_EXT_VERSION, false)
6
+ # rtype c extension version. nil If the extension is not used
7
+ NATIVE_EXT_VERSION = nil unless const_defined?(:NATIVE_EXT_VERSION, false)
8
+ end
9
+ end
@@ -0,0 +1,417 @@
1
+ if Object.const_defined?(:RUBY_ENGINE)
2
+ case RUBY_ENGINE
3
+ when "jruby"
4
+ begin
5
+ require 'java'
6
+ require 'rtype/legacy/rtype_legacy_java'
7
+ # puts "Rtype Legacy with Java extension"
8
+ rescue LoadError
9
+ # puts "Rtype Legacy without native extension"
10
+ end
11
+ when "ruby"
12
+ begin
13
+ require 'rtype/legacy/rtype_legacy_native'
14
+ # puts "Rtype Legacy with C native extension"
15
+ rescue LoadError
16
+ # puts "Rtype Legacy without native extension"
17
+ end
18
+ end
19
+ end
20
+
21
+ require_relative 'rtype_component'
22
+ require_relative 'method_annotator'
23
+ require_relative 'core_ext'
24
+ require_relative 'legacy/version'
25
+ require_relative 'type_signature_error'
26
+ require_relative 'argument_type_error'
27
+ require_relative 'return_type_error'
28
+ require_relative 'type_signature'
29
+ require_relative 'behavior'
30
+
31
+ module Rtype
32
+ extend self
33
+
34
+ # This is just 'information'
35
+ # Any change of this doesn't affect type checking
36
+ @@type_signatures = Hash.new
37
+
38
+ # Makes the method typed
39
+ # @param owner Owner of the method
40
+ # @param [#to_sym] method_name
41
+ # @param [Hash] type_sig_info A type signature. e.g. `[Integer, Float] => Float`
42
+ # @param [Boolean] singleton Whether the method is singleton method
43
+ # @return [void]
44
+ #
45
+ # @raise [ArgumentError] If method_name is nil, keyword argument signature is not empty, or singleton is not a boolean
46
+ # @raise [TypeSignatureError] If type_sig_info is invalid
47
+ def define_typed_method(owner, method_name, type_sig_info, singleton)
48
+ method_name = method_name.to_sym
49
+ raise ArgumentError, "method_name is nil" if method_name.nil?
50
+ raise ArgumentError, "singleton must be a boolean" unless singleton.is_a?(Boolean)
51
+ assert_valid_type_sig(type_sig_info)
52
+
53
+ el = type_sig_info.first
54
+ arg_sig = el[0]
55
+ return_sig = el[1]
56
+
57
+ if arg_sig.is_a?(Array)
58
+ expected_args = arg_sig.dup
59
+ if expected_args.last.is_a?(Hash)
60
+ kwargs = expected_args.pop
61
+ # empty kwargs signature
62
+ else
63
+ # empty kwargs signature
64
+ end
65
+ elsif arg_sig.is_a?(Hash)
66
+ # empty kwargs signature
67
+ expected_args = []
68
+ end
69
+
70
+ sig = TypeSignature.new
71
+ sig.argument_type = arg_sig
72
+ sig.return_type = return_sig
73
+ unless @@type_signatures.key?(owner)
74
+ @@type_signatures[owner] = {}
75
+ end
76
+ @@type_signatures[owner][method_name] = sig
77
+
78
+ redefine_method_to_typed(owner, method_name, expected_args, return_sig, singleton)
79
+ end
80
+
81
+ # Calls `attr_accessor` if the accessor method(getter/setter) is not defined.
82
+ # and makes it typed.
83
+ #
84
+ # this method uses `define_typed_method` for getter and setter.
85
+ #
86
+ # @param owner Owner of the accessor
87
+ # @param [#to_sym] accessor_name
88
+ # @param type_behavior A type behavior. e.g. Integer
89
+ # @param [Boolean] singleton Whether the method is singleton method
90
+ # @return [void]
91
+ #
92
+ # @raise [ArgumentError] If accessor_name is nil or singleton is not a boolean
93
+ # @raise [TypeSignatureError]
94
+ def define_typed_accessor(owner, accessor_name, type_behavior, singleton)
95
+ raise ArgumentError, "accessor_name is nil" if accessor_name.nil?
96
+ getter = accessor_name.to_sym
97
+ setter = :"#{accessor_name}="
98
+ valid?(type_behavior, nil)
99
+ define_typed_method owner, getter, {[] => type_behavior}, singleton
100
+ define_typed_method owner, setter, {[type_behavior] => Any}, singleton
101
+ end
102
+
103
+ # This is just 'information'
104
+ # Any change of this doesn't affect type checking
105
+ #
106
+ # @return [Hash]
107
+ # @note type_signatures[owner][method_name]
108
+ def type_signatures
109
+ @@type_signatures
110
+ end
111
+
112
+ # @param [Integer] idx
113
+ # @param expected A type behavior
114
+ # @param value
115
+ # @return [String] A error message
116
+ #
117
+ # @raise [ArgumentError] If expected is invalid
118
+ def arg_type_error_message(idx, expected, value)
119
+ "#{arg_message(idx)}\n" + type_error_message(expected, value)
120
+ end
121
+
122
+ # @return [String]
123
+ def arg_message(idx)
124
+ "for #{ordinalize_number(idx+1)} argument:"
125
+ end
126
+
127
+ # Returns a error message for the pair of type behavior and value
128
+ #
129
+ # @param expected A type behavior
130
+ # @param value
131
+ # @return [String] error message
132
+ #
133
+ # @note This method doesn't check the value is valid
134
+ # @raise [TypeSignatureError] If expected is invalid
135
+ def type_error_message(expected, value)
136
+ case expected
137
+ when Rtype::Behavior::Base
138
+ expected.error_message(value)
139
+ when Module
140
+ "Expected #{value.inspect} to be a #{expected}"
141
+ when Symbol
142
+ "Expected #{value.inspect} to respond to :#{expected}"
143
+ when Regexp
144
+ "Expected stringified #{value.inspect} to match regexp #{expected.inspect}"
145
+ when Range
146
+ "Expected #{value.inspect} to be included in range #{expected.inspect}"
147
+ when Array
148
+ arr = expected.map { |e| type_error_message(e, value) }
149
+ arr.join("\nOR ")
150
+ when Hash
151
+ if value.is_a?(Hash)
152
+ arr = []
153
+ expected.each do |k, v|
154
+ if v.is_a?(Array) || v.is_a?(Hash)
155
+ arr << "- #{k} : {\n" + type_error_message(v, value[k]) + "\n}"
156
+ else
157
+ arr << "- #{k} : " + type_error_message(v, value[k])
158
+ end
159
+ end
160
+ "Expected #{value.inspect} to be a hash with #{expected.length} elements:\n" + arr.join("\n")
161
+ else
162
+ "Expected #{value.inspect} to be a hash"
163
+ end
164
+ when Proc
165
+ "Expected #{value.inspect} to return a truthy value for proc #{expected}"
166
+ when true
167
+ "Expected #{value.inspect} to be a truthy value"
168
+ when false
169
+ "Expected #{value.inspect} to be a falsy value"
170
+ when nil # for return
171
+ "Expected #{value.inspect} to be nil"
172
+ else
173
+ raise TypeSignatureError, "Invalid type behavior #{expected}"
174
+ end
175
+ end
176
+
177
+ # Checks the type signature is valid
178
+ #
179
+ # e.g.
180
+ # `[Integer] => Any` is valid.
181
+ # `[Integer]` or `Any` are invalid
182
+ #
183
+ # @param sig A type signature
184
+ # @raise [TypeSignatureError] If sig is invalid
185
+ def assert_valid_type_sig(sig)
186
+ unless sig.is_a?(Hash)
187
+ raise TypeSignatureError, "Invalid type signature: type signature is not hash"
188
+ end
189
+ if sig.empty?
190
+ raise TypeSignatureError, "Invalid type signature: type signature is empty hash"
191
+ end
192
+ assert_valid_arguments_type_sig(sig.first[0])
193
+ assert_valid_return_type_sig(sig.first[1])
194
+ end
195
+
196
+ # Checks the arguments type signature is valid
197
+ #
198
+ # e.g.
199
+ # `[Integer]`, `{key: "value"}` are valid (the second is keyword argument signature and ignored in rtype-legacy).
200
+ # `Integer` is invalid.
201
+ #
202
+ # @param sig A arguments type signature
203
+ # @raise [TypeSignatureError] If sig is invalid
204
+ def assert_valid_arguments_type_sig(sig)
205
+ if sig.is_a?(Array)
206
+ sig = sig.dup
207
+ if sig.last.is_a?(Hash)
208
+ kwargs = sig.pop
209
+ else
210
+ kwargs = {}
211
+ end
212
+ sig.each { |e| assert_valid_argument_type_sig_element(e) }
213
+ unless kwargs.empty?
214
+ raise TypeSignatureError, "Invalid type signature: keyword arguments must be empty"
215
+ end
216
+ elsif sig.is_a?(Hash)
217
+ unless kwargs.empty?
218
+ raise TypeSignatureError, "Invalid type signature: keyword arguments must be empty"
219
+ end
220
+ else
221
+ raise TypeSignatureError, "Invalid type signature: arguments type signature is neither array nor hash"
222
+ end
223
+ end
224
+
225
+ # Checks the type behavior is valid
226
+ #
227
+ # @param sig A type behavior
228
+ # @raise [TypeSignatureError] If sig is invalid
229
+ def assert_valid_argument_type_sig_element(sig)
230
+ case sig
231
+ when Rtype::Behavior::Base
232
+ when Module
233
+ when Symbol
234
+ when Regexp
235
+ when Range
236
+ when Array
237
+ sig.each do |e|
238
+ assert_valid_argument_type_sig_element(e)
239
+ end
240
+ when Hash
241
+ sig.each_value do |e|
242
+ assert_valid_argument_type_sig_element(e)
243
+ end
244
+ when Proc
245
+ when true
246
+ when false
247
+ when nil
248
+ else
249
+ raise TypeSignatureError, "Invalid type signature: Unknown type behavior #{sig}"
250
+ end
251
+ end
252
+
253
+ # @see #assert_valid_argument_type_sig_element
254
+ def assert_valid_return_type_sig(sig)
255
+ assert_valid_argument_type_sig_element(sig)
256
+ end
257
+
258
+ unless respond_to?(:valid?)
259
+ # Checks the value is valid for the type behavior
260
+ #
261
+ # @param expected A type behavior
262
+ # @param value
263
+ # @return [Boolean]
264
+ #
265
+ # @raise [TypeSignatureError] If expected is invalid
266
+ def valid?(expected, value)
267
+ case expected
268
+ when Module
269
+ value.is_a? expected
270
+ when Symbol
271
+ value.respond_to? expected
272
+ when Regexp
273
+ !!(expected =~ value.to_s)
274
+ when Range
275
+ expected.include?(value)
276
+ when Hash
277
+ return false unless value.is_a?(Hash)
278
+ return false unless expected.keys == value.keys
279
+ expected.all? { |k, v| valid?(v, value[k]) }
280
+ when Array
281
+ expected.any? { |e| valid?(e, value) }
282
+ when Proc
283
+ !!expected.call(value)
284
+ when true
285
+ !!value
286
+ when false
287
+ !value
288
+ when Rtype::Behavior::Base
289
+ expected.valid? value
290
+ when nil
291
+ value.nil?
292
+ else
293
+ raise TypeSignatureError, "Invalid type signature: Unknown type behavior #{expected}"
294
+ end
295
+ end
296
+ end
297
+
298
+ unless respond_to?(:assert_arguments_type)
299
+ # Validates arguments
300
+ #
301
+ # @param [Array] expected_args A type signature for non-keyword arguments
302
+ # @param [Array] args
303
+ # @return [void]
304
+ #
305
+ # @raise [TypeSignatureError] If expected_args is invalid
306
+ # @raise [ArgumentTypeError] If args is invalid
307
+ def assert_arguments_type(expected_args, args)
308
+ e_len = expected_args.length
309
+ # `length.times` is faster than `each_with_index`
310
+ args.length.times do |i|
311
+ break if i >= e_len
312
+ expected = expected_args[i]
313
+ value = args[i]
314
+ unless valid?(expected, value)
315
+ raise ArgumentTypeError, "#{arg_message(i)}\n" + type_error_message(expected, value)
316
+ end
317
+ end
318
+ nil
319
+ end
320
+ end
321
+
322
+ # Validates result
323
+ #
324
+ # @param expected A type behavior
325
+ # @param result
326
+ # @return [void]
327
+ #
328
+ # @raise [TypeSignatureError] If expected is invalid
329
+ # @raise [ReturnTypeError] If result is invalid
330
+ unless respond_to?(:assert_return_type)
331
+ def assert_return_type(expected, result)
332
+ unless valid?(expected, result)
333
+ raise ReturnTypeError, "for return:\n" + type_error_message(expected, result)
334
+ end
335
+ nil
336
+ end
337
+ end
338
+
339
+ private
340
+ # @param owner
341
+ # @param [Symbol] method_name
342
+ # @param [Array] expected_args
343
+ # @param return_sig
344
+ # @param [Boolean] singleton
345
+ # @return [void]
346
+ def redefine_method_to_typed(owner, method_name, expected_args, return_sig, singleton)
347
+ compo = owner.send(:_rtype_component)
348
+
349
+ methods = owner.instance_methods if !singleton
350
+ methods = owner.methods if singleton
351
+
352
+ if methods.include?(method_name)
353
+ =begin
354
+ unless compo.has_old?(method_name, singleton)
355
+ old_method = owner.instance_method(method_name) if !singleton
356
+ old_method = owner.method(method_name) if singleton
357
+ compo.set_old(method_name, singleton, old_method)
358
+ end
359
+ =end
360
+ if compo.has_old?(method_name, singleton)
361
+ old_method = compo.get_old(method_name, singleton)
362
+ else
363
+ old_method = owner.instance_method(method_name) if !singleton
364
+ old_method = owner.method(method_name) if singleton
365
+ compo.set_old(method_name, singleton, old_method)
366
+ end
367
+ else # Undefined method
368
+ compo.add_undef(method_name, expected_args, return_sig, singleton)
369
+ return
370
+ end
371
+
372
+ owner = owner.singleton_class if singleton
373
+ priv = owner.private_method_defined?(method_name)
374
+ prot = owner.protected_method_defined?(method_name)
375
+
376
+ if !singleton
377
+ # `send` is faster than `method(...).call`
378
+ owner.send :define_method, method_name do |*args, &block|
379
+ ::Rtype::assert_arguments_type(expected_args, args)
380
+ # result = compo.get_old(method_name, singleton).bind(self).call(*args, &block)
381
+ result = old_method.bind(self).call(*args, &block)
382
+ ::Rtype::assert_return_type(return_sig, result)
383
+ result
384
+ end
385
+ else
386
+ owner.send :define_method, method_name do |*args, &block|
387
+ ::Rtype::assert_arguments_type(expected_args, args)
388
+ # result = compo.get_old(method_name, singleton).call(*args, &block)
389
+ result = old_method.call(*args, &block)
390
+ ::Rtype::assert_return_type(return_sig, result)
391
+ result
392
+ end
393
+ end
394
+
395
+ if priv
396
+ owner.send(:private, method_name)
397
+ elsif prot
398
+ owner.send(:protected, method_name)
399
+ end
400
+ nil
401
+ end
402
+
403
+ # @param [Integer] num
404
+ # @return [String]
405
+ def ordinalize_number(num)
406
+ if (11..13).include?(num % 100)
407
+ "#{num}th"
408
+ else
409
+ case num % 10
410
+ when 1; "#{num}st"
411
+ when 2; "#{num}nd"
412
+ when 3; "#{num}rd"
413
+ else "#{num}th"
414
+ end
415
+ end
416
+ end
417
+ end
@@ -0,0 +1,55 @@
1
+ module Rtype
2
+ module MethodAnnotator
3
+ def self.included(base)
4
+ base.extend ClassMethods
5
+ end
6
+
7
+ module ClassMethods
8
+ def method_added(name)
9
+ if @_rtype_component
10
+ compo = @_rtype_component
11
+
12
+ if compo.annotation_mode && !compo.ignoring
13
+ if compo.has_undef?(name, false)
14
+ compo.remove_undef(name, false)
15
+ end
16
+
17
+ compo.ignoring = true
18
+ ::Rtype::define_typed_method(self, name, compo.annotation_type_sig, false)
19
+ compo.annotation_mode = false
20
+ compo.annotation_type_sig = nil
21
+ compo.ignoring = false
22
+
23
+ elsif compo.has_undef?(name, false)
24
+ info = compo.get_undef(name, false)
25
+ compo.remove_undef(name, false)
26
+ ::Rtype.send(:redefine_method_to_typed, self, name, info[:expected], info[:result], false)
27
+ end
28
+ end
29
+ end
30
+
31
+ def singleton_method_added(name)
32
+ if @_rtype_component
33
+ compo = @_rtype_component
34
+
35
+ if compo.annotation_mode && !compo.ignoring
36
+ if compo.has_undef?(name, true)
37
+ compo.remove_undef(name, true)
38
+ end
39
+
40
+ compo.ignoring = true
41
+ ::Rtype::define_typed_method(self, name, compo.annotation_type_sig, true)
42
+ compo.annotation_mode = false
43
+ compo.annotation_type_sig = nil
44
+ compo.ignoring = false
45
+
46
+ elsif compo.has_undef?(name, true)
47
+ info = compo.get_undef(name, true)
48
+ compo.remove_undef(name, true)
49
+ ::Rtype.send(:redefine_method_to_typed, self, name, info[:expected], info[:result], true)
50
+ end
51
+ end
52
+ end
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,4 @@
1
+ module Rtype
2
+ class ReturnTypeError < StandardError
3
+ end
4
+ end