2019-10-29 10:08:37 -04:00
|
|
|
require_relative "../spell_checker"
|
|
|
|
|
|
|
|
module DidYouMean
|
|
|
|
class MethodNameChecker
|
|
|
|
attr_reader :method_name, :receiver
|
|
|
|
|
|
|
|
NAMES_TO_EXCLUDE = { NilClass => nil.methods }
|
|
|
|
NAMES_TO_EXCLUDE.default = []
|
2021-12-24 07:04:49 -05:00
|
|
|
Ractor.make_shareable(NAMES_TO_EXCLUDE) if defined?(Ractor)
|
2019-10-29 10:08:37 -04:00
|
|
|
|
|
|
|
# +MethodNameChecker::RB_RESERVED_WORDS+ is the list of reserved words in
|
|
|
|
# Ruby that take an argument. Unlike
|
|
|
|
# +VariableNameChecker::RB_RESERVED_WORDS+, these reserved words require
|
|
|
|
# an argument, and a +NoMethodError+ is raised due to the presence of the
|
|
|
|
# argument.
|
|
|
|
#
|
|
|
|
# The +MethodNameChecker+ will use this list to suggest a reversed word if
|
|
|
|
# a +NoMethodError+ is raised and found closest matches.
|
|
|
|
#
|
|
|
|
# Also see +VariableNameChecker::RB_RESERVED_WORDS+.
|
|
|
|
RB_RESERVED_WORDS = %i(
|
|
|
|
alias
|
|
|
|
case
|
|
|
|
def
|
|
|
|
defined?
|
|
|
|
elsif
|
|
|
|
end
|
|
|
|
ensure
|
|
|
|
for
|
|
|
|
rescue
|
|
|
|
super
|
|
|
|
undef
|
|
|
|
unless
|
|
|
|
until
|
|
|
|
when
|
|
|
|
while
|
|
|
|
yield
|
|
|
|
)
|
|
|
|
|
2021-12-24 07:04:49 -05:00
|
|
|
Ractor.make_shareable(RB_RESERVED_WORDS) if defined?(Ractor)
|
|
|
|
|
2019-10-29 10:08:37 -04:00
|
|
|
def initialize(exception)
|
|
|
|
@method_name = exception.name
|
|
|
|
@receiver = exception.receiver
|
|
|
|
@private_call = exception.respond_to?(:private_call?) ? exception.private_call? : false
|
|
|
|
end
|
|
|
|
|
|
|
|
def corrections
|
2020-05-22 17:17:10 -04:00
|
|
|
@corrections ||= begin
|
|
|
|
dictionary = method_names
|
|
|
|
dictionary = RB_RESERVED_WORDS + dictionary if @private_call
|
|
|
|
|
|
|
|
SpellChecker.new(dictionary: dictionary).correct(method_name) - names_to_exclude
|
|
|
|
end
|
2019-10-29 10:08:37 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
def method_names
|
2019-12-04 19:55:01 -05:00
|
|
|
if Object === receiver
|
|
|
|
method_names = receiver.methods + receiver.singleton_methods
|
|
|
|
method_names += receiver.private_methods if @private_call
|
|
|
|
method_names.uniq!
|
|
|
|
method_names
|
|
|
|
else
|
|
|
|
[]
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def names_to_exclude
|
|
|
|
Object === receiver ? NAMES_TO_EXCLUDE[receiver.class] : []
|
2019-10-29 10:08:37 -04:00
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|