Class: RuboCop::Cop::Lint::NameTypo

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

Overview

Checks for probable typos in constant and method names: a name that does not resolve anywhere in the project, used in a namespace the project does define, with a close-named sibling to suggest instead.

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.

Constants are checked only in qualified references (Foo::Bar) whose namespace resolves in the index; bare names cannot be distinguished from constants provided by gems or the standard library. Methods are checked only in calls on constant receivers (Foo.bar) whose entire indexed ancestry is resolved, so methods gained through gem classes or dynamic definitions never produce offenses. In both cases an offense requires a similarly named alternative to exist — an unknown name alone is not reported, since the index does not see gems or the standard library.

Names that appear as symbols or inside string literals in the same file are never reported, since they usually belong to runtime definitions the index cannot see (stub_const, const_set, define_method, and the like).

Examples:

# bad - Services::UserCraetor is not defined, Services::UserCreator is
Services::UserCraetor.new

# good
Services::UserCreator.new

# bad - Report.generate_sumary is not defined, Report.generate_summary is
Report.generate_sumary

# good
Report.generate_summary

CheckConstants: false

# good - constant references are not checked
Services::UserCraetor.new

CheckMethods: false

# good - method calls are not checked
Report.generate_sumary

AllowedNames: ['generate_sumary']

# good - the name is explicitly allowed
Report.generate_sumary

Constant Summary collapse

CONSTANT_MSG =
'Possible typo: `%<name>s` is not defined in `%<namespace>s`. ' \
'Did you mean `%<suggestion>s`?'
METHOD_MSG =
'Possible typo: `%<receiver>s` does not respond to `%<name>s`. ' \
'Did you mean `%<suggestion>s`?'
METHOD_MEMBER_REGEXP =
/#([a-zA-Z_]\w*[?!]?)\(\)\z/.freeze
LITERAL_IDENTIFIER_PATTERN =
/[a-zA-Z_]\w*[?!]?/.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?, #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

Instance Method Details

#on_const(node) ⇒ Object



71
72
73
74
75
76
77
78
79
80
81
# File 'lib/rubocop/cop/lint/name_typo.rb', line 71

def on_const(node)
  return unless check?('CheckConstants') && checkable_constant?(node)

  suggestion = constant_typo_suggestion(node)
  return unless suggestion

  message = format(CONSTANT_MSG, name: node.short_name,
                                 namespace: node.namespace.const_name,
                                 suggestion: suggestion)
  add_offense(node.loc.name, message: message)
end

#on_new_investigationObject



98
99
100
101
# File 'lib/rubocop/cop/lint/name_typo.rb', line 98

def on_new_investigation
  @literal_names = nil
  super
end

#on_send(node) ⇒ Object Also known as: on_csend



83
84
85
86
87
88
89
90
91
92
93
94
95
# File 'lib/rubocop/cop/lint/name_typo.rb', line 83

def on_send(node)
  return unless check?('CheckMethods')
  return unless node.receiver&.const_type?
  return if allowed_name?(node.method_name) || defined_check?(node)

  suggestion = method_typo_suggestion(node)
  return unless suggestion

  message = format(METHOD_MSG, receiver: node.receiver.const_name,
                               name: node.method_name,
                               suggestion: suggestion)
  add_offense(node.loc.selector, message: message)
end