class RubyLint::Analysis::ArgumentAmount
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.
Constants
- MAP_METHODS
Hash that contains method names that should be used for analysis instead of the ones specified in the keys.
@return [Hash]
Public Instance Methods
@param [RubyLint::Node] node
# 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
Private Instance Methods
@param [RubyLint::AST::Node] nodes @return [Fixnum]
# File lib/ruby-lint/analysis/argument_amount.rb, line 129 def argument_amount(nodes) return nodes.reject { |n| n.type == :block_pass }.length end
Returns the minimum and maximum amount of arguments for a method call.
@param [RubyLint::Definition::RubyMethod] method @return [Array]
# 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
Returns a String
that indicates the amount of required arguments.
@param [RubyLint::Definition::RubyMethod] method @param [Numeric] given @return [String]
# 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
@param [Numeric] min @param [Numeric] max @param [Numeric] given @return [TrueClass|FalseClass]
# File lib/ruby-lint/analysis/argument_amount.rb, line 83 def correct_argument_amount(min, max, given) return given >= min && given <= max end
@param [RubyLint::Definition::RubyObject] scope @param [String] name @return [RubyLint::Definition::RubyMethod]
# 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
@param [RubyLint::AST::Node] receiver @return [RubyLint::Definition::RubyObject]
# 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