rubocop-sorbet 0.7.3 → 0.7.4

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a0c73cc4c4d3b4982d210699da94d0dca321a93bf95e98579dc32521714e2921
4
- data.tar.gz: b9aa475dea9aa87511868680e92fb1ad5dff83a5b8186439179c17371eaf35f5
3
+ metadata.gz: d771dbc78b04c867bb517a024dacaf6d1c280539ebbd6950374a19fe9d89e439
4
+ data.tar.gz: 5310766358cdbfec15d154733f32769ab7320cf987798710a2c0f1dcd2fddceb
5
5
  SHA512:
6
- metadata.gz: 03a722e469cf1796ba965b044475dabbbe2d99a6b0b79efc083d605bd8dd0973ed1d320dbe511241dd6bfad3c9df7acb6354217ded268db5939ad7f8bf7684aa
7
- data.tar.gz: 9fd995f27b0881e5ec939da2b0b1a87372bc910faa4f27cbaf0de43c367d877e1c5b077397f80130ec58f1caa7b6047a7c51ea1eb0872f194f118ce27dbfa10d
6
+ metadata.gz: 2b0a1b42b4a1a368565d86ef69a335bc5345a562a892dcc930bd4786e1049c5d4cc018a762df22ffac6189aa68628d3c5f74cee147232f6eb9de62d21350d19b
7
+ data.tar.gz: 21d0d71d76975bb9204622b40a026fdc3c5c62105506ddfa293df0cf117e52d05e541a430290d045792208019a60ee824c9e8535d36a5d8f70f455abdbc42f89
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- rubocop-sorbet (0.7.3)
4
+ rubocop-sorbet (0.7.4)
5
5
  rubocop (>= 0.90.0)
6
6
 
7
7
  GEM
data/config/default.yml CHANGED
@@ -97,6 +97,13 @@ Sorbet/ForbidSuperclassConstLiteral:
97
97
  Exclude:
98
98
  - db/migrate/*.rb
99
99
 
100
+ Sorbet/ForbidTStruct:
101
+ Description: 'Forbid usage of T::Struct.'
102
+ Enabled: false
103
+ VersionAdded: <<next>>
104
+ VersionChanged: <<next>>
105
+ Safe: false
106
+
100
107
  Sorbet/ForbidTUnsafe:
101
108
  Description: 'Forbid usage of T.unsafe.'
102
109
  Enabled: false
@@ -171,6 +178,23 @@ Sorbet/ObsoleteStrictMemoization:
171
178
  Safe: true
172
179
  SafeAutoCorrect: true
173
180
 
181
+ Sorbet/BuggyObsoleteStrictMemoization:
182
+ Description: >-
183
+ Checks for the a mistaken variant of the "obsolete memoization pattern" that used to be required
184
+ for older Sorbet versions in `#typed: strict` files. The mistaken variant would overwrite the ivar with `nil`
185
+ on every call, causing the memoized value to be discarded and recomputed on every call.
186
+
187
+ This cop will correct it to read from the ivar instead of `nil`, which will memoize it correctly.
188
+
189
+ The result of this correction will be the "obsolete memoization pattern", which can further be corrected by
190
+ the `Sorbet/ObsoleteStrictMemoization` cop.
191
+
192
+ See `Sorbet/ObsoleteStrictMemoization` for more details.
193
+ Enabled: true
194
+ VersionAdded: '0.7.3'
195
+ Safe: true
196
+ SafeAutoCorrect: false
197
+
174
198
  Sorbet/OneAncestorPerLine:
175
199
  Description: 'Enforces one ancestor per call to requires_ancestor'
176
200
  Enabled: false
@@ -0,0 +1,83 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "rubocop"
4
+
5
+ module RuboCop
6
+ module Cop
7
+ module Sorbet
8
+ # Checks for the a mistaken variant of the "obsolete memoization pattern" that used to be required
9
+ # for older Sorbet versions in `#typed: strict` files. The mistaken variant would overwrite the ivar with `nil`
10
+ # on every call, causing the memoized value to be discarded and recomputed on every call.
11
+ #
12
+ # This cop will correct it to read from the ivar instead of `nil`, which will memoize it correctly.
13
+ #
14
+ # The result of this correction will be the "obsolete memoization pattern", which can further be corrected by
15
+ # the `Sorbet/ObsoleteStrictMemoization` cop.
16
+ #
17
+ # See `Sorbet/ObsoleteStrictMemoization` for more details.
18
+ #
19
+ # @safety
20
+ # If the computation being memoized had side effects, calling it only once (instead of once on every call
21
+ # to the affected method) can be observed, and might be a breaking change.
22
+ #
23
+ # @example
24
+ # # bad
25
+ # sig { returns(Foo) }
26
+ # def foo
27
+ # # This `nil` is likely a mistake, causing the memoized value to be discarded and recomputed on every call.
28
+ # @foo = T.let(nil, T.nilable(Foo))
29
+ # @foo ||= some_computation
30
+ # end
31
+ #
32
+ # # good
33
+ # sig { returns(Foo) }
34
+ # def foo
35
+ # # This will now memoize the value as was likely intended, so `some_computation` is only ever called once.
36
+ # # ⚠️If `some_computation` has side effects, this might be a breaking change!
37
+ # @foo = T.let(@foo, T.nilable(Foo))
38
+ # @foo ||= some_computation
39
+ # end
40
+ #
41
+ # @see Sorbet/ObsoleteStrictMemoization
42
+ class BuggyObsoleteStrictMemoization < RuboCop::Cop::Base
43
+ include RuboCop::Cop::MatchRange
44
+ include RuboCop::Cop::Alignment
45
+ include RuboCop::Cop::LineLengthHelp
46
+ include RuboCop::Cop::RangeHelp
47
+ extend AutoCorrector
48
+
49
+ include TargetSorbetVersion
50
+
51
+ MSG = "This might be a mistaken variant of the two-stage workaround that used to be needed for memoization in "\
52
+ "`#typed: strict` files. See https://sorbet.org/docs/type-assertions#put-type-assertions-behind-memoization."
53
+
54
+ # @!method buggy_legacy_memoization_pattern?(node)
55
+ def_node_matcher :buggy_legacy_memoization_pattern?, <<~PATTERN
56
+ (begin
57
+ ... # Ignore any other lines that come first.
58
+ (ivasgn $_ivar # First line: @_ivar = ...
59
+ (send # T.let(_ivar, T.nilable(_ivar_type))
60
+ (const {nil? cbase} :T) :let
61
+ $nil
62
+ (send (const {nil? cbase} :T) :nilable _ivar_type))) # T.nilable(_ivar_type)
63
+ (or-asgn (ivasgn _ivar) _initialization_expr)) # Second line: @_ivar ||= _initialization_expr
64
+ PATTERN
65
+
66
+ def on_begin(node)
67
+ buggy_legacy_memoization_pattern?(node) do |ivar, nil_node|
68
+ add_offense(nil_node) do |corrector|
69
+ corrector.replace(
70
+ range_between(nil_node.source_range.begin_pos, nil_node.source_range.end_pos),
71
+ ivar,
72
+ )
73
+ end
74
+ end
75
+ end
76
+
77
+ def relevant_file?(file)
78
+ super && sorbet_enabled?
79
+ end
80
+ end
81
+ end
82
+ end
83
+ end
@@ -0,0 +1,223 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "rubocop"
4
+
5
+ module RuboCop
6
+ module Cop
7
+ module Sorbet
8
+ # Disallow using `T::Struct` and `T::Props`.
9
+ #
10
+ # @example
11
+ #
12
+ # # bad
13
+ # class MyStruct < T::Struct
14
+ # const :foo, String
15
+ # prop :bar, Integer, default: 0
16
+ #
17
+ # def some_method; end
18
+ # end
19
+ #
20
+ # # good
21
+ # class MyStruct
22
+ # extend T::Sig
23
+ #
24
+ # sig { returns(String) }
25
+ # attr_reader :foo
26
+ #
27
+ # sig { returns(Integer) }
28
+ # attr_accessor :bar
29
+ #
30
+ # sig { params(foo: String, bar: Integer) }
31
+ # def initialize(foo:, bar: 0)
32
+ # @foo = foo
33
+ # @bar = bar
34
+ # end
35
+ #
36
+ # def some_method; end
37
+ # end
38
+ class ForbidTStruct < RuboCop::Cop::Base
39
+ include Alignment
40
+ include RangeHelp
41
+ include CommentsHelp
42
+ extend AutoCorrector
43
+
44
+ RESTRICT_ON_SEND = [:include, :prepend, :extend].freeze
45
+
46
+ MSG_STRUCT = "Using `T::Struct` or its variants is deprecated."
47
+ MSG_PROPS = "Using `T::Props` or its variants is deprecated."
48
+
49
+ # This class walks down the class body of a T::Struct and collects all the properties that will need to be
50
+ # translated into `attr_reader` and `attr_accessor` methods.
51
+ class TStructWalker
52
+ include AST::Traversal
53
+ extend AST::NodePattern::Macros
54
+
55
+ attr_reader :props, :has_extend_t_sig
56
+
57
+ def initialize
58
+ @props = []
59
+ @has_extend_t_sig = false
60
+ end
61
+
62
+ # @!method extend_t_sig?(node)
63
+ def_node_matcher :extend_t_sig?, <<~PATTERN
64
+ (send _ :extend (const (const {nil? | cbase} :T) :Sig))
65
+ PATTERN
66
+
67
+ # @!method t_struct_prop?(node)
68
+ def_node_matcher(:t_struct_prop?, <<~PATTERN)
69
+ (send nil? {:const :prop} ...)
70
+ PATTERN
71
+
72
+ def on_send(node)
73
+ if extend_t_sig?(node)
74
+ # So we know we won't need to generate again a `extend T::Sig` line in the new class body
75
+ @has_extend_t_sig = true
76
+ return
77
+ end
78
+
79
+ return unless t_struct_prop?(node)
80
+
81
+ kind = node.method?(:const) ? :attr_reader : :attr_accessor
82
+ name = node.arguments[0].source.delete_prefix(":")
83
+ type = node.arguments[1].source
84
+ default = nil
85
+ factory = nil
86
+
87
+ node.arguments[2..-1].each do |arg|
88
+ next unless arg.hash_type?
89
+
90
+ arg.each_pair do |key, value|
91
+ case key.source
92
+ when "default"
93
+ default = value.source
94
+ when "factory"
95
+ factory = value.source
96
+ end
97
+ end
98
+ end
99
+
100
+ @props << Property.new(node, kind, name, type, default: default, factory: factory)
101
+ end
102
+ end
103
+
104
+ class Property
105
+ attr_reader :node, :kind, :name, :type, :default, :factory
106
+
107
+ def initialize(node, kind, name, type, default:, factory:)
108
+ @node = node
109
+ @kind = kind
110
+ @name = name
111
+ @type = type
112
+ @default = default
113
+ @factory = factory
114
+
115
+ # A T::Struct should have both a default and a factory, if we find one let's raise an error
116
+ raise if @default && @factory
117
+ end
118
+
119
+ def attr_sig
120
+ "sig { returns(#{type}) }"
121
+ end
122
+
123
+ def attr_accessor
124
+ "#{kind} :#{name}"
125
+ end
126
+
127
+ def initialize_sig_param
128
+ "#{name}: #{type}"
129
+ end
130
+
131
+ def initialize_param
132
+ rb = String.new
133
+ rb << "#{name}:"
134
+ rb << " #{default}" if default
135
+ rb << " #{factory}" if factory
136
+ rb
137
+ end
138
+
139
+ def initialize_assign
140
+ rb = String.new
141
+ rb << "@#{name} = #{name}"
142
+ rb << ".call" if factory
143
+ rb
144
+ end
145
+ end
146
+
147
+ # @!method t_struct?(node)
148
+ def_node_matcher(:t_struct?, <<~PATTERN)
149
+ (const (const {nil? cbase} :T) {:Struct :ImmutableStruct :InexactStruct})
150
+ PATTERN
151
+
152
+ # @!method t_props?(node)
153
+ def_node_matcher(:t_props?, "(send nil? {:include :prepend :extend} `(const (const {nil? cbase} :T) :Props))")
154
+
155
+ def on_class(node)
156
+ return unless t_struct?(node.parent_class)
157
+
158
+ add_offense(node, message: MSG_STRUCT) do |corrector|
159
+ walker = TStructWalker.new
160
+ walker.walk(node.body)
161
+
162
+ range = range_between(node.identifier.source_range.end_pos, node.parent_class.source_range.end_pos)
163
+ corrector.remove(range)
164
+ next if node.single_line?
165
+
166
+ unless walker.has_extend_t_sig
167
+ indent = offset(node)
168
+ corrector.insert_after(node.identifier, "\n#{indent} extend T::Sig\n")
169
+ end
170
+
171
+ first_prop = walker.props.first
172
+ walker.props.each do |prop|
173
+ node = prop.node
174
+ indent = offset(node)
175
+ line_range = range_by_whole_lines(prop.node.source_range)
176
+ new_line = prop != first_prop && !previous_line_blank?(node)
177
+ trailing_comments = processed_source.each_comment_in_lines(line_range.line..line_range.line)
178
+
179
+ corrector.replace(
180
+ line_range,
181
+ "#{new_line ? "\n" : ""}" \
182
+ "#{trailing_comments.map { |comment| "#{indent}#{comment.text}\n" }.join}" \
183
+ "#{indent}#{prop.attr_sig}\n#{indent}#{prop.attr_accessor}",
184
+ )
185
+ end
186
+
187
+ last_prop = walker.props.last
188
+ if last_prop
189
+ indent = offset(last_prop.node)
190
+ line_range = range_by_whole_lines(last_prop.node.source_range, include_final_newline: true)
191
+ corrector.insert_after(line_range, initialize_method(indent, walker.props))
192
+ end
193
+ end
194
+ end
195
+
196
+ def on_send(node)
197
+ return unless t_props?(node)
198
+
199
+ add_offense(node, message: MSG_PROPS)
200
+ end
201
+
202
+ private
203
+
204
+ def initialize_method(indent, props)
205
+ # We sort optional keyword arguments after required ones
206
+ props = props.sort_by { |prop| prop.default || prop.factory ? 1 : 0 }
207
+
208
+ string = +"\n"
209
+ string << "#{indent}sig { params(#{props.map(&:initialize_sig_param).join(", ")}).void }\n"
210
+ string << "#{indent}def initialize(#{props.map(&:initialize_param).join(", ")})\n"
211
+ props.each do |prop|
212
+ string << "#{indent} #{prop.initialize_assign}\n"
213
+ end
214
+ string << "#{indent}end\n"
215
+ end
216
+
217
+ def previous_line_blank?(node)
218
+ processed_source.buffer.source_line(node.source_range.line - 1).blank?
219
+ end
220
+ end
221
+ end
222
+ end
223
+ end
@@ -11,21 +11,25 @@ module RuboCop
11
11
  end
12
12
 
13
13
  module ClassMethods
14
- # The version of the Sorbet static type checker required by this cop
14
+ # Sets the version of the Sorbet static type checker required by this cop
15
15
  def minimum_target_sorbet_static_version(version)
16
16
  @minimum_target_sorbet_static_version = Gem::Version.new(version)
17
17
  end
18
18
 
19
- def support_target_sorbet_static_version?(version)
19
+ def supports_target_sorbet_static_version?(version)
20
20
  @minimum_target_sorbet_static_version <= Gem::Version.new(version)
21
21
  end
22
22
  end
23
23
 
24
+ def sorbet_enabled?
25
+ !target_sorbet_static_version_from_bundler_lock_file.nil?
26
+ end
27
+
24
28
  def enabled_for_sorbet_static_version?
25
29
  sorbet_static_version = target_sorbet_static_version_from_bundler_lock_file
26
30
  return false unless sorbet_static_version
27
31
 
28
- self.class.support_target_sorbet_static_version?(sorbet_static_version)
32
+ self.class.supports_target_sorbet_static_version?(sorbet_static_version)
29
33
  end
30
34
 
31
35
  def target_sorbet_static_version_from_bundler_lock_file
@@ -54,7 +54,7 @@ module RuboCop
54
54
  $(ivasgn $_ivar # First line: @_ivar = ...
55
55
  (send # T.let(_ivar, T.nilable(_ivar_type))
56
56
  $(const {nil? cbase} :T) :let
57
- {(ivar _ivar) nil}
57
+ (ivar _ivar)
58
58
  (send (const {nil? cbase} :T) :nilable $_ivar_type))) # T.nilable(_ivar_type)
59
59
  $(or-asgn (ivasgn _ivar) $_initialization_expr)) # Second line: @_ivar ||= _initialization_expr
60
60
  PATTERN
@@ -26,6 +26,7 @@ module RuboCop
26
26
  # end
27
27
  #
28
28
  class RedundantExtendTSig < RuboCop::Cop::Base
29
+ include RangeHelp
29
30
  extend AutoCorrector
30
31
 
31
32
  MSG = "Do not redundantly `extend T::Sig` when it is already included in all modules."
@@ -40,7 +41,7 @@ module RuboCop
40
41
  return unless extend_t_sig?(node)
41
42
 
42
43
  add_offense(node) do |corrector|
43
- corrector.remove(node)
44
+ corrector.remove(range_by_whole_lines(node.source_range, include_final_newline: true))
44
45
  end
45
46
  end
46
47
  end
@@ -10,11 +10,13 @@ require_relative "sorbet/forbid_untyped_struct_props"
10
10
  require_relative "sorbet/implicit_conversion_method"
11
11
  require_relative "sorbet/one_ancestor_per_line"
12
12
  require_relative "sorbet/callback_conditionals_binding"
13
+ require_relative "sorbet/forbid_t_struct"
13
14
  require_relative "sorbet/forbid_t_unsafe"
14
15
  require_relative "sorbet/forbid_t_untyped"
15
16
  require_relative "sorbet/redundant_extend_t_sig"
16
17
  require_relative "sorbet/type_alias_name"
17
18
  require_relative "sorbet/obsolete_strict_memoization"
19
+ require_relative "sorbet/buggy_obsolete_strict_memoization"
18
20
 
19
21
  require_relative "sorbet/rbi/forbid_extend_t_sig_helpers_in_shims"
20
22
  require_relative "sorbet/rbi/forbid_rbi_outside_of_allowed_paths"
@@ -2,6 +2,6 @@
2
2
 
3
3
  module RuboCop
4
4
  module Sorbet
5
- VERSION = "0.7.3"
5
+ VERSION = "0.7.4"
6
6
  end
7
7
  end
data/manual/cops.md CHANGED
@@ -7,6 +7,7 @@ In the following section you find all available cops:
7
7
 
8
8
  * [Sorbet/AllowIncompatibleOverride](cops_sorbet.md#sorbetallowincompatibleoverride)
9
9
  * [Sorbet/BindingConstantWithoutTypeAlias](cops_sorbet.md#sorbetbindingconstantwithouttypealias)
10
+ * [Sorbet/BuggyObsoleteStrictMemoization](cops_sorbet.md#sorbetbuggyobsoletestrictmemoization)
10
11
  * [Sorbet/CallbackConditionalsBinding](cops_sorbet.md#sorbetcallbackconditionalsbinding)
11
12
  * [Sorbet/CheckedTrueInSignature](cops_sorbet.md#sorbetcheckedtrueinsignature)
12
13
  * [Sorbet/ConstantsFromStrings](cops_sorbet.md#sorbetconstantsfromstrings)
@@ -19,6 +20,7 @@ In the following section you find all available cops:
19
20
  * [Sorbet/ForbidIncludeConstLiteral](cops_sorbet.md#sorbetforbidincludeconstliteral)
20
21
  * [Sorbet/ForbidRBIOutsideOfAllowedPaths](cops_sorbet.md#sorbetforbidrbioutsideofallowedpaths)
21
22
  * [Sorbet/ForbidSuperclassConstLiteral](cops_sorbet.md#sorbetforbidsuperclassconstliteral)
23
+ * [Sorbet/ForbidTStruct](cops_sorbet.md#sorbetforbidtstruct)
22
24
  * [Sorbet/ForbidTUnsafe](cops_sorbet.md#sorbetforbidtunsafe)
23
25
  * [Sorbet/ForbidTUntyped](cops_sorbet.md#sorbetforbidtuntyped)
24
26
  * [Sorbet/ForbidUntypedStructProps](cops_sorbet.md#sorbetforbiduntypedstructprops)
@@ -41,6 +41,44 @@ FooOrBar = T.any(Foo, Bar)
41
41
  FooOrBar = T.type_alias { T.any(Foo, Bar) }
42
42
  ```
43
43
 
44
+ ## Sorbet/BuggyObsoleteStrictMemoization
45
+
46
+ Enabled by default | Safe | Supports autocorrection | VersionAdded | VersionChanged
47
+ --- | --- | --- | --- | ---
48
+ Enabled | Yes | Yes (Unsafe) | 0.7.3 | -
49
+
50
+ Checks for the a mistaken variant of the "obsolete memoization pattern" that used to be required
51
+ for older Sorbet versions in `#typed: strict` files. The mistaken variant would overwrite the ivar with `nil`
52
+ on every call, causing the memoized value to be discarded and recomputed on every call.
53
+
54
+ This cop will correct it to read from the ivar instead of `nil`, which will memoize it correctly.
55
+
56
+ The result of this correction will be the "obsolete memoization pattern", which can further be corrected by
57
+ the `Sorbet/ObsoleteStrictMemoization` cop.
58
+
59
+ See `Sorbet/ObsoleteStrictMemoization` for more details.
60
+
61
+ ### Examples
62
+
63
+ ```ruby
64
+ # bad
65
+ sig { returns(Foo) }
66
+ def foo
67
+ # This `nil` is likely a mistake, causing the memoized value to be discarded and recomputed on every call.
68
+ @foo = T.let(nil, T.nilable(Foo))
69
+ @foo ||= some_computation
70
+ end
71
+
72
+ # good
73
+ sig { returns(Foo) }
74
+ def foo
75
+ # This will now memoize the value as was likely intended, so `some_computation` is only ever called once.
76
+ # ⚠️If `some_computation` has side effects, this might be a breaking change!
77
+ @foo = T.let(@foo, T.nilable(Foo))
78
+ @foo ||= some_computation
79
+ end
80
+ ```
81
+
44
82
  ## Sorbet/CallbackConditionalsBinding
45
83
 
46
84
  Enabled by default | Safe | Supports autocorrection | VersionAdded | VersionChanged
@@ -383,6 +421,45 @@ Name | Default value | Configurable values
383
421
  --- | --- | ---
384
422
  Exclude | `db/migrate/*.rb` | Array
385
423
 
424
+ ## Sorbet/ForbidTStruct
425
+
426
+ Enabled by default | Safe | Supports autocorrection | VersionAdded | VersionChanged
427
+ --- | --- | --- | --- | ---
428
+ Disabled | No | Yes | <<next>> | <<next>>
429
+
430
+ Disallow using `T::Struct` and `T::Props`.
431
+
432
+ ### Examples
433
+
434
+ ```ruby
435
+ # bad
436
+ class MyStruct < T::Struct
437
+ const :foo, String
438
+ prop :bar, Integer, default: 0
439
+
440
+ def some_method; end
441
+ end
442
+
443
+ # good
444
+ class MyStruct
445
+ extend T::Sig
446
+
447
+ sig { returns(String) }
448
+ attr_reader :foo
449
+
450
+ sig { returns(Integer) }
451
+ attr_accessor :bar
452
+
453
+ sig { params(foo: String, bar: Integer) }
454
+ def initialize(foo:, bar: 0)
455
+ @foo = foo
456
+ @bar = bar
457
+ end
458
+
459
+ def some_method; end
460
+ end
461
+ ```
462
+
386
463
  ## Sorbet/ForbidTUnsafe
387
464
 
388
465
  Enabled by default | Safe | Supports autocorrection | VersionAdded | VersionChanged
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rubocop-sorbet
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.7.3
4
+ version: 0.7.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ufuk Kayserilioglu
@@ -11,7 +11,7 @@ authors:
11
11
  autorequire:
12
12
  bindir: exe
13
13
  cert_chain: []
14
- date: 2023-08-16 00:00:00.000000000 Z
14
+ date: 2023-09-25 00:00:00.000000000 Z
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
17
17
  name: rspec
@@ -87,10 +87,12 @@ files:
87
87
  - dev.yml
88
88
  - lib/rubocop-sorbet.rb
89
89
  - lib/rubocop/cop/sorbet/binding_constant_without_type_alias.rb
90
+ - lib/rubocop/cop/sorbet/buggy_obsolete_strict_memoization.rb
90
91
  - lib/rubocop/cop/sorbet/callback_conditionals_binding.rb
91
92
  - lib/rubocop/cop/sorbet/constants_from_strings.rb
92
93
  - lib/rubocop/cop/sorbet/forbid_include_const_literal.rb
93
94
  - lib/rubocop/cop/sorbet/forbid_superclass_const_literal.rb
95
+ - lib/rubocop/cop/sorbet/forbid_t_struct.rb
94
96
  - lib/rubocop/cop/sorbet/forbid_t_unsafe.rb
95
97
  - lib/rubocop/cop/sorbet/forbid_t_untyped.rb
96
98
  - lib/rubocop/cop/sorbet/forbid_untyped_struct_props.rb
@@ -152,7 +154,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
152
154
  - !ruby/object:Gem::Version
153
155
  version: '0'
154
156
  requirements: []
155
- rubygems_version: 3.4.18
157
+ rubygems_version: 3.4.19
156
158
  signing_key:
157
159
  specification_version: 4
158
160
  summary: Automatic Sorbet code style checking tool.