rubocop-sorbet 0.10.2 → 0.10.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: 39f455b224ebfe0ed1167d4f65df45ba786f5605e7571c81775235563c2d964a
4
- data.tar.gz: f0b2762513b7ee13abf3e2ad63222e796df11692f837530af59285802a54389c
3
+ metadata.gz: 79bcbc5d5d2a20065dae6bd132ce89a78f6d55d913253f582d57b26dbc90e3fe
4
+ data.tar.gz: fc68fab55a25f15a2689564842768d87b2268ed99e8bdcf503284e47dd82deb2
5
5
  SHA512:
6
- metadata.gz: 1407c352354c7dcc548f0e6f2a031ba214627e09c766fd67665f0c47973232bbe406cff70a1a6c6178494bbacee41fcdc0ace83a2c987c7220cdd9e494384bbe
7
- data.tar.gz: 6df2c39e491354b98265115b646ed149bf84b127d28057a0eac05714ed45312377d2fc454945c3e602817b44b46d805c9572affa68d4f04429ef3635faf9663c
6
+ metadata.gz: 6b67f844675e5ca0c5f229cf8dd55e091f12c068dcaeb0cf289eded28a92367d32ead0f315ca4776bd0acd04e743c3c0420c345ac1ac6a7041f84dc61cc1fa78
7
+ data.tar.gz: ca77c4f1a29809ce05da20319309c760dff38fcf4adae09b60e4a588a24ca234a32c6a48226df8baa9eaa169b388953e4f65cb079a47d22f062924efdf3b9c3b
@@ -16,7 +16,7 @@ jobs:
16
16
  steps:
17
17
  - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
18
18
  - name: Set up Ruby
19
- uses: ruby/setup-ruby@13e7a03dc3ac6c3798f4570bfead2aed4d96abfb # v1.244.0
19
+ uses: ruby/setup-ruby@a4effe49ee8ee5b8b5091268c473a4628afb5651 # v1.245.0
20
20
  with:
21
21
  ruby-version: ${{ matrix.ruby }}
22
22
  bundler-cache: true
@@ -31,7 +31,7 @@ jobs:
31
31
  steps:
32
32
  - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
33
33
  - name: Set up Ruby
34
- uses: ruby/setup-ruby@13e7a03dc3ac6c3798f4570bfead2aed4d96abfb # v1.244.0
34
+ uses: ruby/setup-ruby@a4effe49ee8ee5b8b5091268c473a4628afb5651 # v1.245.0
35
35
  with:
36
36
  bundler-cache: true
37
37
  # This is just to ensure the default config is valid. The target is intentionally set
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- rubocop-sorbet (0.10.2)
4
+ rubocop-sorbet (0.10.4)
5
5
  lint_roller
6
6
  rubocop (>= 1.75.2)
7
7
 
@@ -39,7 +39,7 @@ GEM
39
39
  regexp_parser (2.10.0)
40
40
  reline (0.6.0)
41
41
  io-console (~> 0.5)
42
- rubocop (1.75.8)
42
+ rubocop (1.76.1)
43
43
  json (~> 2.3)
44
44
  language_server-protocol (~> 3.17.0.2)
45
45
  lint_roller (~> 1.1.0)
@@ -47,17 +47,17 @@ GEM
47
47
  parser (>= 3.3.0.2)
48
48
  rainbow (>= 2.2.2, < 4.0)
49
49
  regexp_parser (>= 2.9.3, < 3.0)
50
- rubocop-ast (>= 1.44.0, < 2.0)
50
+ rubocop-ast (>= 1.45.0, < 2.0)
51
51
  ruby-progressbar (~> 1.7)
52
52
  unicode-display_width (>= 2.4.0, < 4.0)
53
- rubocop-ast (1.44.1)
53
+ rubocop-ast (1.45.1)
54
54
  parser (>= 3.3.7.2)
55
55
  prism (~> 1.4)
56
56
  rubocop-minitest (0.38.1)
57
57
  lint_roller (~> 1.1)
58
58
  rubocop (>= 1.75.0, < 2.0)
59
59
  rubocop-ast (>= 1.38.0, < 2.0)
60
- rubocop-shopify (2.17.0)
60
+ rubocop-shopify (2.17.1)
61
61
  rubocop (~> 1.62)
62
62
  ruby-progressbar (1.13.0)
63
63
  ruby2_keywords (0.0.5)
data/Rakefile CHANGED
@@ -60,10 +60,10 @@ module Releaser
60
60
 
61
61
  sh "git add lib/rubocop/sorbet/version.rb config/default.yml Gemfile.lock VERSION manual"
62
62
 
63
- puts "git commit -m 'Release #{version}'"
64
- puts "git push origin main"
65
- puts "git tag -a v#{version} -m 'Release #{version}'"
66
- puts "git push origin v#{version}"
63
+ sh "git commit -m 'Release v#{version}'"
64
+ sh "git push origin main"
65
+ sh "git tag -a v#{version} -m 'Release v#{version}'"
66
+ sh "git push origin v#{version}"
67
67
  end
68
68
 
69
69
  private
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.10.2
1
+ 0.10.3
data/config/default.yml CHANGED
@@ -23,6 +23,7 @@ Sorbet/BlockMethodDefinition:
23
23
  Safe: true
24
24
  SafeAutoCorrect: false
25
25
  VersionAdded: '0.10.1'
26
+ VersionChanged: '0.10.3'
26
27
 
27
28
  Sorbet/BuggyObsoleteStrictMemoization:
28
29
  Description: >-
@@ -47,6 +48,12 @@ Sorbet/CallbackConditionalsBinding:
47
48
  Safe: false
48
49
  VersionAdded: 0.7.0
49
50
 
51
+ Sorbet/CapitalizedTypeParameters:
52
+ Description: 'Ensures that type parameters are capitalized.'
53
+ Enabled: true
54
+ SafeAutoCorrect: false
55
+ VersionAdded: '0.10.3'
56
+
50
57
  Sorbet/CheckedTrueInSignature:
51
58
  Description: 'Disallows the usage of `checked(true)` in signatures.'
52
59
  Enabled: true
@@ -164,6 +171,36 @@ Sorbet/ForbidTStruct:
164
171
  VersionAdded: 0.7.4
165
172
  Safe: false
166
173
 
174
+ Sorbet/ForbidTAbsurd:
175
+ Description: 'Forbid usage of T.absurd.'
176
+ Enabled: false
177
+ VersionAdded: <<next>>
178
+
179
+ Sorbet/ForbidTBind:
180
+ Description: 'Forbid usage of T.bind.'
181
+ Enabled: false
182
+ VersionAdded: <<next>>
183
+
184
+ Sorbet/ForbidTCast:
185
+ Description: 'Forbid usage of T.cast.'
186
+ Enabled: false
187
+ VersionAdded: <<next>>
188
+
189
+ Sorbet/ForbidTLet:
190
+ Description: 'Forbid usage of T.let.'
191
+ Enabled: false
192
+ VersionAdded: <<next>>
193
+
194
+ Sorbet/ForbidTMust:
195
+ Description: 'Forbid usage of T.must.'
196
+ Enabled: false
197
+ VersionAdded: <<next>>
198
+
199
+ Sorbet/ForbidTTypeAlias:
200
+ Description: 'Forbid usage of T.type_alias.'
201
+ Enabled: false
202
+ VersionAdded: <<next>>
203
+
167
204
  Sorbet/ForbidTUnsafe:
168
205
  Description: 'Forbid usage of T.unsafe.'
169
206
  Enabled: false
@@ -10,7 +10,8 @@ module RuboCop
10
10
  #
11
11
  # The one exception is for `Class.new` blocks, as long as the result is
12
12
  # assigned to a constant (i.e. as long as it is not an anonymous class).
13
-
13
+ # Another exception is for ActiveSupport::Concern `class_methods` blocks.
14
+ #
14
15
  # @example
15
16
  # # bad
16
17
  # yielding_method do
@@ -40,17 +41,50 @@ module RuboCop
40
41
  # end
41
42
  # end
42
43
  #
44
+ # # good
45
+ # module SomeConcern
46
+ # extend ActiveSupport::Concern
47
+ #
48
+ # class_methods do
49
+ # def good(args)
50
+ # # ...
51
+ # end
52
+ # end
53
+ # end
54
+ #
43
55
  class BlockMethodDefinition < Base
44
56
  include RuboCop::Cop::Alignment
45
57
  extend AutoCorrector
46
58
 
47
59
  MSG = "Do not define methods in blocks (use `define_method` as a workaround)."
48
60
 
61
+ # @!method activesupport_concern_class_methods_block?(node)
62
+ def_node_matcher :activesupport_concern_class_methods_block?, <<~PATTERN
63
+ (block
64
+ (send nil? :class_methods)
65
+ _
66
+ _
67
+ )
68
+ PATTERN
69
+
70
+ # @!method module_extends_activesupport_concern?(node)
71
+ def_node_matcher :module_extends_activesupport_concern?, <<~PATTERN
72
+ (module _
73
+ (begin
74
+ <(send nil? :extend (const (const {nil? cbase} :ActiveSupport) :Concern)) ...>
75
+ ...
76
+ )
77
+ )
78
+ PATTERN
79
+
49
80
  def on_block(node)
50
81
  if (parent = node.parent)
51
82
  return if parent.casgn_type?
52
83
  end
53
84
 
85
+ # Check if this is a class_methods block inside an ActiveSupport::Concern
86
+ return if in_activesupport_concern_class_methods_block?(node)
87
+
54
88
  node.each_descendant(:any_def) do |def_node|
55
89
  add_offense(def_node) do |corrector|
56
90
  autocorrect_method_in_block(corrector, def_node)
@@ -61,21 +95,108 @@ module RuboCop
61
95
 
62
96
  private
63
97
 
98
+ def in_activesupport_concern_class_methods_block?(node)
99
+ return false unless activesupport_concern_class_methods_block?(node)
100
+
101
+ immediate_module = node.each_ancestor(:module).first
102
+
103
+ module_extends_activesupport_concern?(immediate_module)
104
+ end
105
+
64
106
  def autocorrect_method_in_block(corrector, node)
65
107
  indent = offset(node)
66
108
 
67
109
  method_name = node.method_name
68
- args = node.arguments.map(&:source).join(", ")
69
- body = node.body&.source&.prepend("\n#{indent} ")
110
+ args = transform_args_to_block_args(node)
70
111
 
112
+ # Build the method signature replacement
71
113
  if node.def_type?
72
- replacement = "define_method(:#{method_name}) do |#{args}|#{body}\n#{indent}end"
114
+ signature_replacement = "define_method(:#{method_name}) do#{args}"
73
115
  elsif node.defs_type?
74
116
  receiver = node.receiver.source
75
- replacement = "#{receiver}.define_singleton_method(:#{method_name}) do |#{args}|#{body}\n#{indent}end"
117
+ signature_replacement = "#{receiver}.define_singleton_method(:#{method_name}) do#{args}"
118
+ end
119
+
120
+ if node.body
121
+ end_pos = node.body.source_range.begin_pos
122
+ indentation = "\n#{indent} "
123
+ else
124
+ end_pos, indentation = handle_method_without_body(node, indent)
76
125
  end
77
126
 
78
- corrector.replace(node, replacement)
127
+ signature_range = node.source_range.with(end_pos: end_pos)
128
+
129
+ corrector.replace(signature_range, signature_replacement + indentation)
130
+ end
131
+
132
+ def transform_args_to_block_args(node)
133
+ args = node.arguments
134
+
135
+ if args.empty?
136
+ ""
137
+ else
138
+ args_string = args.map(&:source).join(", ")
139
+ " |#{args_string}|"
140
+ end
141
+ end
142
+
143
+ def handle_method_without_body(node, indent)
144
+ if single_line_method?(node)
145
+ handle_single_line_method(node, indent)
146
+ else
147
+ handle_multiline_method_without_body(node)
148
+ end
149
+ end
150
+
151
+ def single_line_method?(node)
152
+ !node.source.include?("\n")
153
+ end
154
+
155
+ def handle_single_line_method(node, indent)
156
+ end_pos = node.source_range.end_pos
157
+ indentation = "\n#{indent}end"
158
+ [end_pos, indentation]
159
+ end
160
+
161
+ def handle_multiline_method_without_body(node)
162
+ end_pos = find_method_signature_end_position(node)
163
+ indentation = ""
164
+ [end_pos, indentation]
165
+ end
166
+
167
+ def find_method_signature_end_position(node)
168
+ if node.arguments.any?
169
+ find_end_position_with_arguments(node)
170
+ else
171
+ find_end_position_without_arguments(node)
172
+ end
173
+ end
174
+
175
+ def find_end_position_with_arguments(node)
176
+ last_arg = node.last_argument
177
+ end_pos = last_arg.source_range.end_pos
178
+
179
+ adjust_for_closing_parenthesis(end_pos)
180
+ end
181
+
182
+ def find_end_position_without_arguments(node)
183
+ node.loc.name.end_pos
184
+ end
185
+
186
+ def adjust_for_closing_parenthesis(end_pos)
187
+ source_after_last_arg = processed_source.buffer.source[end_pos..-1]
188
+
189
+ match = closing_parenthesis_follows(source_after_last_arg)
190
+
191
+ if match
192
+ end_pos + match.end(0)
193
+ else
194
+ end_pos
195
+ end
196
+ end
197
+
198
+ def closing_parenthesis_follows(source)
199
+ source.match(/\A\s*\)/)
79
200
  end
80
201
  end
81
202
  end
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "rubocop"
4
+
5
+ module RuboCop
6
+ module Cop
7
+ module Sorbet
8
+ # Disallows using `T.absurd` anywhere.
9
+ #
10
+ # @example
11
+ #
12
+ # # bad
13
+ # T.absurd(foo)
14
+ #
15
+ # # good
16
+ # x #: absurd
17
+ class ForbidTAbsurd < RuboCop::Cop::Base
18
+ MSG = "Do not use `T.absurd`."
19
+ RESTRICT_ON_SEND = [:absurd].freeze
20
+
21
+ # @!method t_absurd?(node)
22
+ def_node_matcher(:t_absurd?, "(send (const nil? :T) :absurd _)")
23
+
24
+ def on_send(node)
25
+ add_offense(node) if t_absurd?(node)
26
+ end
27
+ alias_method :on_csend, :on_send
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "rubocop"
4
+
5
+ module RuboCop
6
+ module Cop
7
+ module Sorbet
8
+ # Disallows using `T.bind` anywhere.
9
+ #
10
+ # @example
11
+ #
12
+ # # bad
13
+ # T.bind(self, Integer)
14
+ #
15
+ # # good
16
+ # #: self as Integer
17
+ class ForbidTBind < RuboCop::Cop::Base
18
+ MSG = "Do not use `T.bind`."
19
+ RESTRICT_ON_SEND = [:bind].freeze
20
+
21
+ # @!method t_bind?(node)
22
+ def_node_matcher(:t_bind?, "(send (const nil? :T) :bind _ _)")
23
+
24
+ def on_send(node)
25
+ add_offense(node) if t_bind?(node)
26
+ end
27
+ alias_method :on_csend, :on_send
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "rubocop"
4
+
5
+ module RuboCop
6
+ module Cop
7
+ module Sorbet
8
+ # Disallows using `T.cast` anywhere.
9
+ #
10
+ # @example
11
+ #
12
+ # # bad
13
+ # T.cast(foo, Integer)
14
+ #
15
+ # # good
16
+ # foo #: as Integer
17
+ class ForbidTCast < RuboCop::Cop::Base
18
+ MSG = "Do not use `T.cast`."
19
+ RESTRICT_ON_SEND = [:cast].freeze
20
+
21
+ # @!method t_cast?(node)
22
+ def_node_matcher(:t_cast?, "(send (const nil? :T) :cast _ _)")
23
+
24
+ def on_send(node)
25
+ add_offense(node) if t_cast?(node)
26
+ end
27
+ alias_method :on_csend, :on_send
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "rubocop"
4
+
5
+ module RuboCop
6
+ module Cop
7
+ module Sorbet
8
+ # Disallows using `T.let` anywhere.
9
+ #
10
+ # @example
11
+ #
12
+ # # bad
13
+ # T.let(foo, Integer)
14
+ #
15
+ # # good
16
+ # foo #: Integer
17
+ class ForbidTLet < RuboCop::Cop::Base
18
+ MSG = "Do not use `T.let`."
19
+ RESTRICT_ON_SEND = [:let].freeze
20
+
21
+ # @!method t_let?(node)
22
+ def_node_matcher(:t_let?, "(send (const nil? :T) :let _ _)")
23
+
24
+ def on_send(node)
25
+ add_offense(node) if t_let?(node)
26
+ end
27
+ alias_method :on_csend, :on_send
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "rubocop"
4
+
5
+ module RuboCop
6
+ module Cop
7
+ module Sorbet
8
+ # Disallows using `T.must` anywhere.
9
+ #
10
+ # @example
11
+ #
12
+ # # bad
13
+ # T.must(foo)
14
+ #
15
+ # # good
16
+ # foo #: as !nil
17
+ class ForbidTMust < RuboCop::Cop::Base
18
+ MSG = "Do not use `T.must`."
19
+ RESTRICT_ON_SEND = [:must].freeze
20
+
21
+ # @!method t_must?(node)
22
+ def_node_matcher(:t_must?, "(send (const nil? :T) :must _)")
23
+
24
+ def on_send(node)
25
+ add_offense(node) if t_must?(node)
26
+ end
27
+ alias_method :on_csend, :on_send
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "rubocop"
4
+
5
+ module RuboCop
6
+ module Cop
7
+ module Sorbet
8
+ # Disallows using `T.type_alias` anywhere.
9
+ #
10
+ # @example
11
+ #
12
+ # # bad
13
+ # STRING_OR_INTEGER = T.type_alias { T.any(Integer, String) }
14
+ #
15
+ # # good
16
+ # #: type string_or_integer = Integer | String
17
+ class ForbidTTypeAlias < RuboCop::Cop::Base
18
+ MSG = "Do not use `T.type_alias`."
19
+
20
+ # @!method t_type_alias?(node)
21
+ def_node_matcher(:t_type_alias?, "(block (call (const nil? :T) :type_alias) _ _)")
22
+
23
+ def on_block(node)
24
+ add_offense(node) if t_type_alias?(node)
25
+ end
26
+ alias_method :on_numblock, :on_block
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,70 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module Sorbet
6
+ # Ensure type parameters used in generic methods are always capitalized.
7
+ #
8
+ # @example
9
+ #
10
+ # # bad
11
+ # sig { type_parameters(:x).params(a: T.type_parameter(:x)).void }
12
+ # def foo(a); end
13
+ #
14
+ # # good
15
+ # sig { type_parameters(:X).params(a: T.type_parameter(:X)).void }
16
+ # def foo(a: 1); end
17
+ class CapitalizedTypeParameters < ::RuboCop::Cop::Base
18
+ extend AutoCorrector
19
+ include SignatureHelp
20
+
21
+ MSG = "Type parameters must be capitalized."
22
+
23
+ RESTRICT_ON_SEND = [:type_parameter].freeze
24
+
25
+ # @!method type_parameters?(node)
26
+ def_node_matcher(:type_parameters?, <<-PATTERN)
27
+ (send nil? :type_parameters ...)
28
+ PATTERN
29
+
30
+ # @!method t_type_parameter?(node)
31
+ def_node_matcher(:t_type_parameter?, <<-PATTERN)
32
+ (send (const {nil? | cbase} :T) :type_parameter ...)
33
+ PATTERN
34
+
35
+ def on_signature(node)
36
+ send = node.children[2]
37
+
38
+ while send&.send_type?
39
+ if type_parameters?(send)
40
+ check_type_parameters_case(send)
41
+ end
42
+
43
+ send = send.children[0]
44
+ end
45
+ end
46
+
47
+ def on_send(node)
48
+ check_type_parameters_case(node) if t_type_parameter?(node)
49
+ end
50
+
51
+ def on_csend(node)
52
+ check_type_parameters_case(node) if t_type_parameter?(node)
53
+ end
54
+
55
+ private
56
+
57
+ def check_type_parameters_case(node)
58
+ node.children[2..].each do |arg|
59
+ next unless arg.is_a?(RuboCop::AST::SymbolNode)
60
+ next if arg.value =~ /^[A-Z]/
61
+
62
+ add_offense(arg) do |corrector|
63
+ corrector.replace(arg, arg.value.capitalize.to_sym.inspect)
64
+ end
65
+ end
66
+ end
67
+ end
68
+ end
69
+ end
70
+ end
@@ -14,8 +14,14 @@ require_relative "sorbet/forbid_type_aliased_shapes"
14
14
  require_relative "sorbet/forbid_untyped_struct_props"
15
15
  require_relative "sorbet/implicit_conversion_method"
16
16
  require_relative "sorbet/callback_conditionals_binding"
17
+ require_relative "sorbet/forbid_t_absurd"
18
+ require_relative "sorbet/forbid_t_bind"
19
+ require_relative "sorbet/forbid_t_cast"
17
20
  require_relative "sorbet/forbid_t_enum"
21
+ require_relative "sorbet/forbid_t_let"
22
+ require_relative "sorbet/forbid_t_must"
18
23
  require_relative "sorbet/forbid_t_struct"
24
+ require_relative "sorbet/forbid_t_type_alias"
19
25
  require_relative "sorbet/forbid_t_unsafe"
20
26
  require_relative "sorbet/forbid_t_untyped"
21
27
  require_relative "sorbet/redundant_extend_t_sig"
@@ -33,6 +39,7 @@ require_relative "sorbet/rbi_versioning/gem_version_annotation_helper"
33
39
  require_relative "sorbet/rbi_versioning/valid_gem_version_annotations"
34
40
 
35
41
  require_relative "sorbet/signatures/allow_incompatible_override"
42
+ require_relative "sorbet/signatures/capitalized_type_parameters"
36
43
  require_relative "sorbet/signatures/checked_true_in_signature"
37
44
  require_relative "sorbet/signatures/empty_line_after_sig"
38
45
  require_relative "sorbet/signatures/enforce_signatures"
@@ -2,6 +2,6 @@
2
2
 
3
3
  module RuboCop
4
4
  module Sorbet
5
- VERSION = "0.10.2"
5
+ VERSION = "0.10.4"
6
6
  end
7
7
  end
data/manual/cops.md CHANGED
@@ -10,6 +10,7 @@ In the following section you find all available cops:
10
10
  * [Sorbet/BlockMethodDefinition](cops_sorbet.md#sorbetblockmethoddefinition)
11
11
  * [Sorbet/BuggyObsoleteStrictMemoization](cops_sorbet.md#sorbetbuggyobsoletestrictmemoization)
12
12
  * [Sorbet/CallbackConditionalsBinding](cops_sorbet.md#sorbetcallbackconditionalsbinding)
13
+ * [Sorbet/CapitalizedTypeParameters](cops_sorbet.md#sorbetcapitalizedtypeparameters)
13
14
  * [Sorbet/CheckedTrueInSignature](cops_sorbet.md#sorbetcheckedtrueinsignature)
14
15
  * [Sorbet/ConstantsFromStrings](cops_sorbet.md#sorbetconstantsfromstrings)
15
16
  * [Sorbet/EmptyLineAfterSig](cops_sorbet.md#sorbetemptylineaftersig)
@@ -26,8 +27,14 @@ In the following section you find all available cops:
26
27
  * [Sorbet/ForbidSigWithRuntime](cops_sorbet.md#sorbetforbidsigwithruntime)
27
28
  * [Sorbet/ForbidSigWithoutRuntime](cops_sorbet.md#sorbetforbidsigwithoutruntime)
28
29
  * [Sorbet/ForbidSuperclassConstLiteral](cops_sorbet.md#sorbetforbidsuperclassconstliteral)
30
+ * [Sorbet/ForbidTAbsurd](cops_sorbet.md#sorbetforbidtabsurd)
31
+ * [Sorbet/ForbidTBind](cops_sorbet.md#sorbetforbidtbind)
32
+ * [Sorbet/ForbidTCast](cops_sorbet.md#sorbetforbidtcast)
29
33
  * [Sorbet/ForbidTEnum](cops_sorbet.md#sorbetforbidtenum)
34
+ * [Sorbet/ForbidTLet](cops_sorbet.md#sorbetforbidtlet)
35
+ * [Sorbet/ForbidTMust](cops_sorbet.md#sorbetforbidtmust)
30
36
  * [Sorbet/ForbidTStruct](cops_sorbet.md#sorbetforbidtstruct)
37
+ * [Sorbet/ForbidTTypeAlias](cops_sorbet.md#sorbetforbidttypealias)
31
38
  * [Sorbet/ForbidTUnsafe](cops_sorbet.md#sorbetforbidtunsafe)
32
39
  * [Sorbet/ForbidTUntyped](cops_sorbet.md#sorbetforbidtuntyped)
33
40
  * [Sorbet/ForbidTypeAliasedShapes](cops_sorbet.md#sorbetforbidtypealiasedshapes)
@@ -45,9 +45,16 @@ FooOrBar = T.type_alias { T.any(Foo, Bar) }
45
45
 
46
46
  Enabled by default | Safe | Supports autocorrection | VersionAdded | VersionChanged
47
47
  --- | --- | --- | --- | ---
48
- Enabled | Yes | Yes (Unsafe) | 0.10.1 | -
48
+ Enabled | Yes | Yes (Unsafe) | 0.10.1 | 0.10.3
49
49
 
50
+ Disallow defining methods in blocks, to prevent running into issues
51
+ caused by https://github.com/sorbet/sorbet/issues/3609.
50
52
 
53
+ As a workaround, use `define_method` instead.
54
+
55
+ The one exception is for `Class.new` blocks, as long as the result is
56
+ assigned to a constant (i.e. as long as it is not an anonymous class).
57
+ Another exception is for ActiveSupport::Concern `class_methods` blocks.
51
58
 
52
59
  ### Examples
53
60
 
@@ -79,6 +86,17 @@ MyClass = Class.new do
79
86
  # ...
80
87
  end
81
88
  end
89
+
90
+ # good
91
+ module SomeConcern
92
+ extend ActiveSupport::Concern
93
+
94
+ class_methods do
95
+ def good(args)
96
+ # ...
97
+ end
98
+ end
99
+ end
82
100
  ```
83
101
 
84
102
  ## Sorbet/BuggyObsoleteStrictMemoization
@@ -157,6 +175,26 @@ class Post < ApplicationRecord
157
175
  end
158
176
  ```
159
177
 
178
+ ## Sorbet/CapitalizedTypeParameters
179
+
180
+ Enabled by default | Safe | Supports autocorrection | VersionAdded | VersionChanged
181
+ --- | --- | --- | --- | ---
182
+ Enabled | Yes | Yes (Unsafe) | 0.10.3 | -
183
+
184
+ Ensure type parameters used in generic methods are always capitalized.
185
+
186
+ ### Examples
187
+
188
+ ```ruby
189
+ # bad
190
+ sig { type_parameters(:x).params(a: T.type_parameter(:x)).void }
191
+ def foo(a); end
192
+
193
+ # good
194
+ sig { type_parameters(:X).params(a: T.type_parameter(:X)).void }
195
+ def foo(a: 1); end
196
+ ```
197
+
160
198
  ## Sorbet/CheckedTrueInSignature
161
199
 
162
200
  Enabled by default | Safe | Supports autocorrection | VersionAdded | VersionChanged
@@ -594,6 +632,60 @@ Name | Default value | Configurable values
594
632
  --- | --- | ---
595
633
  Exclude | `db/migrate/*.rb` | Array
596
634
 
635
+ ## Sorbet/ForbidTAbsurd
636
+
637
+ Enabled by default | Safe | Supports autocorrection | VersionAdded | VersionChanged
638
+ --- | --- | --- | --- | ---
639
+ Disabled | Yes | No | <<next>> | -
640
+
641
+ Disallows using `T.absurd` anywhere.
642
+
643
+ ### Examples
644
+
645
+ ```ruby
646
+ # bad
647
+ T.absurd(foo)
648
+
649
+ # good
650
+ x #: absurd
651
+ ```
652
+
653
+ ## Sorbet/ForbidTBind
654
+
655
+ Enabled by default | Safe | Supports autocorrection | VersionAdded | VersionChanged
656
+ --- | --- | --- | --- | ---
657
+ Disabled | Yes | No | <<next>> | -
658
+
659
+ Disallows using `T.bind` anywhere.
660
+
661
+ ### Examples
662
+
663
+ ```ruby
664
+ # bad
665
+ T.bind(self, Integer)
666
+
667
+ # good
668
+ #: self as Integer
669
+ ```
670
+
671
+ ## Sorbet/ForbidTCast
672
+
673
+ Enabled by default | Safe | Supports autocorrection | VersionAdded | VersionChanged
674
+ --- | --- | --- | --- | ---
675
+ Disabled | Yes | No | <<next>> | -
676
+
677
+ Disallows using `T.cast` anywhere.
678
+
679
+ ### Examples
680
+
681
+ ```ruby
682
+ # bad
683
+ T.cast(foo, Integer)
684
+
685
+ # good
686
+ foo #: as Integer
687
+ ```
688
+
597
689
  ## Sorbet/ForbidTEnum
598
690
 
599
691
  Enabled by default | Safe | Supports autocorrection | VersionAdded | VersionChanged
@@ -621,6 +713,42 @@ class MyEnum
621
713
  end
622
714
  ```
623
715
 
716
+ ## Sorbet/ForbidTLet
717
+
718
+ Enabled by default | Safe | Supports autocorrection | VersionAdded | VersionChanged
719
+ --- | --- | --- | --- | ---
720
+ Disabled | Yes | No | <<next>> | -
721
+
722
+ Disallows using `T.let` anywhere.
723
+
724
+ ### Examples
725
+
726
+ ```ruby
727
+ # bad
728
+ T.let(foo, Integer)
729
+
730
+ # good
731
+ foo #: Integer
732
+ ```
733
+
734
+ ## Sorbet/ForbidTMust
735
+
736
+ Enabled by default | Safe | Supports autocorrection | VersionAdded | VersionChanged
737
+ --- | --- | --- | --- | ---
738
+ Disabled | Yes | No | <<next>> | -
739
+
740
+ Disallows using `T.must` anywhere.
741
+
742
+ ### Examples
743
+
744
+ ```ruby
745
+ # bad
746
+ T.must(foo)
747
+
748
+ # good
749
+ foo #: as !nil
750
+ ```
751
+
624
752
  ## Sorbet/ForbidTStruct
625
753
 
626
754
  Enabled by default | Safe | Supports autocorrection | VersionAdded | VersionChanged
@@ -660,6 +788,24 @@ class MyStruct
660
788
  end
661
789
  ```
662
790
 
791
+ ## Sorbet/ForbidTTypeAlias
792
+
793
+ Enabled by default | Safe | Supports autocorrection | VersionAdded | VersionChanged
794
+ --- | --- | --- | --- | ---
795
+ Disabled | Yes | No | <<next>> | -
796
+
797
+ Disallows using `T.type_alias` anywhere.
798
+
799
+ ### Examples
800
+
801
+ ```ruby
802
+ # bad
803
+ STRING_OR_INTEGER = T.type_alias { T.any(Integer, String) }
804
+
805
+ # good
806
+ #: type string_or_integer = Integer | String
807
+ ```
808
+
663
809
  ## Sorbet/ForbidTUnsafe
664
810
 
665
811
  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.10.2
4
+ version: 0.10.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ufuk Kayserilioglu
@@ -84,8 +84,14 @@ files:
84
84
  - lib/rubocop/cop/sorbet/forbid_include_const_literal.rb
85
85
  - lib/rubocop/cop/sorbet/forbid_mixes_in_class_methods.rb
86
86
  - lib/rubocop/cop/sorbet/forbid_superclass_const_literal.rb
87
+ - lib/rubocop/cop/sorbet/forbid_t_absurd.rb
88
+ - lib/rubocop/cop/sorbet/forbid_t_bind.rb
89
+ - lib/rubocop/cop/sorbet/forbid_t_cast.rb
87
90
  - lib/rubocop/cop/sorbet/forbid_t_enum.rb
91
+ - lib/rubocop/cop/sorbet/forbid_t_let.rb
92
+ - lib/rubocop/cop/sorbet/forbid_t_must.rb
88
93
  - lib/rubocop/cop/sorbet/forbid_t_struct.rb
94
+ - lib/rubocop/cop/sorbet/forbid_t_type_alias.rb
89
95
  - lib/rubocop/cop/sorbet/forbid_t_unsafe.rb
90
96
  - lib/rubocop/cop/sorbet/forbid_t_untyped.rb
91
97
  - lib/rubocop/cop/sorbet/forbid_type_aliased_shapes.rb
@@ -114,6 +120,7 @@ files:
114
120
  - lib/rubocop/cop/sorbet/sigils/true_sigil.rb
115
121
  - lib/rubocop/cop/sorbet/sigils/valid_sigil.rb
116
122
  - lib/rubocop/cop/sorbet/signatures/allow_incompatible_override.rb
123
+ - lib/rubocop/cop/sorbet/signatures/capitalized_type_parameters.rb
117
124
  - lib/rubocop/cop/sorbet/signatures/checked_true_in_signature.rb
118
125
  - lib/rubocop/cop/sorbet/signatures/empty_line_after_sig.rb
119
126
  - lib/rubocop/cop/sorbet/signatures/enforce_signatures.rb