Class: RuboCop::Cop::TypeToolkit::DontExpectUnexpectedNil

Inherits:
Base
  • Object
show all
Defined in:
lib/rubocop/cop/type_toolkit/dont_expect_unexpected_nil.rb

Overview

This cop detects attempts to raise, rescue, or otherwise use the UnexpectedNilError class.

Constant Summary collapse

RESTRICT_ON_SEND =
[:assert_raises, :raise].freeze

Instance Method Summary collapse

Instance Method Details

#on_const(node) ⇒ Object

This is a catch-all for cases where the UnexpectedNilError class is used outside of a raise, rescue, etc.

Signature:

  • (RuboCop::AST::ConstNode) -> void



39
40
41
42
43
44
45
46
# File 'lib/rubocop/cop/type_toolkit/dont_expect_unexpected_nil.rb', line 39

def on_const(node)
  # Don't report this node right away, in case its parent AST is reported by one of the other cases.
  # Instead, record it for now, and maybe report it at the end of the investigation.
  if unexpected_nil_error?(node)
    @const_read_nodes ||= Set.new.compare_by_identity
    @const_read_nodes << node
  end
end

#on_investigation_endObject

Signature:

  • -> void



50
51
52
53
54
55
56
57
58
59
# File 'lib/rubocop/cop/type_toolkit/dont_expect_unexpected_nil.rb', line 50

def on_investigation_end
  @const_read_nodes&.each do |node|
    next if @ignored_const_nodes&.include?(node)

    message = "`UnexpectedNilError` should only ever be used by `#not_nil!`."
    add_offense(node, message:)
  end

  super
end

#on_resbody(node) ⇒ Object

Signature:

  • (RuboCop::AST::ResbodyNode) -> void



27
28
29
30
31
32
33
34
35
# File 'lib/rubocop/cop/type_toolkit/dont_expect_unexpected_nil.rb', line 27

def on_resbody(node)
  if (rescued_cls = node.exceptions.find { |ex_class| ex_class.const_type? && unexpected_nil_error?(ex_class) })
    message = "It is always a mistake for `not_nil!` to be called on nil, " \
      "so you should never try to rescue `UnexpectedNilError` specifically. " \
      "Change your code to gracefully handle `nil` instead."
    add_offense(rescued_cls, message:)
    ignore_const_node(rescued_cls)
  end
end

#on_send(node) ⇒ Object

Signature:

  • (RuboCop::AST::SendNode) -> void



19
20
21
22
23
24
# File 'lib/rubocop/cop/type_toolkit/dont_expect_unexpected_nil.rb', line 19

def on_send(node)
  case node.method_name
  when :raise then check_raise(node)
  when :assert_raises then check_assert_raises(node)
  end
end