Class: Typeguard::Validation::Wrapper
- Inherits:
-
Object
- Object
- Typeguard::Validation::Wrapper
- Includes:
- TypeModel::Definitions
- Defined in:
- lib/typeguard/wrapper.rb
Instance Method Summary collapse
- #check_arity(mod, sig, original_method) ⇒ Object
- #check_visibility(target, mod, sig, method_name) ⇒ Object
-
#initialize(definitions, config) ⇒ Wrapper
constructor
A new instance of Wrapper.
- #unsafe_method?(sig) ⇒ Boolean
- #wrap! ⇒ Object
- #wrap_definition(definition) ⇒ Object
- #wrap_method(mod, sig) ⇒ Object
Constructor Details
#initialize(definitions, config) ⇒ Wrapper
Returns a new instance of Wrapper.
8 9 10 11 |
# File 'lib/typeguard/wrapper.rb', line 8 def initialize(definitions, config) @definitions = definitions @config = config end |
Instance Method Details
#check_arity(mod, sig, original_method) ⇒ Object
55 56 57 58 59 60 61 62 |
# File 'lib/typeguard/wrapper.rb', line 55 def check_arity(mod, sig, original_method) expected_arity = sig.parameters.size actual_arity = original_method.parameters.count return if expected_arity == actual_arity log = Metrics.report(mod, sig, :unexpected_arity, expected_arity, actual_arity) raise Metrics.format_log(log) if @config.raise_on_unexpected_arity end |
#check_visibility(target, mod, sig, method_name) ⇒ Object
64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 |
# File 'lib/typeguard/wrapper.rb', line 64 def check_visibility(target, mod, sig, method_name) expected_visibility = sig.visibility actual_visibility = if target.public_instance_methods(false).include?(method_name) :public elsif target.protected_instance_methods(false).include?(method_name) :protected elsif target.private_instance_methods(false).include?(method_name) :private else :public end error = false unless expected_visibility.nil? || expected_visibility == actual_visibility if expected_visibility == :public && actual_visibility == :private if sig.name == :initialize # Initialize is private by default, ignore elsif mod == Object # Methods on Object (root) are private by default, ignore else error = true end else error = true end end if error log = Metrics.report(mod, sig, :unexpected_visibility, expected_visibility, actual_visibility) raise Metrics.format_log(log) if @config.raise_on_unexpected_visibility end actual_visibility end |
#unsafe_method?(sig) ⇒ Boolean
48 49 50 51 52 53 |
# File 'lib/typeguard/wrapper.rb', line 48 def unsafe_method?(sig) # It is unsafe to redefine these methods because # the return type is not always the same: assignment # vs method call sig.name == :initialize || sig.name.to_s =~ /=$/ end |
#wrap! ⇒ Object
13 14 15 |
# File 'lib/typeguard/wrapper.rb', line 13 def wrap! @definitions.each { |definition| wrap_definition(definition) } end |
#wrap_definition(definition) ⇒ Object
17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
# File 'lib/typeguard/wrapper.rb', line 17 def wrap_definition(definition) case definition when ModuleDefinition, ClassDefinition mod = Object.const_get(definition.name) definition.children.each do |child| if child.is_a?(MethodDefinition) wrap_method(mod, child) else # Wrap nested modules wrap_definition(child) end end when MethodDefinition # Method defined in root, as a private instance method of Object wrap_method(Object, definition) else raise "Unexpected definition for '#{definition}'" end end |
#wrap_method(mod, sig) ⇒ Object
36 37 38 39 40 41 42 43 44 45 46 |
# File 'lib/typeguard/wrapper.rb', line 36 def wrap_method(mod, sig) return if unsafe_method?(sig) target = sig.scope == :class ? mod.singleton_class : mod method_name = sig.name original_method = target.instance_method(method_name) check_arity(mod, sig, original_method) actual_visibility = check_visibility(target, mod, sig, method_name) Validator.exhaustive_path(mod, original_method, sig) target.send(actual_visibility, method_name) end |