Class: RuboCop::Cop::Sorbet::BlockMethodDefinition

Inherits:
Base
  • Object
show all
Extended by:
AutoCorrector
Includes:
Alignment
Defined in:
lib/rubocop/cop/sorbet/block_method_definition.rb

Overview

Disallow defining methods in blocks, to prevent running into issues caused by https://github.com/sorbet/sorbet/issues/3609.

As a workaround, use define_method instead.

The one exception is for Class.new blocks, as long as the result is assigned to a constant (i.e. as long as it is not an anonymous class). Another exception is for ActiveSupport::Concern class_methods blocks.

Examples:

# bad
yielding_method do
  def bad(args)
    # ...
  end
end

# bad
Class.new do
  def bad(args)
    # ...
  end
end

# good
yielding_method do
  define_method(:good) do |args|
    # ...
  end
end

# good
MyClass = Class.new do
  def good(args)
    # ...
  end
end

# good
module SomeConcern
  extend ActiveSupport::Concern

  class_methods do
    def good(args)
      # ...
    end
  end
end

Constant Summary collapse

MSG =
"Do not define methods in blocks (use `define_method` as a workaround)."

Instance Method Summary collapse

Instance Method Details

#activesupport_concern_class_methods_block?(node) ⇒ Object



62
63
64
65
66
67
68
# File 'lib/rubocop/cop/sorbet/block_method_definition.rb', line 62

def_node_matcher :activesupport_concern_class_methods_block?, <<~PATTERN
  (block
    (send nil? :class_methods)
    _
    _
  )
PATTERN

#module_extends_activesupport_concern?(node) ⇒ Object



71
72
73
74
75
76
77
78
# File 'lib/rubocop/cop/sorbet/block_method_definition.rb', line 71

def_node_matcher :module_extends_activesupport_concern?, <<~PATTERN
  (module _
    (begin
      <(send nil? :extend (const (const {nil? cbase} :ActiveSupport) :Concern)) ...>
      ...
    )
  )
PATTERN

#on_block(node) ⇒ Object Also known as: on_numblock



80
81
82
83
84
85
86
87
88
89
90
91
92
93
# File 'lib/rubocop/cop/sorbet/block_method_definition.rb', line 80

def on_block(node)
  if (parent = node.parent)
    return if parent.casgn_type?
  end

  # Check if this is a class_methods block inside an ActiveSupport::Concern
  return if in_activesupport_concern_class_methods_block?(node)

  node.each_descendant(:any_def) do |def_node|
    add_offense(def_node) do |corrector|
      autocorrect_method_in_block(corrector, def_node)
    end
  end
end