Class: RuboCop::Cop::Lint::UnusedPrivateMethod

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

Overview

Checks for private instance methods that are not referenced anywhere in the project.

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.

A method counts as referenced when a call with its name appears anywhere in the indexed project (regardless of the receiver), when it is the source of an alias, or when its name appears in the same file as a symbol or inside a string literal (covering send(:name) and declarative DSLs like before_action :name). Methods defined in classes or modules with descendants are not checked, since they may be invoked through super or inherited dispatch, and neither are methods whose names are built dynamically (e.g. send("do_#{action}")).

The cop is disabled by default because symbol-based references from other files (e.g. a Rails callback declared in a concern) cannot be detected and would be reported as false positives. It is best suited for occasional dead-code sweeps rather than permanent enforcement.

Examples:

# bad - `helper` is never referenced anywhere in the project
class Service
  def call
    do_something
  end

  private

  def helper
  end
end

# good
class Service
  def call
    do_something(helper)
  end

  private

  def helper
  end
end

Constant Summary collapse

MSG =
'Private method `%<method>s` appears to be unused.'
IDENTIFIER_PATTERN =
/[a-zA-Z_]\w*[?!=]?/.freeze
IMPLICITLY_INVOKED_METHODS =

Methods invoked implicitly by the Ruby runtime.

%i[initialize initialize_copy initialize_clone
initialize_dup method_missing respond_to_missing?
marshal_dump marshal_load].to_set.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

Class Method Summary collapse

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?, #message, #offenses, #on_investigation_end, #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?

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

Class Method Details

.reference_names_cacheObject

The reference-name set is derived once per index and shared by the per-file cop instances.



67
68
69
# File 'lib/rubocop/cop/lint/unused_private_method.rb', line 67

def reference_names_cache
  @reference_names_cache ||= {}.compare_by_identity
end

Instance Method Details

#on_def(node) ⇒ Object



77
78
79
80
81
82
83
84
85
86
87
# File 'lib/rubocop/cop/lint/unused_private_method.rb', line 77

def on_def(node)
  return unless project_index

  declaration = checkable_declaration(node)
  return unless declaration
  return if referenced?(node.method_name)
  return if owner_with_descendants?(declaration) || override?(declaration, node.method_name)

  message = format(MSG, method: node.method_name)
  add_offense(node.loc.keyword.join(node.loc.name), message: message)
end

#on_new_investigationObject



72
73
74
75
# File 'lib/rubocop/cop/lint/unused_private_method.rb', line 72

def on_new_investigation
  @literal_names = nil
  super
end