rubocop-sorbet 0.7.3 → 0.7.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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.