Class: RuboCop::Cop::Sorbet::BuggyObsoleteStrictMemoization
- Inherits:
-
Base
- Object
- Base
- RuboCop::Cop::Sorbet::BuggyObsoleteStrictMemoization
- Extended by:
- AutoCorrector
- Includes:
- Alignment, LineLengthHelp, MatchRange, RangeHelp, TargetSorbetVersion
- Defined in:
- lib/rubocop/cop/sorbet/buggy_obsolete_strict_memoization.rb
Overview
Checks for the a mistaken variant of the "obsolete memoization pattern" that used to be required
for older Sorbet versions in #typed: strict files. The mistaken variant would overwrite the ivar with nil
on every call, causing the memoized value to be discarded and recomputed on every call.
This cop will correct it to read from the ivar instead of nil, which will memoize it correctly.
The result of this correction will be the "obsolete memoization pattern", which can further be corrected by
the Sorbet/ObsoleteStrictMemoization cop.
See Sorbet/ObsoleteStrictMemoization for more details.
Constant Summary collapse
- MSG =
"This might be a mistaken variant of the two-stage workaround that used to be needed for memoization " \ "in `#typed: strict` files. See https://sorbet.org/docs/type-assertions#put-type-assertions-behind-memoization."
Instance Method Summary collapse
- #buggy_legacy_memoization_pattern?(node) ⇒ Object
- #on_begin(node) ⇒ Object
- #relevant_file?(file) ⇒ Boolean
Methods included from TargetSorbetVersion
#enabled_for_sorbet_static_version?, included, #read_sorbet_static_version_from_bundler_lock_file, #sorbet_enabled?, #target_sorbet_static_version_from_bundler_lock_file
Instance Method Details
#buggy_legacy_memoization_pattern?(node) ⇒ Object
55 56 57 58 59 60 61 62 63 64 |
# File 'lib/rubocop/cop/sorbet/buggy_obsolete_strict_memoization.rb', line 55 def_node_matcher :buggy_legacy_memoization_pattern?, <<~PATTERN (begin ... # Ignore any other lines that come first. (ivasgn $_ivar # First line: @_ivar = ... (send # T.let(_ivar, T.nilable(_ivar_type)) (const {nil? cbase} :T) :let $nil (send (const {nil? cbase} :T) :nilable _ivar_type))) # T.nilable(_ivar_type) (or-asgn (ivasgn _ivar) _initialization_expr)) # Second line: @_ivar ||= _initialization_expr PATTERN |
#on_begin(node) ⇒ Object
66 67 68 69 70 71 72 73 74 75 |
# File 'lib/rubocop/cop/sorbet/buggy_obsolete_strict_memoization.rb', line 66 def on_begin(node) buggy_legacy_memoization_pattern?(node) do |ivar, nil_node| add_offense(nil_node) do |corrector| corrector.replace( range_between(nil_node.source_range.begin_pos, nil_node.source_range.end_pos), ivar, ) end end end |
#relevant_file?(file) ⇒ Boolean
77 78 79 |
# File 'lib/rubocop/cop/sorbet/buggy_obsolete_strict_memoization.rb', line 77 def relevant_file?(file) super && sorbet_enabled? end |