rubocop-sorbet 0.8.1 → 0.8.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile +1 -1
- data/Gemfile.lock +19 -6
- data/config/default.yml +10 -5
- data/config/obsoletion.yml +3 -1
- data/lib/rubocop/cop/sorbet/buggy_obsolete_strict_memoization.rb +2 -2
- data/lib/rubocop/cop/sorbet/mixin/t_enum.rb +35 -0
- data/lib/rubocop/cop/sorbet/t_enum/forbid_comparable_t_enum.rb +44 -0
- data/lib/rubocop/cop/sorbet/t_enum/multiple_t_enum_values.rb +59 -0
- data/lib/rubocop/cop/sorbet_cops.rb +6 -3
- data/lib/rubocop/sorbet/version.rb +1 -1
- data/manual/cops.md +2 -1
- data/manual/cops_sorbet.md +54 -24
- metadata +6 -4
- data/lib/rubocop/cop/sorbet/one_ancestor_per_line.rb +0 -80
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1cf8cfdff3aedba93731774d5f47fd8c4f10ef8d615ea2cb9f4cdfd2f20d1522
|
4
|
+
data.tar.gz: 69b6974d9a6de86eeed4b29dcfcae25648a3880036b49ceb57a426821da4535c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 98a957ed012dcfefb642d54ee332d1435c0931bafe6fa07e2d36d280b7a1c4391bab2f05d2b77b1f44da850196a7edb322886b0d50bbe154e0e6d9d80a9f8f62
|
7
|
+
data.tar.gz: 25634e48e2daf8db8b41211d64f49560f9ddcd7236cc181364e7ab6ecc67cbdcd5d169454825a92ffebb2e6337ed81c1847d54483f0a073447034333c2b4b150
|
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,25 +1,37 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
rubocop-sorbet (0.8.
|
4
|
+
rubocop-sorbet (0.8.2)
|
5
5
|
rubocop (>= 0.90.0)
|
6
6
|
|
7
7
|
GEM
|
8
8
|
remote: https://rubygems.org/
|
9
9
|
specs:
|
10
10
|
ast (2.4.2)
|
11
|
-
|
11
|
+
debug (1.9.2)
|
12
|
+
irb (~> 1.10)
|
13
|
+
reline (>= 0.3.8)
|
12
14
|
diff-lcs (1.5.1)
|
13
|
-
|
15
|
+
io-console (0.7.2)
|
16
|
+
irb (1.12.0)
|
17
|
+
rdoc
|
18
|
+
reline (>= 0.4.2)
|
19
|
+
json (2.7.2)
|
14
20
|
language_server-protocol (3.17.0.3)
|
15
21
|
parallel (1.24.0)
|
16
22
|
parser (3.3.0.5)
|
17
23
|
ast (~> 2.4.1)
|
18
24
|
racc
|
25
|
+
psych (5.1.2)
|
26
|
+
stringio
|
19
27
|
racc (1.7.3)
|
20
28
|
rainbow (3.1.1)
|
21
29
|
rake (13.2.1)
|
30
|
+
rdoc (6.6.3.1)
|
31
|
+
psych (>= 4.0.0)
|
22
32
|
regexp_parser (2.9.0)
|
33
|
+
reline (0.5.1)
|
34
|
+
io-console (~> 0.5)
|
23
35
|
rexml (3.2.6)
|
24
36
|
rspec (3.13.0)
|
25
37
|
rspec-core (~> 3.13.0)
|
@@ -34,7 +46,7 @@ GEM
|
|
34
46
|
diff-lcs (>= 1.2.0, < 2.0)
|
35
47
|
rspec-support (~> 3.13.0)
|
36
48
|
rspec-support (3.13.1)
|
37
|
-
rubocop (1.
|
49
|
+
rubocop (1.63.2)
|
38
50
|
json (~> 2.3)
|
39
51
|
language_server-protocol (>= 3.17.0)
|
40
52
|
parallel (~> 1.10)
|
@@ -47,9 +59,10 @@ GEM
|
|
47
59
|
unicode-display_width (>= 2.4.0, < 3.0)
|
48
60
|
rubocop-ast (1.31.2)
|
49
61
|
parser (>= 3.3.0.4)
|
50
|
-
rubocop-shopify (2.
|
62
|
+
rubocop-shopify (2.15.1)
|
51
63
|
rubocop (~> 1.51)
|
52
64
|
ruby-progressbar (1.13.0)
|
65
|
+
stringio (3.1.0)
|
53
66
|
unicode-display_width (2.5.0)
|
54
67
|
yard (0.9.36)
|
55
68
|
|
@@ -57,7 +70,7 @@ PLATFORMS
|
|
57
70
|
ruby
|
58
71
|
|
59
72
|
DEPENDENCIES
|
60
|
-
|
73
|
+
debug
|
61
74
|
rake (>= 12.3.3)
|
62
75
|
rspec (~> 3.13)
|
63
76
|
rubocop-shopify
|
data/config/default.yml
CHANGED
@@ -200,11 +200,6 @@ Sorbet/BuggyObsoleteStrictMemoization:
|
|
200
200
|
Safe: true
|
201
201
|
SafeAutoCorrect: false
|
202
202
|
|
203
|
-
Sorbet/OneAncestorPerLine:
|
204
|
-
Description: 'Enforces one ancestor per call to requires_ancestor'
|
205
|
-
Enabled: false
|
206
|
-
VersionAdded: '0.6.0'
|
207
|
-
|
208
203
|
Sorbet/RedundantExtendTSig:
|
209
204
|
Description: >-
|
210
205
|
Forbid the usage of redundant `extend T::Sig`.
|
@@ -312,3 +307,13 @@ Sorbet/VoidCheckedTests:
|
|
312
307
|
Description: 'Forbid `.void.checked(:tests)`'
|
313
308
|
Enabled: true
|
314
309
|
VersionAdded: 0.7.7
|
310
|
+
|
311
|
+
Sorbet/MultipleTEnumValues:
|
312
|
+
Description: 'Ensures that all `T::Enum`s have multiple values.'
|
313
|
+
Enabled: true
|
314
|
+
VersionAdded: 0.8.2
|
315
|
+
|
316
|
+
Sorbet/ForbidComparableTEnum:
|
317
|
+
Description: 'Disallows including the `Comparable` module in a `T::Enum`.'
|
318
|
+
Enabled: true
|
319
|
+
VersionAdded: 0.8.2
|
data/config/obsoletion.yml
CHANGED
@@ -48,8 +48,8 @@ module RuboCop
|
|
48
48
|
|
49
49
|
include TargetSorbetVersion
|
50
50
|
|
51
|
-
MSG = "This might be a mistaken variant of the two-stage workaround that used to be needed for memoization
|
52
|
-
"`#typed: strict` files. See https://sorbet.org/docs/type-assertions#put-type-assertions-behind-memoization."
|
51
|
+
MSG = "This might be a mistaken variant of the two-stage workaround that used to be needed for memoization " \
|
52
|
+
"in `#typed: strict` files. See https://sorbet.org/docs/type-assertions#put-type-assertions-behind-memoization."
|
53
53
|
|
54
54
|
# @!method buggy_legacy_memoization_pattern?(node)
|
55
55
|
def_node_matcher :buggy_legacy_memoization_pattern?, <<~PATTERN
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module Sorbet
|
6
|
+
# Mixing for writing cops that deal with `T::Enum`s
|
7
|
+
module TEnum
|
8
|
+
extend RuboCop::NodePattern::Macros
|
9
|
+
def initialize(*)
|
10
|
+
@scopes = []
|
11
|
+
super
|
12
|
+
end
|
13
|
+
|
14
|
+
# @!method t_enum?(node)
|
15
|
+
def_node_matcher :t_enum?, <<~PATTERN
|
16
|
+
(class (const...) (const (const nil? :T) :Enum) ...)
|
17
|
+
PATTERN
|
18
|
+
|
19
|
+
def on_class(node)
|
20
|
+
@scopes.push(node)
|
21
|
+
end
|
22
|
+
|
23
|
+
def after_class(node)
|
24
|
+
@scopes.pop
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
def in_t_enum_class?
|
30
|
+
t_enum?(@scopes&.last)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module Sorbet
|
6
|
+
# Disallow including the `Comparable` module in `T::Enum`.
|
7
|
+
#
|
8
|
+
# @example
|
9
|
+
#
|
10
|
+
# # bad
|
11
|
+
# class Priority < T::Enum
|
12
|
+
# include Comparable
|
13
|
+
#
|
14
|
+
# enums do
|
15
|
+
# High = new(3)
|
16
|
+
# Medium = new(2)
|
17
|
+
# Low = new(1)
|
18
|
+
# end
|
19
|
+
#
|
20
|
+
# def <=>(other)
|
21
|
+
# serialize <=> other.serialize
|
22
|
+
# end
|
23
|
+
# end
|
24
|
+
class ForbidComparableTEnum < Base
|
25
|
+
include TEnum
|
26
|
+
|
27
|
+
MSG = "Do not use `T::Enum` as a comparable object because of significant performance overhead."
|
28
|
+
|
29
|
+
RESTRICT_ON_SEND = [:include, :prepend].freeze
|
30
|
+
|
31
|
+
# @!method mix_in_comparable?(node)
|
32
|
+
def_node_matcher :mix_in_comparable?, <<~PATTERN
|
33
|
+
(send nil? {:include | :prepend} (const nil? :Comparable))
|
34
|
+
PATTERN
|
35
|
+
|
36
|
+
def on_send(node)
|
37
|
+
return unless in_t_enum_class? && mix_in_comparable?(node)
|
38
|
+
|
39
|
+
add_offense(node)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module Sorbet
|
6
|
+
# Disallow creating a `T::Enum` with less than two values.
|
7
|
+
#
|
8
|
+
# @example
|
9
|
+
#
|
10
|
+
# # bad
|
11
|
+
# class ErrorMessages < T::Enum
|
12
|
+
# enums do
|
13
|
+
# ServerError = new("There was a server error.")
|
14
|
+
# end
|
15
|
+
# end
|
16
|
+
#
|
17
|
+
# # good
|
18
|
+
# class ErrorMessages < T::Enum
|
19
|
+
# enums do
|
20
|
+
# ServerError = new("There was a server error.")
|
21
|
+
# NotFound = new("The resource was not found.")
|
22
|
+
# end
|
23
|
+
# end
|
24
|
+
class MultipleTEnumValues < Base
|
25
|
+
include TEnum
|
26
|
+
|
27
|
+
MSG = "`T::Enum` should have at least two values."
|
28
|
+
|
29
|
+
# @!method enums_block?(node)
|
30
|
+
def_node_matcher :enums_block?, <<~PATTERN
|
31
|
+
(block (send nil? :enums) ...)
|
32
|
+
PATTERN
|
33
|
+
|
34
|
+
def on_class(node)
|
35
|
+
super
|
36
|
+
|
37
|
+
add_offense(node) if t_enum?(node) && node.body.nil?
|
38
|
+
end
|
39
|
+
|
40
|
+
def on_block(node) # rubocop:disable InternalAffairs/NumblockHandler
|
41
|
+
return unless in_t_enum_class?
|
42
|
+
return unless enums_block?(node)
|
43
|
+
|
44
|
+
scope = @scopes.last
|
45
|
+
|
46
|
+
if node.body.nil?
|
47
|
+
add_offense(scope)
|
48
|
+
return
|
49
|
+
end
|
50
|
+
|
51
|
+
begin_node = node.children.find(&:begin_type?)
|
52
|
+
|
53
|
+
num_casgn_nodes = (begin_node || node).children.count(&:casgn_type?)
|
54
|
+
add_offense(scope) if num_casgn_nodes < 2
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
@@ -1,7 +1,8 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require_relative "sorbet/mixin/target_sorbet_version
|
4
|
-
require_relative "sorbet/mixin/
|
3
|
+
require_relative "sorbet/mixin/target_sorbet_version"
|
4
|
+
require_relative "sorbet/mixin/t_enum"
|
5
|
+
require_relative "sorbet/mixin/signature_help"
|
5
6
|
|
6
7
|
require_relative "sorbet/binding_constant_without_type_alias"
|
7
8
|
require_relative "sorbet/constants_from_strings"
|
@@ -10,7 +11,6 @@ require_relative "sorbet/forbid_include_const_literal"
|
|
10
11
|
require_relative "sorbet/forbid_type_aliased_shapes"
|
11
12
|
require_relative "sorbet/forbid_untyped_struct_props"
|
12
13
|
require_relative "sorbet/implicit_conversion_method"
|
13
|
-
require_relative "sorbet/one_ancestor_per_line"
|
14
14
|
require_relative "sorbet/callback_conditionals_binding"
|
15
15
|
require_relative "sorbet/forbid_t_struct"
|
16
16
|
require_relative "sorbet/forbid_t_unsafe"
|
@@ -42,4 +42,7 @@ require_relative "sorbet/sigils/strong_sigil"
|
|
42
42
|
require_relative "sorbet/sigils/enforce_sigil_order"
|
43
43
|
require_relative "sorbet/sigils/enforce_single_sigil"
|
44
44
|
|
45
|
+
require_relative "sorbet/t_enum/forbid_comparable_t_enum"
|
46
|
+
require_relative "sorbet/t_enum/multiple_t_enum_values"
|
47
|
+
|
45
48
|
require_relative "sorbet/mutable_constant_sorbet_aware_behaviour"
|
data/manual/cops.md
CHANGED
@@ -16,6 +16,7 @@ In the following section you find all available cops:
|
|
16
16
|
* [Sorbet/EnforceSignatures](cops_sorbet.md#sorbetenforcesignatures)
|
17
17
|
* [Sorbet/EnforceSingleSigil](cops_sorbet.md#sorbetenforcesinglesigil)
|
18
18
|
* [Sorbet/FalseSigil](cops_sorbet.md#sorbetfalsesigil)
|
19
|
+
* [Sorbet/ForbidComparableTEnum](cops_sorbet.md#sorbetforbidcomparabletenum)
|
19
20
|
* [Sorbet/ForbidExtendTSigHelpersInShims](cops_sorbet.md#sorbetforbidextendtsighelpersinshims)
|
20
21
|
* [Sorbet/ForbidIncludeConstLiteral](cops_sorbet.md#sorbetforbidincludeconstliteral)
|
21
22
|
* [Sorbet/ForbidRBIOutsideOfAllowedPaths](cops_sorbet.md#sorbetforbidrbioutsideofallowedpaths)
|
@@ -29,8 +30,8 @@ In the following section you find all available cops:
|
|
29
30
|
* [Sorbet/IgnoreSigil](cops_sorbet.md#sorbetignoresigil)
|
30
31
|
* [Sorbet/ImplicitConversionMethod](cops_sorbet.md#sorbetimplicitconversionmethod)
|
31
32
|
* [Sorbet/KeywordArgumentOrdering](cops_sorbet.md#sorbetkeywordargumentordering)
|
33
|
+
* [Sorbet/MultipleTEnumValues](cops_sorbet.md#sorbetmultipletenumvalues)
|
32
34
|
* [Sorbet/ObsoleteStrictMemoization](cops_sorbet.md#sorbetobsoletestrictmemoization)
|
33
|
-
* [Sorbet/OneAncestorPerLine](cops_sorbet.md#sorbetoneancestorperline)
|
34
35
|
* [Sorbet/RedundantExtendTSig](cops_sorbet.md#sorbetredundantextendtsig)
|
35
36
|
* [Sorbet/SignatureBuildOrder](cops_sorbet.md#sorbetsignaturebuildorder)
|
36
37
|
* [Sorbet/SingleLineRbiClassModuleDefinitions](cops_sorbet.md#sorbetsinglelinerbiclassmoduledefinitions)
|
data/manual/cops_sorbet.md
CHANGED
@@ -295,6 +295,33 @@ SuggestedStrictness | `false` | String
|
|
295
295
|
Include | `**/*.{rb,rbi,rake,ru}` | Array
|
296
296
|
Exclude | `bin/**/*`, `db/**/*.rb`, `script/**/*` | Array
|
297
297
|
|
298
|
+
## Sorbet/ForbidComparableTEnum
|
299
|
+
|
300
|
+
Enabled by default | Safe | Supports autocorrection | VersionAdded | VersionChanged
|
301
|
+
--- | --- | --- | --- | ---
|
302
|
+
Enabled | Yes | No | 0.8.2 | -
|
303
|
+
|
304
|
+
Disallow including the `Comparable` module in `T::Enum`.
|
305
|
+
|
306
|
+
### Examples
|
307
|
+
|
308
|
+
```ruby
|
309
|
+
# bad
|
310
|
+
class Priority < T::Enum
|
311
|
+
include Comparable
|
312
|
+
|
313
|
+
enums do
|
314
|
+
High = new(3)
|
315
|
+
Medium = new(2)
|
316
|
+
Low = new(1)
|
317
|
+
end
|
318
|
+
|
319
|
+
def <=>(other)
|
320
|
+
serialize <=> other.serialize
|
321
|
+
end
|
322
|
+
end
|
323
|
+
```
|
324
|
+
|
298
325
|
## Sorbet/ForbidExtendTSigHelpersInShims
|
299
326
|
|
300
327
|
Enabled by default | Safe | Supports autocorrection | VersionAdded | VersionChanged
|
@@ -639,6 +666,33 @@ sig { params(b: String, a: Integer).void }
|
|
639
666
|
def foo(b:, a: 1); end
|
640
667
|
```
|
641
668
|
|
669
|
+
## Sorbet/MultipleTEnumValues
|
670
|
+
|
671
|
+
Enabled by default | Safe | Supports autocorrection | VersionAdded | VersionChanged
|
672
|
+
--- | --- | --- | --- | ---
|
673
|
+
Enabled | Yes | No | 0.8.2 | -
|
674
|
+
|
675
|
+
Disallow creating a `T::Enum` with less than two values.
|
676
|
+
|
677
|
+
### Examples
|
678
|
+
|
679
|
+
```ruby
|
680
|
+
# bad
|
681
|
+
class ErrorMessages < T::Enum
|
682
|
+
enums do
|
683
|
+
ServerError = new("There was a server error.")
|
684
|
+
end
|
685
|
+
end
|
686
|
+
|
687
|
+
# good
|
688
|
+
class ErrorMessages < T::Enum
|
689
|
+
enums do
|
690
|
+
ServerError = new("There was a server error.")
|
691
|
+
NotFound = new("The resource was not found.")
|
692
|
+
end
|
693
|
+
end
|
694
|
+
```
|
695
|
+
|
642
696
|
## Sorbet/ObsoleteStrictMemoization
|
643
697
|
|
644
698
|
Enabled by default | Safe | Supports autocorrection | VersionAdded | VersionChanged
|
@@ -676,30 +730,6 @@ def foo
|
|
676
730
|
end
|
677
731
|
```
|
678
732
|
|
679
|
-
## Sorbet/OneAncestorPerLine
|
680
|
-
|
681
|
-
Enabled by default | Safe | Supports autocorrection | VersionAdded | VersionChanged
|
682
|
-
--- | --- | --- | --- | ---
|
683
|
-
Disabled | Yes | Yes | 0.6.0 | -
|
684
|
-
|
685
|
-
Ensures one ancestor per requires_ancestor line
|
686
|
-
rather than chaining them as a comma-separated list.
|
687
|
-
|
688
|
-
### Examples
|
689
|
-
|
690
|
-
```ruby
|
691
|
-
# bad
|
692
|
-
module SomeModule
|
693
|
-
requires_ancestor Kernel, Minitest::Assertions
|
694
|
-
end
|
695
|
-
|
696
|
-
# good
|
697
|
-
module SomeModule
|
698
|
-
requires_ancestor Kernel
|
699
|
-
requires_ancestor Minitest::Assertions
|
700
|
-
end
|
701
|
-
```
|
702
|
-
|
703
733
|
## Sorbet/RedundantExtendTSig
|
704
734
|
|
705
735
|
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.8.
|
4
|
+
version: 0.8.2
|
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: 2024-04-
|
14
|
+
date: 2024-04-23 00:00:00.000000000 Z
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
17
17
|
name: rubocop
|
@@ -74,10 +74,10 @@ files:
|
|
74
74
|
- lib/rubocop/cop/sorbet/forbid_untyped_struct_props.rb
|
75
75
|
- lib/rubocop/cop/sorbet/implicit_conversion_method.rb
|
76
76
|
- lib/rubocop/cop/sorbet/mixin/signature_help.rb
|
77
|
+
- lib/rubocop/cop/sorbet/mixin/t_enum.rb
|
77
78
|
- lib/rubocop/cop/sorbet/mixin/target_sorbet_version.rb
|
78
79
|
- lib/rubocop/cop/sorbet/mutable_constant_sorbet_aware_behaviour.rb
|
79
80
|
- lib/rubocop/cop/sorbet/obsolete_strict_memoization.rb
|
80
|
-
- lib/rubocop/cop/sorbet/one_ancestor_per_line.rb
|
81
81
|
- lib/rubocop/cop/sorbet/rbi/forbid_extend_t_sig_helpers_in_shims.rb
|
82
82
|
- lib/rubocop/cop/sorbet/rbi/forbid_rbi_outside_of_allowed_paths.rb
|
83
83
|
- lib/rubocop/cop/sorbet/rbi/single_line_rbi_class_module_definitions.rb
|
@@ -98,6 +98,8 @@ files:
|
|
98
98
|
- lib/rubocop/cop/sorbet/signatures/keyword_argument_ordering.rb
|
99
99
|
- lib/rubocop/cop/sorbet/signatures/signature_build_order.rb
|
100
100
|
- lib/rubocop/cop/sorbet/signatures/void_checked_tests.rb
|
101
|
+
- lib/rubocop/cop/sorbet/t_enum/forbid_comparable_t_enum.rb
|
102
|
+
- lib/rubocop/cop/sorbet/t_enum/multiple_t_enum_values.rb
|
101
103
|
- lib/rubocop/cop/sorbet/type_alias_name.rb
|
102
104
|
- lib/rubocop/cop/sorbet_cops.rb
|
103
105
|
- lib/rubocop/sorbet.rb
|
@@ -131,7 +133,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
131
133
|
- !ruby/object:Gem::Version
|
132
134
|
version: '0'
|
133
135
|
requirements: []
|
134
|
-
rubygems_version: 3.5.
|
136
|
+
rubygems_version: 3.5.9
|
135
137
|
signing_key:
|
136
138
|
specification_version: 4
|
137
139
|
summary: Automatic Sorbet code style checking tool.
|
@@ -1,80 +0,0 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
# frozen_string_literal: true
|
3
|
-
|
4
|
-
require "rubocop"
|
5
|
-
|
6
|
-
module RuboCop
|
7
|
-
module Cop
|
8
|
-
module Sorbet
|
9
|
-
# Ensures one ancestor per requires_ancestor line
|
10
|
-
# rather than chaining them as a comma-separated list.
|
11
|
-
#
|
12
|
-
# @example
|
13
|
-
#
|
14
|
-
# # bad
|
15
|
-
# module SomeModule
|
16
|
-
# requires_ancestor Kernel, Minitest::Assertions
|
17
|
-
# end
|
18
|
-
#
|
19
|
-
# # good
|
20
|
-
# module SomeModule
|
21
|
-
# requires_ancestor Kernel
|
22
|
-
# requires_ancestor Minitest::Assertions
|
23
|
-
# end
|
24
|
-
class OneAncestorPerLine < RuboCop::Cop::Cop # rubocop:todo InternalAffairs/InheritDeprecatedCopClass
|
25
|
-
MSG = "Cannot require more than one ancestor per line"
|
26
|
-
|
27
|
-
# @!method requires_ancestors(node)
|
28
|
-
def_node_search :requires_ancestors, <<~PATTERN
|
29
|
-
(send nil? :requires_ancestor ...)
|
30
|
-
PATTERN
|
31
|
-
|
32
|
-
# @!method more_than_one_ancestor(node)
|
33
|
-
def_node_matcher :more_than_one_ancestor, <<~PATTERN
|
34
|
-
(send nil? :requires_ancestor const const+)
|
35
|
-
PATTERN
|
36
|
-
|
37
|
-
# @!method abstract?(node)
|
38
|
-
def_node_search :abstract?, <<~PATTERN
|
39
|
-
(send nil? :abstract!)
|
40
|
-
PATTERN
|
41
|
-
|
42
|
-
def on_module(node)
|
43
|
-
return unless node.body
|
44
|
-
return unless requires_ancestors(node)
|
45
|
-
|
46
|
-
process_node(node)
|
47
|
-
end
|
48
|
-
|
49
|
-
def on_class(node)
|
50
|
-
return unless abstract?(node)
|
51
|
-
return unless requires_ancestors(node)
|
52
|
-
|
53
|
-
process_node(node)
|
54
|
-
end
|
55
|
-
|
56
|
-
def autocorrect(node)
|
57
|
-
->(corrector) do
|
58
|
-
ra_call = node.parent
|
59
|
-
split_ra_calls = ra_call.source.gsub(/,\s+/, new_ra_line(ra_call.loc.column))
|
60
|
-
corrector.replace(ra_call, split_ra_calls)
|
61
|
-
end
|
62
|
-
end
|
63
|
-
|
64
|
-
private
|
65
|
-
|
66
|
-
def process_node(node)
|
67
|
-
requires_ancestors(node).each do |ra|
|
68
|
-
add_offense(ra.child_nodes[1]) if more_than_one_ancestor(ra)
|
69
|
-
end
|
70
|
-
end
|
71
|
-
|
72
|
-
def new_ra_line(indent_count)
|
73
|
-
indents = " " * indent_count
|
74
|
-
indented_ra_call = "#{indents}requires_ancestor "
|
75
|
-
"\n#{indented_ra_call}"
|
76
|
-
end
|
77
|
-
end
|
78
|
-
end
|
79
|
-
end
|
80
|
-
end
|