Class: RuboCop::Cop::RBS::Lint::RestKeywordHash

Inherits:
RBS::CopBase
  • Object
show all
Defined in:
lib/rubocop/cop/rbs/lint/rest_keyword_hash.rb

Overview

Specifying the ‘Hash` type for `**` is a very special case and, in most situations, it is a mistake in type specification.

Examples:

# bad
def foo: (**Hash[Symbol, String]) -> void
# e.g.) foo(a: {x: "x"}, b: {y: "y"}, c: {z: "z"})

# good
def foo: (**String) -> void
# e.g.) foo(a: "x", b: "y", c: "z")

Instance Attribute Summary

Attributes inherited from RBS::CopBase

#processed_rbs_source

Instance Method Summary collapse

Methods inherited from RBS::CopBase

documentation_url, #investigation_rbs, #location_to_range, #on_new_investigation, #on_other_file, #on_rbs_attribute, #on_rbs_class, #on_rbs_constant, #on_rbs_global, #on_rbs_interface, #on_rbs_module, #on_rbs_new_investigation, #on_rbs_parsing_error, #on_rbs_private, #on_rbs_public, #on_rbs_type_alias, #on_rbs_var, #parse_rbs, #rbs_buffer, #tokenize, #walk

Methods included from RBS::OnTypeHelper

#on_not_type, #on_type

Instance Method Details

#check_type(type) ⇒ Object



31
32
33
34
35
36
37
38
39
40
41
42
# File 'lib/rubocop/cop/rbs/lint/rest_keyword_hash.rb', line 31

def check_type(type)
  case type
  when ::RBS::Types::ClassInstance
    if type.name.relative!.to_s == 'Hash'
      did_you_mean = type.args[1] or return
      range = location_to_range(type.location)
      message = "The type of `**` specifies only the type of value. " \
                "Did you mean `**#{did_you_mean}`?"
      add_offense(range, message:)
    end
  end
end

#on_rbs_def(decl) ⇒ Object



20
21
22
23
24
25
26
27
28
29
# File 'lib/rubocop/cop/rbs/lint/rest_keyword_hash.rb', line 20

def on_rbs_def(decl)
  decl.overloads.each do |overload|
    func = overload.method_type.type
    next unless func.is_a?(::RBS::Types::Function)

    if !func.rest_keywords.nil?
      check_type(func.rest_keywords.type)
    end
  end
end