Class: RuboCop::Cop::Sorbet::VoidCheckedTests
- Inherits:
-
Base
- Object
- Base
- RuboCop::Cop::Sorbet::VoidCheckedTests
- Extended by:
- AutoCorrector
- Includes:
- RangeHelp, SignatureHelp
- Defined in:
- lib/rubocop/cop/sorbet/signatures/void_checked_tests.rb
Overview
Disallows the usage of ‘.void.checked(:tests)`.
Using ‘.void` changes the value returned from the method, but only if runtime type checking is enabled for the method. Methods marked `.void` will return different values in tests compared with non-test environments. This is particularly troublesome if branching on the result of a `.void` method, because the returned value in test code will be the truthy `VOID` value, while the non-test return value may be falsy depending on the method’s implementation.
-
Use ‘.returns(T.anything).checked(:tests)` to keep the runtime type checking for the rest of the parameters.
-
Use ‘.void.checked(:never)` if you are on an older version of Sorbet which does not have `T.anything` (meaning versions 0.5.10781 or earlier. Versions released after 2023-04-14 include `T.anything`.)
Instance Method Summary collapse
Methods included from SignatureHelp
#on_block, #signature?, #with_runtime?, #without_runtime?
Instance Method Details
#checked_tests(node) ⇒ Object
37 38 39 |
# File 'lib/rubocop/cop/sorbet/signatures/void_checked_tests.rb', line 37 def_node_search(:checked_tests, <<~PATTERN) ({csend send} _ :checked (sym :tests)) PATTERN |
#on_signature(node) ⇒ Object
58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 |
# File 'lib/rubocop/cop/sorbet/signatures/void_checked_tests.rb', line 58 def on_signature(node) checked_send = checked_tests(node).first return unless checked_send if (parent = node.parent) && (sibling_index = node.sibling_index) later_siblings = parent.children[(sibling_index + 1)..] if (def_node = later_siblings.find { |sibling| sibling.is_a?(RuboCop::AST::DefNode) }) # Sorbet requires that `initialize` methods return `.void` # (A stylistic convention which happens to be enforced by Sorbet) return if def_node.method?(:initialize) end end void_send = top_level_void(node.body) return unless void_send add_offense( void_send.selector, message: MESSAGE, ) do |corrector| corrector.replace(void_send.selector, "returns(T.anything)") end end |