Class: RuboCop::Cop::Lint::SuperArgumentMismatch

Inherits:
Base
  • Object
show all
Includes:
IndexedMethodArity, ProjectIndexHelp
Defined in:
lib/rubocop/cop/lint/super_argument_mismatch.rb

Overview

Checks for super calls with explicit arguments that pass the wrong number of positional arguments to the overridden implementation, using the project index.

The check is powered by the project-wide index, so it only runs when AllCops/UseProjectIndex is enabled and the rubydex gem is installed. Without the index the cop does nothing.

Only super inside a plain instance method defined directly in a class body is considered, and only when the enclosing class resolves in the index and its entire ancestry is resolved, so a superclass method coming from a gem, the standard library, or a dynamic definition never produces an offense. The overridden implementation is the first ancestor after the enclosing class in the index's method resolution order that defines the method; when it is not a plain method definition (an attr_* or an alias) or its definitions disagree on arity, the call is not checked. Calls that forward arguments (*, **, ...) are skipped, and bare super (which forwards the current method's parameters) is not checked. Methods the index attributes to Object, Kernel, or BasicObject are never used as the overridden implementation, since a def inside a block at the top level (Struct.new do ... end) is indexed under Object even though it defines a method somewhere else entirely.

Examples:

# Given the project defines:
#   class Base
#     def initialize(name, size); end
#   end

# bad
class Widget < Base
  def initialize(name)
    super(name)
  end
end

# good
class Widget < Base
  def initialize(name)
    super(name, 0)
  end
end

Constant Summary collapse

MSG =
'Wrong number of arguments to `super` ' \
'(given %<given>d, expected %<expected>s for `%<parent>s#%<method>s`).'
CONTEXT_CHANGING_BLOCKS =

Blocks that change what method (or scope) super refers to, or in which super is not statically resolvable.

%i[
  define_method define_singleton_method class_eval class_exec
  module_eval module_exec instance_eval instance_exec refine
].freeze
BUILTIN_ROOTS =

Methods the index attributes to the root namespaces are not trustworthy super targets: a def inside a block at the top level (Struct.new do ... end, Class.new do ... end) is indexed under Object even though it defines a method somewhere else entirely.

%w[Object Kernel BasicObject].freeze

Constants included from ProjectIndexHelp

ProjectIndexHelp::BUILTIN_DOCUMENT_URI, ProjectIndexHelp::FILE_URI_PREFIX, ProjectIndexHelp::WINDOWS_DRIVE_PREFIX

Constants inherited from Base

Base::RESTRICT_ON_SEND

Instance Attribute Summary

Attributes inherited from Base

#config, #processed_source, #project_index

Instance Method Summary collapse

Methods included from ProjectIndexHelp

#external_dependency_checksum

Methods inherited from Base

#active_support_extensions_enabled?, #add_global_offense, #add_offense, #always_autocorrect?, autocorrect_incompatible_with, badge, #begin_investigation, #callbacks_needed, callbacks_needed, #config_to_allow_offenses, #config_to_allow_offenses=, #contextual_autocorrect?, #cop_config, cop_name, #cop_name, department, documentation_url, exclude_from_registry, #excluded_file?, #external_dependency_checksum, inherited, #initialize, #inspect, joining_forces, lint?, match?, #offenses, #on_investigation_end, #on_new_investigation, #on_other_file, #parse, #parser_engine, #ready, #relevant_file?, requires_gem, #string_literals_frozen_by_default?, support_autocorrect?, support_multiple_source?, #target_gem_version, #target_rails_version, #target_ruby_version

Methods included from ExcludeLimit

cop_dir_for, #exclude_limit, read_limits

Methods included from AutocorrectLogic

#autocorrect?, #autocorrect_enabled?, #autocorrect_requested?, #autocorrect_with_disable_uncorrectable?, #correctable?, #disable_uncorrectable?, #safe_autocorrect?, #skipped_unsafe_correction_with_disable_uncorrectable?

Methods included from IgnoredNode

#ignore_node, #ignored_node?, #part_of_ignored_node?

Methods included from Util

silence_warnings

Constructor Details

This class inherits a constructor from RuboCop::Cop::Base

Instance Method Details

#on_super(node) ⇒ Object



69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
# File 'lib/rubocop/cop/lint/super_argument_mismatch.rb', line 69

def on_super(node)
  return unless project_index

  def_node = enclosing_instance_method(node)
  return unless def_node

  shape, parent = resolved_super_shape(def_node)
  return unless shape

  min, max, has_keywords = shape
  given = positional_argument_count(node, has_keywords)
  return if given.nil? || arity_satisfied?(given, min, max)

  add_offense(node.loc.keyword,
              message: message(def_node.method_name, parent, given, min, max))
end