Class: RuboCop::Cop::Lint::UselessConstantScoping

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

Overview

Checks for useless constant scoping. Private constants must be defined using private_constant. Even if private access modifier is used, it is public scope despite its appearance.

It does not support autocorrection due to behavior change and multiple ways to fix it. Or a public constant may be intended.

Constant assignments that define classes or modules via Class.new, Module.new, Struct.new, or Data.define are allowed. Those forms are class and module definitions written with assignment syntax, and match the common practice of placing nested class / module bodies after private without intending private constant visibility.

Examples:


# bad
class Foo
  private
  PRIVATE_CONST = 42
end

# good
class Foo
  PRIVATE_CONST = 42
  private_constant :PRIVATE_CONST
end

# good
class Foo
  PUBLIC_CONST = 42 # If private scope is not intended.
end

# good - class/module definitions via assignment, same as nested `class`/`module`
class Foo
  private

  def some_private_method
  end

  MyClass = Class.new
  MyModule = Module.new
  MyStruct = Struct.new(:name)
  MyData = Data.define(:name)
end

Constant Summary collapse

MSG =
'Useless `private` access modifier for constant scope.'

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 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_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

#class_or_module_definition_assignment?(node) ⇒ Object

Matches class/module-like constant assignments. Nested class / module keyword definitions are not visited by this cop; these assignment forms are the equivalent syntax and should be treated the same way.



62
63
64
65
66
67
68
69
70
71
72
73
# File 'lib/rubocop/cop/lint/useless_constant_scoping.rb', line 62

def_node_matcher :class_or_module_definition_assignment?, <<~PATTERN
  {
    (send (const {nil? cbase} {:Class :Module :Struct}) :new ...)
    (send (const {nil? cbase} :Data) :define ...)
    (any_block
      {
        (send (const {nil? cbase} {:Class :Module :Struct}) :new ...)
        (send (const {nil? cbase} :Data) :define ...)
      }
      ...)
  }
PATTERN

#on_casgn(node) ⇒ Object



75
76
77
78
79
80
81
# File 'lib/rubocop/cop/lint/useless_constant_scoping.rb', line 75

def on_casgn(node)
  return unless after_private_modifier?(node.left_siblings)
  return if private_constantize?(node.right_siblings, node.name)
  return if class_or_module_definition_assignment?(node.expression)

  add_offense(node)
end

#private_constants(node) ⇒ Object



54
55
56
# File 'lib/rubocop/cop/lint/useless_constant_scoping.rb', line 54

def_node_matcher :private_constants, <<~PATTERN
  (send nil? :private_constant $...)
PATTERN