class RuboCop::Cop::Sorbet::CallbackConditionalsBinding
end
end
true
def should_do_it?
}
should_do_it?
T.bind(self, Post)
before_create :do_it, if: -> {
class Post < ApplicationRecord
# good
end
end
true
def should_do_it?
before_create :do_it, if: -> { should_do_it? }
class Post < ApplicationRecord
# bad
@example
introduces new typing errors.
binding to the attached class. Auto-correcting those usages can lead to false positives and auto-correction
Auto-correction is unsafe because other libraries define similar style callbacks as Rails, but don’t always need
so that they are type checked properly.
Ensures that callback conditionals are bound to the right type
def immediately_enclosing_module_name(node)
Find the immediately enclosing class or module name.
def immediately_enclosing_module_name(node) (node.parent&.begin_type? ? node.parent.parent : node.parent)&.defined_module_name end
def on_send(node)
def on_send(node) type = immediately_enclosing_module_name(node) return unless type node.arguments.each do |arg| next unless arg.hash_type? # Skip non-keyword arguments arg.each_child_node do |pair_node| argumentless_unbound_callable_callback_conditional?(pair_node) do |block| add_offense(pair_node, message: format(MSG, type: type)) do |corrector| block_opening_indentation = block.source_range.source_line[/\A */] block_body_indentation = block_opening_indentation + SPACE * configured_indentation_width if block.single_line? # then convert to multi-line block first # 1. Replace whitespace (if any) between the opening delimiter and the block body, # with newline and the correct indentation for the block body. preceeding_whitespace_range = block.loc.begin.end.join(block.body.source_range.begin) corrector.replace(preceeding_whitespace_range, "\n#{block_body_indentation}") # 2. Replace whitespace (if any) between the block body and the closing delimiter, # with newline and the same indentation as the block opening. trailing_whitespace_range = block.body.source_range.end.join(block.loc.end.begin) corrector.replace(trailing_whitespace_range, "\n#{block_opening_indentation}") end # Prepend the binding to the block body corrector.insert_before(block.body, "T.bind(self, #{type})\n#{block_body_indentation}") end end end end end