rubocop-sorbet 0.10.0 → 0.10.2
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 +4 -4
- data/.devcontainer/devcontainer.json +25 -0
- data/.github/workflows/ci.yml +5 -5
- data/.github/workflows/dependabot_automerge.yml +2 -2
- data/.github/workflows/stale.yml +1 -1
- data/.rubocop.yml +2 -2
- data/.ruby-version +1 -1
- data/CONTRIBUTING.md +29 -0
- data/Gemfile +3 -1
- data/Gemfile.lock +24 -27
- data/README.md +2 -16
- data/Rakefile +44 -5
- data/VERSION +1 -0
- data/bin/{rspec → rake} +5 -9
- data/config/default.yml +88 -64
- data/dev.yml +1 -1
- data/lib/rubocop/cop/sorbet/block_method_definition.rb +83 -0
- data/lib/rubocop/cop/sorbet/forbid_mixes_in_class_methods.rb +49 -0
- data/lib/rubocop/cop/sorbet/select_by_is_a.rb +62 -0
- data/lib/rubocop/cop/sorbet/sigils/enforce_single_sigil.rb +1 -1
- data/lib/rubocop/cop/sorbet/sigils/valid_sigil.rb +20 -2
- data/lib/rubocop/cop/sorbet/signatures/empty_line_after_sig.rb +20 -11
- data/lib/rubocop/cop/sorbet_cops.rb +3 -0
- data/lib/rubocop/sorbet/version.rb +1 -1
- data/manual/cops.md +3 -0
- data/manual/cops_sorbet.md +102 -8
- data/rubocop-sorbet.gemspec +3 -2
- metadata +27 -8
- data/.travis.yml +0 -12
@@ -0,0 +1,83 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module Sorbet
|
6
|
+
# Disallow defining methods in blocks, to prevent running into issues
|
7
|
+
# caused by https://github.com/sorbet/sorbet/issues/3609.
|
8
|
+
#
|
9
|
+
# As a workaround, use `define_method` instead.
|
10
|
+
#
|
11
|
+
# The one exception is for `Class.new` blocks, as long as the result is
|
12
|
+
# assigned to a constant (i.e. as long as it is not an anonymous class).
|
13
|
+
|
14
|
+
# @example
|
15
|
+
# # bad
|
16
|
+
# yielding_method do
|
17
|
+
# def bad(args)
|
18
|
+
# # ...
|
19
|
+
# end
|
20
|
+
# end
|
21
|
+
#
|
22
|
+
# # bad
|
23
|
+
# Class.new do
|
24
|
+
# def bad(args)
|
25
|
+
# # ...
|
26
|
+
# end
|
27
|
+
# end
|
28
|
+
#
|
29
|
+
# # good
|
30
|
+
# yielding_method do
|
31
|
+
# define_method(:good) do |args|
|
32
|
+
# # ...
|
33
|
+
# end
|
34
|
+
# end
|
35
|
+
#
|
36
|
+
# # good
|
37
|
+
# MyClass = Class.new do
|
38
|
+
# def good(args)
|
39
|
+
# # ...
|
40
|
+
# end
|
41
|
+
# end
|
42
|
+
#
|
43
|
+
class BlockMethodDefinition < Base
|
44
|
+
include RuboCop::Cop::Alignment
|
45
|
+
extend AutoCorrector
|
46
|
+
|
47
|
+
MSG = "Do not define methods in blocks (use `define_method` as a workaround)."
|
48
|
+
|
49
|
+
def on_block(node)
|
50
|
+
if (parent = node.parent)
|
51
|
+
return if parent.casgn_type?
|
52
|
+
end
|
53
|
+
|
54
|
+
node.each_descendant(:any_def) do |def_node|
|
55
|
+
add_offense(def_node) do |corrector|
|
56
|
+
autocorrect_method_in_block(corrector, def_node)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
alias_method :on_numblock, :on_block
|
61
|
+
|
62
|
+
private
|
63
|
+
|
64
|
+
def autocorrect_method_in_block(corrector, node)
|
65
|
+
indent = offset(node)
|
66
|
+
|
67
|
+
method_name = node.method_name
|
68
|
+
args = node.arguments.map(&:source).join(", ")
|
69
|
+
body = node.body&.source&.prepend("\n#{indent} ")
|
70
|
+
|
71
|
+
if node.def_type?
|
72
|
+
replacement = "define_method(:#{method_name}) do |#{args}|#{body}\n#{indent}end"
|
73
|
+
elsif node.defs_type?
|
74
|
+
receiver = node.receiver.source
|
75
|
+
replacement = "#{receiver}.define_singleton_method(:#{method_name}) do |#{args}|#{body}\n#{indent}end"
|
76
|
+
end
|
77
|
+
|
78
|
+
corrector.replace(node, replacement)
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module Sorbet
|
6
|
+
# Check that code does not call `mixes_in_class_methods` from Sorbet `T::Helpers`.
|
7
|
+
#
|
8
|
+
# Good:
|
9
|
+
#
|
10
|
+
# ```
|
11
|
+
# module M
|
12
|
+
# extend ActiveSupport::Concern
|
13
|
+
#
|
14
|
+
# class_methods do
|
15
|
+
# ...
|
16
|
+
# end
|
17
|
+
# end
|
18
|
+
# ```
|
19
|
+
#
|
20
|
+
# Bad:
|
21
|
+
#
|
22
|
+
# ```
|
23
|
+
# module M
|
24
|
+
# extend T::Helpers
|
25
|
+
#
|
26
|
+
# module ClassMethods
|
27
|
+
# ...
|
28
|
+
# end
|
29
|
+
#
|
30
|
+
# mixes_in_class_methods(ClassMethods)
|
31
|
+
# end
|
32
|
+
# ```
|
33
|
+
class ForbidMixesInClassMethods < ::RuboCop::Cop::Base
|
34
|
+
MSG = "Do not use `mixes_in_class_methods`, use `extend ActiveSupport::Concern` instead."
|
35
|
+
RESTRICT_ON_SEND = [:mixes_in_class_methods].freeze
|
36
|
+
|
37
|
+
# @!method mixes_in_class_methods?(node)
|
38
|
+
def_node_matcher(:mixes_in_class_methods?, <<~PATTERN)
|
39
|
+
(send {self | nil? | (const (const {cbase | nil?} :T) :Helpers)} :mixes_in_class_methods ...)
|
40
|
+
PATTERN
|
41
|
+
|
42
|
+
def on_send(node)
|
43
|
+
add_offense(node) if mixes_in_class_methods?(node)
|
44
|
+
end
|
45
|
+
alias_method :on_csend, :on_send
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "rubocop"
|
4
|
+
|
5
|
+
module RuboCop
|
6
|
+
module Cop
|
7
|
+
module Sorbet
|
8
|
+
# Suggests using `grep` over `select` when using it only for type narrowing.
|
9
|
+
#
|
10
|
+
# @example
|
11
|
+
#
|
12
|
+
# # bad
|
13
|
+
# strings_or_integers.select { |e| e.is_a?(String) }
|
14
|
+
# strings_or_integers.filter { |e| e.is_a?(String) }
|
15
|
+
# strings_or_integers.select { |e| e.kind_of?(String) }
|
16
|
+
#
|
17
|
+
# # good
|
18
|
+
# strings_or_integers.grep(String)
|
19
|
+
class SelectByIsA < RuboCop::Cop::Base
|
20
|
+
extend AutoCorrector
|
21
|
+
|
22
|
+
MSG = "Use `grep` instead of `select` when using it only for type narrowing."
|
23
|
+
RESTRICT_ON_SEND = [:select, :filter].freeze
|
24
|
+
|
25
|
+
# @!method type_narrowing_select?(node)
|
26
|
+
def_node_matcher :type_narrowing_select?, <<~PATTERN
|
27
|
+
{
|
28
|
+
(block
|
29
|
+
(call _ {:select :filter})
|
30
|
+
(args (arg _))
|
31
|
+
(send (lvar _) { :is_a? :kind_of? } (const nil? _)))
|
32
|
+
(numblock
|
33
|
+
(call _ {:select :filter})
|
34
|
+
_
|
35
|
+
(send (lvar _) { :is_a? :kind_of? } (const nil? _)))
|
36
|
+
(itblock
|
37
|
+
(call _ {:select :filter})
|
38
|
+
_
|
39
|
+
(send (lvar _) { :is_a? :kind_of? } (const nil? _)))
|
40
|
+
}
|
41
|
+
PATTERN
|
42
|
+
|
43
|
+
def on_send(node)
|
44
|
+
block_node = node.block_node
|
45
|
+
|
46
|
+
return unless block_node
|
47
|
+
return unless type_narrowing_select?(block_node)
|
48
|
+
|
49
|
+
add_offense(block_node) do |corrector|
|
50
|
+
receiver = node.receiver
|
51
|
+
type_class = block_node.body.children[2]
|
52
|
+
navigation = node.csend_type? ? "&." : "."
|
53
|
+
replacement = "#{receiver.source}#{navigation}grep(#{type_class.source})"
|
54
|
+
|
55
|
+
corrector.replace(block_node, replacement)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
alias_method :on_csend, :on_send
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
@@ -54,7 +54,7 @@ module RuboCop
|
|
54
54
|
# The first sigil encountered represents the "real" strictness so remove any below
|
55
55
|
sigils[1..sigils.size].each do |token|
|
56
56
|
corrector.remove(
|
57
|
-
source_range(processed_source.buffer, token.line,
|
57
|
+
source_range(processed_source.buffer, token.line, 0..token.pos.last_column),
|
58
58
|
)
|
59
59
|
end
|
60
60
|
end
|
@@ -28,6 +28,8 @@ module RuboCop
|
|
28
28
|
return unless check_sigil_present(sigil)
|
29
29
|
|
30
30
|
strictness = extract_strictness(sigil)
|
31
|
+
check_double_commented_sigil(sigil, strictness)
|
32
|
+
|
31
33
|
return unless check_strictness_not_empty(sigil, strictness)
|
32
34
|
return unless check_strictness_valid(sigil, strictness)
|
33
35
|
|
@@ -37,7 +39,8 @@ module RuboCop
|
|
37
39
|
protected
|
38
40
|
|
39
41
|
STRICTNESS_LEVELS = ["ignore", "false", "true", "strict", "strong"]
|
40
|
-
SIGIL_REGEX = /^[[:blank:]]
|
42
|
+
SIGIL_REGEX = /^[[:blank:]]*(?:#[[:blank:]]*)?#[[:blank:]]+typed:(?:[[:blank:]]+([\S]+))?/
|
43
|
+
INVALID_SIGIL_MSG = "Invalid Sorbet sigil `%<sigil>s`."
|
41
44
|
|
42
45
|
# extraction
|
43
46
|
|
@@ -104,12 +107,27 @@ module RuboCop
|
|
104
107
|
false
|
105
108
|
end
|
106
109
|
|
110
|
+
def check_double_commented_sigil(sigil, strictness)
|
111
|
+
return unless sigil.text.start_with?(/[[:blank:]]*#[[:blank:]]*#/)
|
112
|
+
|
113
|
+
add_offense(
|
114
|
+
sigil.pos,
|
115
|
+
message: format(INVALID_SIGIL_MSG, sigil: sigil.text),
|
116
|
+
) do |corrector|
|
117
|
+
# Remove the extra comment and normalize spaces
|
118
|
+
corrector.replace(
|
119
|
+
sigil.pos,
|
120
|
+
"# typed: #{strictness}",
|
121
|
+
)
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
107
125
|
def check_strictness_valid(sigil, strictness)
|
108
126
|
return true if STRICTNESS_LEVELS.include?(strictness)
|
109
127
|
|
110
128
|
add_offense(
|
111
129
|
sigil.pos,
|
112
|
-
message:
|
130
|
+
message: format(INVALID_SIGIL_MSG, sigil: strictness),
|
113
131
|
) do |corrector|
|
114
132
|
autocorrect(corrector)
|
115
133
|
end
|
@@ -24,9 +24,8 @@ module RuboCop
|
|
24
24
|
# @!method sig_or_signable_method_definition?(node)
|
25
25
|
def_node_matcher :sig_or_signable_method_definition?, <<~PATTERN
|
26
26
|
${
|
27
|
-
|
28
|
-
|
29
|
-
(send nil? {:attr_reader :attr_writer :attr_accessor} ...)
|
27
|
+
any_def
|
28
|
+
(send nil? {:attr :attr_reader :attr_writer :attr_accessor} ...)
|
30
29
|
#signature?
|
31
30
|
}
|
32
31
|
PATTERN
|
@@ -34,16 +33,22 @@ module RuboCop
|
|
34
33
|
def on_signature(sig)
|
35
34
|
sig_or_signable_method_definition?(next_sibling(sig)) do |definition|
|
36
35
|
range = lines_between(sig, definition)
|
37
|
-
next if range.empty? || range.single_line?
|
36
|
+
next if range.empty? || range.single_line? || contains_only_rubocop_directives?(range)
|
38
37
|
|
39
38
|
add_offense(range) do |corrector|
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
39
|
+
lines = range.source.lines
|
40
|
+
rubocop_lines, other_lines = lines.partition { |line| line.strip.start_with?("# rubocop:") }
|
41
|
+
|
42
|
+
unless other_lines.empty?
|
43
|
+
corrector.insert_before(
|
44
|
+
range_by_whole_lines(sig.source_range),
|
45
|
+
other_lines.join
|
46
|
+
.sub(/\A\n+/, "") # remove initial newline(s)
|
47
|
+
.gsub(/\n{2,}/, "\n"), # remove empty line(s)
|
48
|
+
)
|
49
|
+
end
|
50
|
+
|
51
|
+
corrector.replace(range, rubocop_lines.empty? ? "" : rubocop_lines.join)
|
47
52
|
end
|
48
53
|
end
|
49
54
|
end
|
@@ -54,6 +59,10 @@ module RuboCop
|
|
54
59
|
node.parent&.children&.at(node.sibling_index + 1)
|
55
60
|
end
|
56
61
|
|
62
|
+
def contains_only_rubocop_directives?(range)
|
63
|
+
range.source.lines.all? { |line| line.strip.start_with?("# rubocop:") }
|
64
|
+
end
|
65
|
+
|
57
66
|
def lines_between(node1, node2, buffer: processed_source.buffer)
|
58
67
|
end_of_node1_pos = node1.source_range.end_pos
|
59
68
|
start_of_node2_pos = node2.source_range.begin_pos
|
@@ -5,9 +5,11 @@ require_relative "sorbet/mixin/t_enum"
|
|
5
5
|
require_relative "sorbet/mixin/signature_help"
|
6
6
|
|
7
7
|
require_relative "sorbet/binding_constant_without_type_alias"
|
8
|
+
require_relative "sorbet/block_method_definition"
|
8
9
|
require_relative "sorbet/constants_from_strings"
|
9
10
|
require_relative "sorbet/forbid_superclass_const_literal"
|
10
11
|
require_relative "sorbet/forbid_include_const_literal"
|
12
|
+
require_relative "sorbet/forbid_mixes_in_class_methods"
|
11
13
|
require_relative "sorbet/forbid_type_aliased_shapes"
|
12
14
|
require_relative "sorbet/forbid_untyped_struct_props"
|
13
15
|
require_relative "sorbet/implicit_conversion_method"
|
@@ -18,6 +20,7 @@ require_relative "sorbet/forbid_t_unsafe"
|
|
18
20
|
require_relative "sorbet/forbid_t_untyped"
|
19
21
|
require_relative "sorbet/redundant_extend_t_sig"
|
20
22
|
require_relative "sorbet/refinement"
|
23
|
+
require_relative "sorbet/select_by_is_a"
|
21
24
|
require_relative "sorbet/type_alias_name"
|
22
25
|
require_relative "sorbet/obsolete_strict_memoization"
|
23
26
|
require_relative "sorbet/buggy_obsolete_strict_memoization"
|
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/BlockMethodDefinition](cops_sorbet.md#sorbetblockmethoddefinition)
|
10
11
|
* [Sorbet/BuggyObsoleteStrictMemoization](cops_sorbet.md#sorbetbuggyobsoletestrictmemoization)
|
11
12
|
* [Sorbet/CallbackConditionalsBinding](cops_sorbet.md#sorbetcallbackconditionalsbinding)
|
12
13
|
* [Sorbet/CheckedTrueInSignature](cops_sorbet.md#sorbetcheckedtrueinsignature)
|
@@ -19,6 +20,7 @@ In the following section you find all available cops:
|
|
19
20
|
* [Sorbet/ForbidComparableTEnum](cops_sorbet.md#sorbetforbidcomparabletenum)
|
20
21
|
* [Sorbet/ForbidExtendTSigHelpersInShims](cops_sorbet.md#sorbetforbidextendtsighelpersinshims)
|
21
22
|
* [Sorbet/ForbidIncludeConstLiteral](cops_sorbet.md#sorbetforbidincludeconstliteral)
|
23
|
+
* [Sorbet/ForbidMixesInClassMethods](cops_sorbet.md#sorbetforbidmixesinclassmethods)
|
22
24
|
* [Sorbet/ForbidRBIOutsideOfAllowedPaths](cops_sorbet.md#sorbetforbidrbioutsideofallowedpaths)
|
23
25
|
* [Sorbet/ForbidSig](cops_sorbet.md#sorbetforbidsig)
|
24
26
|
* [Sorbet/ForbidSigWithRuntime](cops_sorbet.md#sorbetforbidsigwithruntime)
|
@@ -38,6 +40,7 @@ In the following section you find all available cops:
|
|
38
40
|
* [Sorbet/ObsoleteStrictMemoization](cops_sorbet.md#sorbetobsoletestrictmemoization)
|
39
41
|
* [Sorbet/RedundantExtendTSig](cops_sorbet.md#sorbetredundantextendtsig)
|
40
42
|
* [Sorbet/Refinement](cops_sorbet.md#sorbetrefinement)
|
43
|
+
* [Sorbet/SelectByIsA](cops_sorbet.md#sorbetselectbyisa)
|
41
44
|
* [Sorbet/SignatureBuildOrder](cops_sorbet.md#sorbetsignaturebuildorder)
|
42
45
|
* [Sorbet/SingleLineRbiClassModuleDefinitions](cops_sorbet.md#sorbetsinglelinerbiclassmoduledefinitions)
|
43
46
|
* [Sorbet/StrictSigil](cops_sorbet.md#sorbetstrictsigil)
|
data/manual/cops_sorbet.md
CHANGED
@@ -41,6 +41,46 @@ FooOrBar = T.any(Foo, Bar)
|
|
41
41
|
FooOrBar = T.type_alias { T.any(Foo, Bar) }
|
42
42
|
```
|
43
43
|
|
44
|
+
## Sorbet/BlockMethodDefinition
|
45
|
+
|
46
|
+
Enabled by default | Safe | Supports autocorrection | VersionAdded | VersionChanged
|
47
|
+
--- | --- | --- | --- | ---
|
48
|
+
Enabled | Yes | Yes (Unsafe) | 0.10.1 | -
|
49
|
+
|
50
|
+
|
51
|
+
|
52
|
+
### Examples
|
53
|
+
|
54
|
+
```ruby
|
55
|
+
# bad
|
56
|
+
yielding_method do
|
57
|
+
def bad(args)
|
58
|
+
# ...
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
# bad
|
63
|
+
Class.new do
|
64
|
+
def bad(args)
|
65
|
+
# ...
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
# good
|
70
|
+
yielding_method do
|
71
|
+
define_method(:good) do |args|
|
72
|
+
# ...
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
# good
|
77
|
+
MyClass = Class.new do
|
78
|
+
def good(args)
|
79
|
+
# ...
|
80
|
+
end
|
81
|
+
end
|
82
|
+
```
|
83
|
+
|
44
84
|
## Sorbet/BuggyObsoleteStrictMemoization
|
45
85
|
|
46
86
|
Enabled by default | Safe | Supports autocorrection | VersionAdded | VersionChanged
|
@@ -180,7 +220,7 @@ end
|
|
180
220
|
|
181
221
|
Enabled by default | Safe | Supports autocorrection | VersionAdded | VersionChanged
|
182
222
|
--- | --- | --- | --- | ---
|
183
|
-
Enabled | Yes | Yes | 0.7.0 |
|
223
|
+
Enabled | Yes | Yes | 0.7.0 | 0.10.1
|
184
224
|
|
185
225
|
Checks for blank lines after signatures.
|
186
226
|
|
@@ -391,6 +431,40 @@ or
|
|
391
431
|
include Polaris::Engine.helpers
|
392
432
|
```
|
393
433
|
|
434
|
+
## Sorbet/ForbidMixesInClassMethods
|
435
|
+
|
436
|
+
Enabled by default | Safe | Supports autocorrection | VersionAdded | VersionChanged
|
437
|
+
--- | --- | --- | --- | ---
|
438
|
+
Disabled | Yes | No | 0.10.1 | -
|
439
|
+
|
440
|
+
Check that code does not call `mixes_in_class_methods` from Sorbet `T::Helpers`.
|
441
|
+
|
442
|
+
Good:
|
443
|
+
|
444
|
+
```
|
445
|
+
module M
|
446
|
+
extend ActiveSupport::Concern
|
447
|
+
|
448
|
+
class_methods do
|
449
|
+
...
|
450
|
+
end
|
451
|
+
end
|
452
|
+
```
|
453
|
+
|
454
|
+
Bad:
|
455
|
+
|
456
|
+
```
|
457
|
+
module M
|
458
|
+
extend T::Helpers
|
459
|
+
|
460
|
+
module ClassMethods
|
461
|
+
...
|
462
|
+
end
|
463
|
+
|
464
|
+
mixes_in_class_methods(ClassMethods)
|
465
|
+
end
|
466
|
+
```
|
467
|
+
|
394
468
|
## Sorbet/ForbidRBIOutsideOfAllowedPaths
|
395
469
|
|
396
470
|
Enabled by default | Safe | Supports autocorrection | VersionAdded | VersionChanged
|
@@ -427,7 +501,7 @@ Include | `**/*.rbi` | Array
|
|
427
501
|
|
428
502
|
Enabled by default | Safe | Supports autocorrection | VersionAdded | VersionChanged
|
429
503
|
--- | --- | --- | --- | ---
|
430
|
-
Disabled | Yes | No |
|
504
|
+
Disabled | Yes | No | 0.9.0 | -
|
431
505
|
|
432
506
|
Check that definitions do not use a `sig` block.
|
433
507
|
|
@@ -449,7 +523,7 @@ def foo; end
|
|
449
523
|
|
450
524
|
Enabled by default | Safe | Supports autocorrection | VersionAdded | VersionChanged
|
451
525
|
--- | --- | --- | --- | ---
|
452
|
-
Disabled | Yes | No |
|
526
|
+
Disabled | Yes | No | 0.9.0 | -
|
453
527
|
|
454
528
|
Check that definitions do not use a `sig` block.
|
455
529
|
|
@@ -471,7 +545,7 @@ def foo; end
|
|
471
545
|
|
472
546
|
Enabled by default | Safe | Supports autocorrection | VersionAdded | VersionChanged
|
473
547
|
--- | --- | --- | --- | ---
|
474
|
-
Disabled | Yes | Yes |
|
548
|
+
Disabled | Yes | Yes | 0.9.0 | -
|
475
549
|
|
476
550
|
Check that `sig` is used instead of `T::Sig::WithoutRuntime.sig`.
|
477
551
|
|
@@ -524,7 +598,7 @@ Exclude | `db/migrate/*.rb` | Array
|
|
524
598
|
|
525
599
|
Enabled by default | Safe | Supports autocorrection | VersionAdded | VersionChanged
|
526
600
|
--- | --- | --- | --- | ---
|
527
|
-
Disabled | No | No |
|
601
|
+
Disabled | No | No | 0.8.9 | -
|
528
602
|
|
529
603
|
Disallow using `T::Enum`.
|
530
604
|
|
@@ -551,7 +625,7 @@ end
|
|
551
625
|
|
552
626
|
Enabled by default | Safe | Supports autocorrection | VersionAdded | VersionChanged
|
553
627
|
--- | --- | --- | --- | ---
|
554
|
-
Disabled | No | Yes |
|
628
|
+
Disabled | No | Yes | 0.7.4 | -
|
555
629
|
|
556
630
|
Disallow using `T::Struct` and `T::Props`.
|
557
631
|
|
@@ -720,7 +794,7 @@ Exclude | `bin/**/*`, `db/**/*.rb`, `script/**/*` | Array
|
|
720
794
|
|
721
795
|
Enabled by default | Safe | Supports autocorrection | VersionAdded | VersionChanged
|
722
796
|
--- | --- | --- | --- | ---
|
723
|
-
Disabled | Yes | No |
|
797
|
+
Disabled | Yes | No | 0.7.1 | -
|
724
798
|
|
725
799
|
Disallows declaring implicit conversion methods.
|
726
800
|
Since Sorbet is a nominal (not structural) type system,
|
@@ -863,7 +937,7 @@ end
|
|
863
937
|
|
864
938
|
Enabled by default | Safe | Supports autocorrection | VersionAdded | VersionChanged
|
865
939
|
--- | --- | --- | --- | ---
|
866
|
-
Enabled | Yes | No |
|
940
|
+
Enabled | Yes | No | 0.8.6 | -
|
867
941
|
|
868
942
|
Checks for the use of Ruby Refinements library. Refinements add
|
869
943
|
complexity and incur a performance penalty that can be significant
|
@@ -896,6 +970,26 @@ module Foo
|
|
896
970
|
end
|
897
971
|
```
|
898
972
|
|
973
|
+
## Sorbet/SelectByIsA
|
974
|
+
|
975
|
+
Enabled by default | Safe | Supports autocorrection | VersionAdded | VersionChanged
|
976
|
+
--- | --- | --- | --- | ---
|
977
|
+
Enabled | Yes | Yes | 0.10.1 | -
|
978
|
+
|
979
|
+
Suggests using `grep` over `select` when using it only for type narrowing.
|
980
|
+
|
981
|
+
### Examples
|
982
|
+
|
983
|
+
```ruby
|
984
|
+
# bad
|
985
|
+
strings_or_integers.select { |e| e.is_a?(String) }
|
986
|
+
strings_or_integers.filter { |e| e.is_a?(String) }
|
987
|
+
strings_or_integers.select { |e| e.kind_of?(String) }
|
988
|
+
|
989
|
+
# good
|
990
|
+
strings_or_integers.grep(String)
|
991
|
+
```
|
992
|
+
|
899
993
|
## Sorbet/SignatureBuildOrder
|
900
994
|
|
901
995
|
Enabled by default | Safe | Supports autocorrection | VersionAdded | VersionChanged
|
data/rubocop-sorbet.gemspec
CHANGED
@@ -12,7 +12,7 @@ Gem::Specification.new do |spec|
|
|
12
12
|
spec.homepage = "https://github.com/shopify/rubocop-sorbet"
|
13
13
|
spec.license = "MIT"
|
14
14
|
|
15
|
-
spec.required_ruby_version = ">= 3.
|
15
|
+
spec.required_ruby_version = ">= 3.1"
|
16
16
|
|
17
17
|
spec.metadata["allowed_push_host"] = "https://rubygems.org"
|
18
18
|
spec.metadata["homepage_uri"] = spec.homepage
|
@@ -28,5 +28,6 @@ Gem::Specification.new do |spec|
|
|
28
28
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
29
29
|
spec.require_paths = ["lib"]
|
30
30
|
|
31
|
-
spec.add_runtime_dependency("
|
31
|
+
spec.add_runtime_dependency("lint_roller")
|
32
|
+
spec.add_runtime_dependency("rubocop", ">= 1.75.2")
|
32
33
|
end
|
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.
|
4
|
+
version: 0.10.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ufuk Kayserilioglu
|
@@ -10,28 +10,43 @@ authors:
|
|
10
10
|
- Peter Zhu
|
11
11
|
bindir: exe
|
12
12
|
cert_chain: []
|
13
|
-
date:
|
13
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: lint_roller
|
17
|
+
requirement: !ruby/object:Gem::Requirement
|
18
|
+
requirements:
|
19
|
+
- - ">="
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
requirements:
|
26
|
+
- - ">="
|
27
|
+
- !ruby/object:Gem::Version
|
28
|
+
version: '0'
|
15
29
|
- !ruby/object:Gem::Dependency
|
16
30
|
name: rubocop
|
17
31
|
requirement: !ruby/object:Gem::Requirement
|
18
32
|
requirements:
|
19
33
|
- - ">="
|
20
34
|
- !ruby/object:Gem::Version
|
21
|
-
version:
|
35
|
+
version: 1.75.2
|
22
36
|
type: :runtime
|
23
37
|
prerelease: false
|
24
38
|
version_requirements: !ruby/object:Gem::Requirement
|
25
39
|
requirements:
|
26
40
|
- - ">="
|
27
41
|
- !ruby/object:Gem::Version
|
28
|
-
version:
|
42
|
+
version: 1.75.2
|
29
43
|
email:
|
30
44
|
- ruby@shopify.com
|
31
45
|
executables: []
|
32
46
|
extensions: []
|
33
47
|
extra_rdoc_files: []
|
34
48
|
files:
|
49
|
+
- ".devcontainer/devcontainer.json"
|
35
50
|
- ".github/CODEOWNERS"
|
36
51
|
- ".github/dependabot.yml"
|
37
52
|
- ".github/release.yml"
|
@@ -43,16 +58,17 @@ files:
|
|
43
58
|
- ".rspec"
|
44
59
|
- ".rubocop.yml"
|
45
60
|
- ".ruby-version"
|
46
|
-
- ".travis.yml"
|
47
61
|
- ".yardopts"
|
48
62
|
- CODE_OF_CONDUCT.md
|
63
|
+
- CONTRIBUTING.md
|
49
64
|
- Gemfile
|
50
65
|
- Gemfile.lock
|
51
66
|
- LICENSE.txt
|
52
67
|
- README.md
|
53
68
|
- Rakefile
|
69
|
+
- VERSION
|
54
70
|
- bin/console
|
55
|
-
- bin/
|
71
|
+
- bin/rake
|
56
72
|
- bin/rubocop
|
57
73
|
- bin/setup
|
58
74
|
- config/default.yml
|
@@ -61,10 +77,12 @@ files:
|
|
61
77
|
- dev.yml
|
62
78
|
- lib/rubocop-sorbet.rb
|
63
79
|
- lib/rubocop/cop/sorbet/binding_constant_without_type_alias.rb
|
80
|
+
- lib/rubocop/cop/sorbet/block_method_definition.rb
|
64
81
|
- lib/rubocop/cop/sorbet/buggy_obsolete_strict_memoization.rb
|
65
82
|
- lib/rubocop/cop/sorbet/callback_conditionals_binding.rb
|
66
83
|
- lib/rubocop/cop/sorbet/constants_from_strings.rb
|
67
84
|
- lib/rubocop/cop/sorbet/forbid_include_const_literal.rb
|
85
|
+
- lib/rubocop/cop/sorbet/forbid_mixes_in_class_methods.rb
|
68
86
|
- lib/rubocop/cop/sorbet/forbid_superclass_const_literal.rb
|
69
87
|
- lib/rubocop/cop/sorbet/forbid_t_enum.rb
|
70
88
|
- lib/rubocop/cop/sorbet/forbid_t_struct.rb
|
@@ -85,6 +103,7 @@ files:
|
|
85
103
|
- lib/rubocop/cop/sorbet/rbi_versioning/valid_gem_version_annotations.rb
|
86
104
|
- lib/rubocop/cop/sorbet/redundant_extend_t_sig.rb
|
87
105
|
- lib/rubocop/cop/sorbet/refinement.rb
|
106
|
+
- lib/rubocop/cop/sorbet/select_by_is_a.rb
|
88
107
|
- lib/rubocop/cop/sorbet/sigils/enforce_sigil_order.rb
|
89
108
|
- lib/rubocop/cop/sorbet/sigils/enforce_single_sigil.rb
|
90
109
|
- lib/rubocop/cop/sorbet/sigils/false_sigil.rb
|
@@ -133,14 +152,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
133
152
|
requirements:
|
134
153
|
- - ">="
|
135
154
|
- !ruby/object:Gem::Version
|
136
|
-
version: '3.
|
155
|
+
version: '3.1'
|
137
156
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
138
157
|
requirements:
|
139
158
|
- - ">="
|
140
159
|
- !ruby/object:Gem::Version
|
141
160
|
version: '0'
|
142
161
|
requirements: []
|
143
|
-
rubygems_version: 3.6.
|
162
|
+
rubygems_version: 3.6.9
|
144
163
|
specification_version: 4
|
145
164
|
summary: Automatic Sorbet code style checking tool.
|
146
165
|
test_files: []
|