rubocop-sorbet 0.8.1 → 0.8.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/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
|