Class: RubyLint::Analysis::ArgumentAmount
- Defined in:
- lib/ruby-lint/analysis/argument_amount.rb
Overview
The ArgumentAmount class is an analysis class that verifies the amount of arguments given with each method call and adds errors whenever an invalid amount was given.
Constant Summary
- MAP_METHODS =
Hash that contains method names that should be used for analysis instead of the ones specified in the keys.
{ 'new' => [:instance_method, 'initialize'] }
Constants inherited from Base
Instance Attribute Summary
Attributes inherited from Base
Attributes inherited from Iterator
#arity_cache, #arity_cache Hash containing the amount of arguments for
Instance Method Summary collapse
-
#argument_amount(nodes) ⇒ Fixnum
private
-
#argument_range(method) ⇒ Array
private
Returns the minimum and maximum amount of arguments for a method call.
-
#argument_text(method, given) ⇒ String
private
Returns a String that indicates the amount of required arguments.
-
#correct_argument_amount(min, max, given) ⇒ TrueClass|FalseClass
private
-
#determine_method(scope, name) ⇒ RubyLint::Definition::RubyMethod
private
-
#on_send(node) ⇒ Object
-
#scope_for_receiver(receiver) ⇒ RubyLint::Definition::RubyObject
private
Methods inherited from Base
#add_message, #after_initialize, analyze?, #current_scope, #error, #info, #previous_scope, register, #set_current_scope, #set_previous_scope, #warning
Methods included from MethodEvaluation
Methods inherited from Iterator
#execute_callback, #initialize, #iterate, #skip_child_nodes!
Constructor Details
This class inherits a constructor from RubyLint::Iterator
Instance Method Details
#argument_amount(nodes) ⇒ Fixnum (private)
129 130 131 |
# File 'lib/ruby-lint/analysis/argument_amount.rb', line 129 def argument_amount(nodes) return nodes.reject { |n| n.type == :block_pass }.length end |
#argument_range(method) ⇒ Array (private)
Returns the minimum and maximum amount of arguments for a method call.
107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 |
# File 'lib/ruby-lint/analysis/argument_amount.rb', line 107 def argument_range(method) min = method.amount(:arg) if method.amount(:restarg) > 0 max = Float::INFINITY else max = min + method.amount(:optarg) + method.amount(:restarg) end # If the method follows the writer naming pattern with a '=' ending, # the parser generates send nodes with one less argument than needed in # the case of parallel assignment. Here reducing minimum prevents false # positive warnings to be generated. min -= 1 if method.name =~ /=$/ return min, max end |
#argument_text(method, given) ⇒ String (private)
Returns a String that indicates the amount of required arguments.
94 95 96 97 98 99 |
# File 'lib/ruby-lint/analysis/argument_amount.rb', line 94 def argument_text(method, given) min = method.amount(:arg) opt = method.amount(:optarg) return opt > 0 ? "#{min}..#{min + opt}" : min.to_s end |
#correct_argument_amount(min, max, given) ⇒ TrueClass|FalseClass (private)
83 84 85 |
# File 'lib/ruby-lint/analysis/argument_amount.rb', line 83 def correct_argument_amount(min, max, given) return given >= min && given <= max end |
#determine_method(scope, name) ⇒ RubyLint::Definition::RubyMethod (private)
67 68 69 70 71 72 73 74 75 |
# File 'lib/ruby-lint/analysis/argument_amount.rb', line 67 def determine_method(scope, name) method = scope.lookup(scope.method_call_type, name) if method and MAP_METHODS[method.name] method = scope.lookup(*MAP_METHODS[method.name]) end return method end |
#on_send(node) ⇒ Object
24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
# File 'lib/ruby-lint/analysis/argument_amount.rb', line 24 def on_send(node) receiver, name, *args = *node scope = scope_for_receiver(receiver) method = determine_method(scope, name.to_s) return unless method given = argument_amount(args) min, max = argument_range(method) unless correct_argument_amount(min, max, given) text = argument_text(method, given) error( "wrong number of arguments for '#{method.name}' " \ "(expected #{text} but got #{given})", node ) end end |
#scope_for_receiver(receiver) ⇒ RubyLint::Definition::RubyObject (private)
52 53 54 55 56 57 58 59 60 |
# File 'lib/ruby-lint/analysis/argument_amount.rb', line 52 def scope_for_receiver(receiver) scope = current_scope if receiver and vm.associations.key?(receiver) scope = vm.associations[receiver] end return scope end |