Class: RuboCop::Cop::Lint::MissingSuper

Inherits:
Base
  • Object
show all
Defined in:
lib/rubocop/cop/lint/missing_super.rb

Overview

Checks for the presence of constructors and lifecycle callbacks without calls to ‘super`.

This cop does not consider ‘method_missing` (and `respond_to_missing?`) because in some cases it makes sense to overtake what is considered a missing method. In other cases, the theoretical ideal handling could be challenging or verbose for no actual gain.

Autocorrection is not supported because the position of ‘super` cannot be determined automatically.

‘Object` and `BasicObject` are allowed by this cop because of their stateless nature. However, sometimes you might want to allow other parent classes from this cop, for example in the case of an abstract class that is not meant to be called with `super`. In those cases, you can use the `AllowedParentClasses` option to specify which classes should be allowed *in addition to* `Object` and `BasicObject`.

Examples:

# bad
class Employee < Person
  def initialize(name, salary)
    @salary = salary
  end
end

# good
class Employee < Person
  def initialize(name, salary)
    super(name)
    @salary = salary
  end
end

# bad
Employee = Class.new(Person) do
  def initialize(name, salary)
    @salary = salary
  end
end

# good
Employee = Class.new(Person) do
  def initialize(name, salary)
    super(name)
    @salary = salary
  end
end

# bad
class Parent
  def self.inherited(base)
    do_something
  end
end

# good
class Parent
  def self.inherited(base)
    super
    do_something
  end
end

# good
class ClassWithNoParent
  def initialize
    do_something
  end
end

AllowedParentClasses: [MyAbstractClass]

# good
class MyConcreteClass < MyAbstractClass
  def initialize
    do_something
  end
end

Constant Summary collapse

CONSTRUCTOR_MSG =
'Call `super` to initialize state of the parent class.'
CALLBACK_MSG =
'Call `super` to invoke callback defined in the parent class.'
STATELESS_CLASSES =
%w[BasicObject Object].freeze
CLASS_LIFECYCLE_CALLBACKS =
%i[inherited].freeze
METHOD_LIFECYCLE_CALLBACKS =
%i[method_added method_removed method_undefined
singleton_method_added singleton_method_removed
singleton_method_undefined].freeze
CALLBACKS =
(CLASS_LIFECYCLE_CALLBACKS + METHOD_LIFECYCLE_CALLBACKS).to_set.freeze

Constants inherited from Base

Base::RESTRICT_ON_SEND

Instance Attribute Summary

Attributes inherited from Base

#config, #processed_source

Instance Method Summary collapse

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?, #message, #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_rails_version, #target_ruby_version

Methods included from ExcludeLimit

#exclude_limit

Methods included from AutocorrectLogic

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

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

#class_new_block(node) ⇒ Object



99
100
101
102
103
# File 'lib/rubocop/cop/lint/missing_super.rb', line 99

def_node_matcher :class_new_block, <<~RUBY
  ({block numblock}
    (send
      (const {nil? cbase} :Class) :new $_) ...)
RUBY

#on_def(node) ⇒ Object



105
106
107
108
109
110
111
112
113
# File 'lib/rubocop/cop/lint/missing_super.rb', line 105

def on_def(node)
  return unless offender?(node)

  if node.method?(:initialize) && inside_class_with_stateful_parent?(node)
    add_offense(node, message: CONSTRUCTOR_MSG)
  elsif callback_method_def?(node)
    add_offense(node, message: CALLBACK_MSG)
  end
end

#on_defs(node) ⇒ Object



115
116
117
118
119
# File 'lib/rubocop/cop/lint/missing_super.rb', line 115

def on_defs(node)
  return if !callback_method_def?(node) || contains_super?(node)

  add_offense(node, message: CALLBACK_MSG)
end