rubocop-sorbet 0.8.3 → 0.8.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 +4 -4
- data/.github/dependabot.yml +1 -0
- data/.github/workflows/ci.yml +7 -2
- data/.ruby-version +1 -1
- data/Gemfile.lock +13 -11
- data/lib/rubocop/cop/sorbet/rbi/forbid_rbi_outside_of_allowed_paths.rb +5 -8
- data/lib/rubocop/cop/sorbet/sigils/enforce_sigil_order.rb +30 -29
- data/lib/rubocop/cop/sorbet/sigils/enforce_single_sigil.rb +15 -15
- data/lib/rubocop/cop/sorbet/sigils/has_sigil.rb +0 -2
- data/lib/rubocop/cop/sorbet/sigils/valid_sigil.rb +37 -34
- data/lib/rubocop/cop/sorbet/signatures/checked_true_in_signature.rb +2 -3
- data/lib/rubocop/cop/sorbet/signatures/enforce_signatures.rb +22 -21
- data/lib/rubocop/cop/sorbet/signatures/keyword_argument_ordering.rb +1 -1
- data/lib/rubocop/sorbet/version.rb +1 -1
- data/manual/cops_sorbet.md +3 -1
- data/rubocop-sorbet.gemspec +1 -1
- data/tasks/cops_documentation.rake +2 -2
- metadata +9 -9
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9cb17e31fa88a9bf6693e1bbdad97425f25920b8293782b2dbf3642df2b3138d
|
4
|
+
data.tar.gz: 1a7cc0e93155410faf2f7e9f431b7a182e72b081217774796ff63515a1b2bbc4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 694a6aeff04a8c14a8a511f0f44ffc6abb0035fbbedc9a9e0bdaeeef3ba97d5a360cdc8141048f502f663475743441d8537f7f27c4c2cae78b40cb8d050e8375
|
7
|
+
data.tar.gz: 8781a983e0e0e97a3535943c9ffe76beab985cc5643832b9b138590d3585220dddba6ec3fcdbe6d2ea58152a6349d6fb28c418d7874a7b53b271190120d7bf93
|
data/.github/dependabot.yml
CHANGED
data/.github/workflows/ci.yml
CHANGED
@@ -11,7 +11,7 @@ jobs:
|
|
11
11
|
strategy:
|
12
12
|
fail-fast: false
|
13
13
|
matrix:
|
14
|
-
ruby: ["3.
|
14
|
+
ruby: ["3.1", "3.2", "3.3"]
|
15
15
|
name: Test Ruby ${{ matrix.ruby }}
|
16
16
|
steps:
|
17
17
|
- uses: actions/checkout@v4
|
@@ -33,8 +33,13 @@ jobs:
|
|
33
33
|
- name: Set up Ruby
|
34
34
|
uses: ruby/setup-ruby@v1
|
35
35
|
with:
|
36
|
-
ruby-version: 3.2
|
37
36
|
bundler-cache: true
|
37
|
+
# This is just to ensure the default config is valid. The target is intentionally set
|
38
|
+
# to a directory that doesn't contain any .rb or .rbi files.
|
39
|
+
- name: Validate default config
|
40
|
+
run: |
|
41
|
+
bin/rubocop --config config/rbi.yml config
|
42
|
+
bin/rubocop --config config/default.yml config -r rubocop-sorbet
|
38
43
|
- name: Lint Ruby files
|
39
44
|
run: bin/rubocop
|
40
45
|
- name: Verify documentation is up to date
|
data/.ruby-version
CHANGED
@@ -1 +1 @@
|
|
1
|
-
3.
|
1
|
+
3.3.3
|
data/Gemfile.lock
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
rubocop-sorbet (0.8.
|
5
|
-
rubocop (>=
|
4
|
+
rubocop-sorbet (0.8.4)
|
5
|
+
rubocop (>= 1)
|
6
6
|
|
7
7
|
GEM
|
8
8
|
remote: https://rubygems.org/
|
@@ -18,21 +18,22 @@ GEM
|
|
18
18
|
reline (>= 0.4.2)
|
19
19
|
json (2.7.2)
|
20
20
|
language_server-protocol (3.17.0.3)
|
21
|
-
parallel (1.
|
22
|
-
parser (3.3.0
|
21
|
+
parallel (1.25.1)
|
22
|
+
parser (3.3.4.0)
|
23
23
|
ast (~> 2.4.1)
|
24
24
|
racc
|
25
25
|
psych (5.1.2)
|
26
26
|
stringio
|
27
|
-
racc (1.
|
27
|
+
racc (1.8.0)
|
28
28
|
rainbow (3.1.1)
|
29
29
|
rake (13.2.1)
|
30
30
|
rdoc (6.6.3.1)
|
31
31
|
psych (>= 4.0.0)
|
32
|
-
regexp_parser (2.9.
|
32
|
+
regexp_parser (2.9.2)
|
33
33
|
reline (0.5.1)
|
34
34
|
io-console (~> 0.5)
|
35
|
-
rexml (3.
|
35
|
+
rexml (3.3.1)
|
36
|
+
strscan
|
36
37
|
rspec (3.13.0)
|
37
38
|
rspec-core (~> 3.13.0)
|
38
39
|
rspec-expectations (~> 3.13.0)
|
@@ -46,23 +47,24 @@ GEM
|
|
46
47
|
diff-lcs (>= 1.2.0, < 2.0)
|
47
48
|
rspec-support (~> 3.13.0)
|
48
49
|
rspec-support (3.13.1)
|
49
|
-
rubocop (1.
|
50
|
+
rubocop (1.65.0)
|
50
51
|
json (~> 2.3)
|
51
52
|
language_server-protocol (>= 3.17.0)
|
52
53
|
parallel (~> 1.10)
|
53
54
|
parser (>= 3.3.0.2)
|
54
55
|
rainbow (>= 2.2.2, < 4.0)
|
55
|
-
regexp_parser (>=
|
56
|
+
regexp_parser (>= 2.4, < 3.0)
|
56
57
|
rexml (>= 3.2.5, < 4.0)
|
57
58
|
rubocop-ast (>= 1.31.1, < 2.0)
|
58
59
|
ruby-progressbar (~> 1.7)
|
59
60
|
unicode-display_width (>= 2.4.0, < 3.0)
|
60
|
-
rubocop-ast (1.31.
|
61
|
-
parser (>= 3.3.0
|
61
|
+
rubocop-ast (1.31.3)
|
62
|
+
parser (>= 3.3.1.0)
|
62
63
|
rubocop-shopify (2.15.1)
|
63
64
|
rubocop (~> 1.51)
|
64
65
|
ruby-progressbar (1.13.0)
|
65
66
|
stringio (3.1.0)
|
67
|
+
strscan (3.1.0)
|
66
68
|
unicode-display_width (2.5.0)
|
67
69
|
yard (0.9.36)
|
68
70
|
|
@@ -20,23 +20,21 @@ module RuboCop
|
|
20
20
|
# # rbi/external_interface.rbi
|
21
21
|
# # sorbet/rbi/some_file.rbi
|
22
22
|
# # sorbet/rbi/any/path/for/file.rbi
|
23
|
-
class ForbidRBIOutsideOfAllowedPaths < RuboCop::Cop::
|
23
|
+
class ForbidRBIOutsideOfAllowedPaths < RuboCop::Cop::Base
|
24
24
|
include RangeHelp
|
25
25
|
|
26
|
-
def
|
26
|
+
def on_new_investigation
|
27
27
|
paths = allowed_paths
|
28
28
|
|
29
29
|
if paths.nil?
|
30
30
|
add_offense(
|
31
|
-
|
32
|
-
location: source_range(processed_source.buffer, 1, 0),
|
31
|
+
source_range(processed_source.buffer, 1, 0),
|
33
32
|
message: "AllowedPaths expects an array",
|
34
33
|
)
|
35
34
|
return
|
36
35
|
elsif paths.empty?
|
37
36
|
add_offense(
|
38
|
-
|
39
|
-
location: source_range(processed_source.buffer, 1, 0),
|
37
|
+
source_range(processed_source.buffer, 1, 0),
|
40
38
|
message: "AllowedPaths cannot be empty",
|
41
39
|
)
|
42
40
|
return
|
@@ -47,8 +45,7 @@ module RuboCop
|
|
47
45
|
rel_path = processed_source.file_path.sub("#{Dir.pwd}/", "")
|
48
46
|
|
49
47
|
add_offense(
|
50
|
-
|
51
|
-
location: source_range(processed_source.buffer, 1, 0),
|
48
|
+
source_range(processed_source.buffer, 1, 0),
|
52
49
|
message: "RBI file path should match one of: #{paths.join(", ")}",
|
53
50
|
) if paths.none? { |pattern| File.fnmatch(pattern, rel_path) }
|
54
51
|
end
|
@@ -5,10 +5,12 @@ require "rubocop"
|
|
5
5
|
module RuboCop
|
6
6
|
module Cop
|
7
7
|
module Sorbet
|
8
|
-
# Checks that the Sorbet sigil comes as the first magic comment in the file.
|
8
|
+
# Checks that the Sorbet sigil comes as the first magic comment in the file, after the encoding comment if any.
|
9
9
|
#
|
10
10
|
# The expected order for magic comments is: (en)?coding, typed, warn_indent then frozen_string_literal.
|
11
11
|
#
|
12
|
+
# The ordering is for consistency only, except for the encoding comment which must be first, if present.
|
13
|
+
#
|
12
14
|
# For example, the following bad ordering:
|
13
15
|
#
|
14
16
|
# ```ruby
|
@@ -30,7 +32,7 @@ module RuboCop
|
|
30
32
|
class EnforceSigilOrder < ValidSigil
|
31
33
|
include RangeHelp
|
32
34
|
|
33
|
-
def
|
35
|
+
def on_new_investigation
|
34
36
|
return if processed_source.tokens.empty?
|
35
37
|
|
36
38
|
tokens = extract_magic_comments(processed_source)
|
@@ -39,30 +41,6 @@ module RuboCop
|
|
39
41
|
check_magic_comments_order(tokens)
|
40
42
|
end
|
41
43
|
|
42
|
-
def autocorrect(_node)
|
43
|
-
lambda do |corrector|
|
44
|
-
tokens = extract_magic_comments(processed_source)
|
45
|
-
|
46
|
-
# Get the magic comments tokens in their expected order
|
47
|
-
expected = PREFERRED_ORDER.keys.map do |re|
|
48
|
-
tokens.select { |token| re.match?(token.text) }
|
49
|
-
end.flatten
|
50
|
-
|
51
|
-
tokens.each_with_index do |token, index|
|
52
|
-
corrector.replace(token.pos, expected[index].text)
|
53
|
-
end
|
54
|
-
|
55
|
-
# Remove blank lines between the magic comments
|
56
|
-
lines = tokens.map(&:line).to_set
|
57
|
-
(lines.min...lines.max).each do |line|
|
58
|
-
next if lines.include?(line)
|
59
|
-
next unless processed_source[line - 1].empty?
|
60
|
-
|
61
|
-
corrector.remove(source_range(processed_source.buffer, line, 0))
|
62
|
-
end
|
63
|
-
end
|
64
|
-
end
|
65
|
-
|
66
44
|
protected
|
67
45
|
|
68
46
|
CODING_REGEX = /#\s+(en)?coding:(?:\s+([\w]+))?/
|
@@ -103,13 +81,36 @@ module RuboCop
|
|
103
81
|
if order != expected
|
104
82
|
tokens.each do |token|
|
105
83
|
add_offense(
|
106
|
-
token,
|
107
|
-
location: token.pos,
|
84
|
+
token.pos,
|
108
85
|
message: "Magic comments should be in the following order: #{PREFERRED_ORDER.values.join(", ")}.",
|
109
|
-
)
|
86
|
+
) do |corrector|
|
87
|
+
autocorrect(corrector)
|
88
|
+
end
|
110
89
|
end
|
111
90
|
end
|
112
91
|
end
|
92
|
+
|
93
|
+
def autocorrect(corrector)
|
94
|
+
tokens = extract_magic_comments(processed_source)
|
95
|
+
|
96
|
+
# Get the magic comments tokens in their expected order
|
97
|
+
expected = PREFERRED_ORDER.keys.map do |re|
|
98
|
+
tokens.select { |token| re.match?(token.text) }
|
99
|
+
end.flatten
|
100
|
+
|
101
|
+
tokens.each_with_index do |token, index|
|
102
|
+
corrector.replace(token.pos, expected[index].text)
|
103
|
+
end
|
104
|
+
|
105
|
+
# Remove blank lines between the magic comments
|
106
|
+
lines = tokens.map(&:line).to_set
|
107
|
+
(lines.min...lines.max).each do |line|
|
108
|
+
next if lines.include?(line)
|
109
|
+
next unless processed_source[line - 1].empty?
|
110
|
+
|
111
|
+
corrector.remove(source_range(processed_source.buffer, line, 0))
|
112
|
+
end
|
113
|
+
end
|
113
114
|
end
|
114
115
|
end
|
115
116
|
end
|
@@ -26,27 +26,15 @@ module RuboCop
|
|
26
26
|
class EnforceSingleSigil < ValidSigil
|
27
27
|
include RangeHelp
|
28
28
|
|
29
|
-
def
|
29
|
+
def on_new_investigation
|
30
30
|
return if processed_source.tokens.empty?
|
31
31
|
|
32
32
|
sigils = extract_all_sigils(processed_source)
|
33
33
|
return if sigils.empty?
|
34
34
|
|
35
35
|
sigils[1..sigils.size].each do |token|
|
36
|
-
add_offense(token
|
37
|
-
|
38
|
-
end
|
39
|
-
|
40
|
-
def autocorrect(_node)
|
41
|
-
->(corrector) do
|
42
|
-
sigils = extract_all_sigils(processed_source)
|
43
|
-
return if sigils.empty?
|
44
|
-
|
45
|
-
# The first sigil encountered represents the "real" strictness so remove any below
|
46
|
-
sigils[1..sigils.size].each do |token|
|
47
|
-
corrector.remove(
|
48
|
-
source_range(processed_source.buffer, token.line, (0..token.pos.last_column)),
|
49
|
-
)
|
36
|
+
add_offense(token.pos, message: "Files must only contain one sigil") do |corrector|
|
37
|
+
autocorrect(corrector)
|
50
38
|
end
|
51
39
|
end
|
52
40
|
end
|
@@ -58,6 +46,18 @@ module RuboCop
|
|
58
46
|
.take_while { |token| token.type == :tCOMMENT }
|
59
47
|
.find_all { |token| SIGIL_REGEX.match?(token.text) }
|
60
48
|
end
|
49
|
+
|
50
|
+
def autocorrect(corrector)
|
51
|
+
sigils = extract_all_sigils(processed_source)
|
52
|
+
return if sigils.empty?
|
53
|
+
|
54
|
+
# The first sigil encountered represents the "real" strictness so remove any below
|
55
|
+
sigils[1..sigils.size].each do |token|
|
56
|
+
corrector.remove(
|
57
|
+
source_range(processed_source.buffer, token.line, (0..token.pos.last_column)),
|
58
|
+
)
|
59
|
+
end
|
60
|
+
end
|
61
61
|
end
|
62
62
|
end
|
63
63
|
end
|
@@ -15,8 +15,6 @@ module RuboCop
|
|
15
15
|
#
|
16
16
|
# If a `MinimumStrictness` level is specified, it will be used in offense messages and autocorrect.
|
17
17
|
class HasSigil < ValidSigil
|
18
|
-
@registry = Cop.registry # So we can properly subclass this cop
|
19
|
-
|
20
18
|
def require_sigil_on_all_files?
|
21
19
|
true
|
22
20
|
end
|
@@ -17,10 +17,10 @@ module RuboCop
|
|
17
17
|
#
|
18
18
|
# If an `ExactStrictness` level is specified, it will be used in offense messages and autocorrect.
|
19
19
|
# Otherwise, if a `MinimumStrictness` level is specified, it will be used in offense messages and autocorrect.
|
20
|
-
class ValidSigil < RuboCop::Cop::
|
21
|
-
|
20
|
+
class ValidSigil < RuboCop::Cop::Base
|
21
|
+
extend AutoCorrector
|
22
22
|
|
23
|
-
def
|
23
|
+
def on_new_investigation
|
24
24
|
return if processed_source.tokens.empty?
|
25
25
|
|
26
26
|
sigil = extract_sigil(processed_source)
|
@@ -33,22 +33,6 @@ module RuboCop
|
|
33
33
|
nil unless check_strictness_level(sigil, strictness)
|
34
34
|
end
|
35
35
|
|
36
|
-
def autocorrect(_node)
|
37
|
-
lambda do |corrector|
|
38
|
-
return unless require_sigil_on_all_files?
|
39
|
-
return unless extract_sigil(processed_source).nil?
|
40
|
-
|
41
|
-
token = processed_source.tokens.first
|
42
|
-
replace_with = suggested_strictness_level
|
43
|
-
sigil = "# typed: #{replace_with}"
|
44
|
-
if token.text.start_with?("#!") # shebang line
|
45
|
-
corrector.insert_after(token.pos, "\n#{sigil}")
|
46
|
-
else
|
47
|
-
corrector.insert_before(token.pos, "#{sigil}\n")
|
48
|
-
end
|
49
|
-
end
|
50
|
-
end
|
51
|
-
|
52
36
|
protected
|
53
37
|
|
54
38
|
STRICTNESS_LEVELS = ["ignore", "false", "true", "strict", "strong"]
|
@@ -75,11 +59,12 @@ module RuboCop
|
|
75
59
|
if require_sigil_on_all_files?
|
76
60
|
strictness = suggested_strictness_level
|
77
61
|
add_offense(
|
78
|
-
token,
|
79
|
-
location: token.pos,
|
62
|
+
token.pos,
|
80
63
|
message: "No Sorbet sigil found in file. " \
|
81
64
|
"Try a `typed: #{strictness}` to start (you can also use `rubocop -a` to automatically add this).",
|
82
|
-
)
|
65
|
+
) do |corrector|
|
66
|
+
autocorrect(corrector)
|
67
|
+
end
|
83
68
|
end
|
84
69
|
false
|
85
70
|
end
|
@@ -110,10 +95,11 @@ module RuboCop
|
|
110
95
|
return true if strictness
|
111
96
|
|
112
97
|
add_offense(
|
113
|
-
sigil,
|
114
|
-
location: sigil.pos,
|
98
|
+
sigil.pos,
|
115
99
|
message: "Sorbet sigil should not be empty.",
|
116
|
-
)
|
100
|
+
) do |corrector|
|
101
|
+
autocorrect(corrector)
|
102
|
+
end
|
117
103
|
false
|
118
104
|
end
|
119
105
|
|
@@ -121,10 +107,11 @@ module RuboCop
|
|
121
107
|
return true if STRICTNESS_LEVELS.include?(strictness)
|
122
108
|
|
123
109
|
add_offense(
|
124
|
-
sigil,
|
125
|
-
location: sigil.pos,
|
110
|
+
sigil.pos,
|
126
111
|
message: "Invalid Sorbet sigil `#{strictness}`.",
|
127
|
-
)
|
112
|
+
) do |corrector|
|
113
|
+
autocorrect(corrector)
|
114
|
+
end
|
128
115
|
false
|
129
116
|
end
|
130
117
|
|
@@ -137,20 +124,22 @@ module RuboCop
|
|
137
124
|
exact_level = STRICTNESS_LEVELS.index(exact_strictness)
|
138
125
|
if current_level != exact_level
|
139
126
|
add_offense(
|
140
|
-
sigil,
|
141
|
-
location: sigil.pos,
|
127
|
+
sigil.pos,
|
142
128
|
message: "Sorbet sigil should be `#{exact_strictness}` got `#{strictness}`.",
|
143
|
-
)
|
129
|
+
) do |corrector|
|
130
|
+
autocorrect(corrector)
|
131
|
+
end
|
144
132
|
return false
|
145
133
|
end
|
146
134
|
else
|
147
135
|
minimum_level = STRICTNESS_LEVELS.index(minimum_strictness)
|
148
136
|
if current_level < minimum_level
|
149
137
|
add_offense(
|
150
|
-
sigil,
|
151
|
-
location: sigil.pos,
|
138
|
+
sigil.pos,
|
152
139
|
message: "Sorbet sigil should be at least `#{minimum_strictness}` got `#{strictness}`.",
|
153
|
-
)
|
140
|
+
) do |corrector|
|
141
|
+
autocorrect(corrector)
|
142
|
+
end
|
154
143
|
return false
|
155
144
|
end
|
156
145
|
end
|
@@ -158,6 +147,20 @@ module RuboCop
|
|
158
147
|
true
|
159
148
|
end
|
160
149
|
|
150
|
+
def autocorrect(corrector)
|
151
|
+
return unless require_sigil_on_all_files?
|
152
|
+
return unless extract_sigil(processed_source).nil?
|
153
|
+
|
154
|
+
token = processed_source.tokens.first
|
155
|
+
replace_with = suggested_strictness_level
|
156
|
+
sigil = "# typed: #{replace_with}"
|
157
|
+
if token.text.start_with?("#!") # shebang line
|
158
|
+
corrector.insert_after(token.pos, "\n#{sigil}")
|
159
|
+
else
|
160
|
+
corrector.insert_before(token.pos, "#{sigil}\n")
|
161
|
+
end
|
162
|
+
end
|
163
|
+
|
161
164
|
# options
|
162
165
|
|
163
166
|
# Default is `false`
|
@@ -16,7 +16,7 @@ module RuboCop
|
|
16
16
|
#
|
17
17
|
# # good
|
18
18
|
# sig { void }
|
19
|
-
class CheckedTrueInSignature < ::RuboCop::Cop::
|
19
|
+
class CheckedTrueInSignature < ::RuboCop::Cop::Base
|
20
20
|
include(RuboCop::Cop::RangeHelp)
|
21
21
|
include(RuboCop::Cop::Sorbet::SignatureHelp)
|
22
22
|
|
@@ -37,8 +37,7 @@ module RuboCop
|
|
37
37
|
return unless error
|
38
38
|
|
39
39
|
add_offense(
|
40
|
-
|
41
|
-
location: source_range(
|
40
|
+
source_range(
|
42
41
|
processed_source.buffer,
|
43
42
|
error.location.line,
|
44
43
|
(error.location.selector.begin_pos)..(error.location.end.begin_pos),
|
@@ -24,7 +24,8 @@ module RuboCop
|
|
24
24
|
#
|
25
25
|
# * `ParameterTypePlaceholder`: placeholders used for parameter types (default: 'T.untyped')
|
26
26
|
# * `ReturnTypePlaceholder`: placeholders used for return types (default: 'T.untyped')
|
27
|
-
class EnforceSignatures < ::RuboCop::Cop::
|
27
|
+
class EnforceSignatures < ::RuboCop::Cop::Base
|
28
|
+
extend AutoCorrector
|
28
29
|
include SignatureHelp
|
29
30
|
|
30
31
|
def initialize(config = nil, options = nil)
|
@@ -53,25 +54,6 @@ module RuboCop
|
|
53
54
|
@last_sig_for_scope[scope(node)] = node
|
54
55
|
end
|
55
56
|
|
56
|
-
def autocorrect(node)
|
57
|
-
lambda do |corrector|
|
58
|
-
suggest = SigSuggestion.new(node.loc.column, param_type_placeholder, return_type_placeholder)
|
59
|
-
|
60
|
-
if node.is_a?(RuboCop::AST::DefNode) # def something
|
61
|
-
node.arguments.each do |arg|
|
62
|
-
suggest.params << arg.children.first
|
63
|
-
end
|
64
|
-
elsif accessor?(node) # attr reader, writer, accessor
|
65
|
-
method = node.children[1]
|
66
|
-
symbol = node.children[2]
|
67
|
-
suggest.params << symbol.value if symbol && (method == :attr_writer || method == :attr_accessor)
|
68
|
-
suggest.returns = "void" if method == :attr_writer
|
69
|
-
end
|
70
|
-
|
71
|
-
corrector.insert_before(node, suggest.to_autocorrect)
|
72
|
-
end
|
73
|
-
end
|
74
|
-
|
75
57
|
def scope(node)
|
76
58
|
return unless node.parent
|
77
59
|
return node.parent if [:begin, :block, :class, :module].include?(node.parent.type)
|
@@ -87,11 +69,30 @@ module RuboCop
|
|
87
69
|
add_offense(
|
88
70
|
node,
|
89
71
|
message: "Each method is required to have a signature.",
|
90
|
-
)
|
72
|
+
) do |corrector|
|
73
|
+
autocorrect(corrector, node)
|
74
|
+
end
|
91
75
|
end
|
92
76
|
@last_sig_for_scope[scope] = nil
|
93
77
|
end
|
94
78
|
|
79
|
+
def autocorrect(corrector, node)
|
80
|
+
suggest = SigSuggestion.new(node.loc.column, param_type_placeholder, return_type_placeholder)
|
81
|
+
|
82
|
+
if node.is_a?(RuboCop::AST::DefNode) # def something
|
83
|
+
node.arguments.each do |arg|
|
84
|
+
suggest.params << arg.children.first
|
85
|
+
end
|
86
|
+
elsif accessor?(node) # attr reader, writer, accessor
|
87
|
+
method = node.children[1]
|
88
|
+
symbol = node.children[2]
|
89
|
+
suggest.params << symbol.value if symbol && (method == :attr_writer || method == :attr_accessor)
|
90
|
+
suggest.returns = "void" if method == :attr_writer
|
91
|
+
end
|
92
|
+
|
93
|
+
corrector.insert_before(node, suggest.to_autocorrect)
|
94
|
+
end
|
95
|
+
|
95
96
|
def param_type_placeholder
|
96
97
|
cop_config["ParameterTypePlaceholder"] || "T.untyped"
|
97
98
|
end
|
@@ -17,7 +17,7 @@ module RuboCop
|
|
17
17
|
# # good
|
18
18
|
# sig { params(b: String, a: Integer).void }
|
19
19
|
# def foo(b:, a: 1); end
|
20
|
-
class KeywordArgumentOrdering < ::RuboCop::Cop::
|
20
|
+
class KeywordArgumentOrdering < ::RuboCop::Cop::Base
|
21
21
|
include SignatureHelp
|
22
22
|
|
23
23
|
def on_signature(node)
|
data/manual/cops_sorbet.md
CHANGED
@@ -203,10 +203,12 @@ Enabled by default | Safe | Supports autocorrection | VersionAdded | VersionChan
|
|
203
203
|
--- | --- | --- | --- | ---
|
204
204
|
Enabled | Yes | Yes | 0.3.4 | -
|
205
205
|
|
206
|
-
Checks that the Sorbet sigil comes as the first magic comment in the file.
|
206
|
+
Checks that the Sorbet sigil comes as the first magic comment in the file, after the encoding comment if any.
|
207
207
|
|
208
208
|
The expected order for magic comments is: (en)?coding, typed, warn_indent then frozen_string_literal.
|
209
209
|
|
210
|
+
The ordering is for consistency only, except for the encoding comment which must be first, if present.
|
211
|
+
|
210
212
|
For example, the following bad ordering:
|
211
213
|
|
212
214
|
```ruby
|
data/rubocop-sorbet.gemspec
CHANGED
@@ -278,7 +278,7 @@ task generate_cops_documentation: :yard_for_generate_documentation do
|
|
278
278
|
end
|
279
279
|
|
280
280
|
def main
|
281
|
-
cops = RuboCop::Cop::
|
281
|
+
cops = RuboCop::Cop::Registry.global
|
282
282
|
config = RuboCop::ConfigLoader.load_file("config/default.yml")
|
283
283
|
|
284
284
|
YARD::Registry.load!
|
@@ -302,7 +302,7 @@ task documentation_syntax_check: :yard_for_generate_documentation do
|
|
302
302
|
|
303
303
|
ok = true
|
304
304
|
YARD::Registry.load!
|
305
|
-
cops = RuboCop::Cop::
|
305
|
+
cops = RuboCop::Cop::Registry.global
|
306
306
|
cops.each do |cop|
|
307
307
|
examples = YARD::Registry.all(:class).find do |code_object|
|
308
308
|
next unless RuboCop::Cop::Badge.for(code_object.to_s) == cop.badge
|
metadata
CHANGED
@@ -1,17 +1,17 @@
|
|
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.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ufuk Kayserilioglu
|
8
8
|
- Alan Wu
|
9
9
|
- Alexandre Terrasa
|
10
10
|
- Peter Zhu
|
11
|
-
autorequire:
|
11
|
+
autorequire:
|
12
12
|
bindir: exe
|
13
13
|
cert_chain: []
|
14
|
-
date: 2024-
|
14
|
+
date: 2024-07-16 00:00:00.000000000 Z
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
17
17
|
name: rubocop
|
@@ -19,15 +19,15 @@ dependencies:
|
|
19
19
|
requirements:
|
20
20
|
- - ">="
|
21
21
|
- !ruby/object:Gem::Version
|
22
|
-
version:
|
22
|
+
version: '1'
|
23
23
|
type: :runtime
|
24
24
|
prerelease: false
|
25
25
|
version_requirements: !ruby/object:Gem::Requirement
|
26
26
|
requirements:
|
27
27
|
- - ">="
|
28
28
|
- !ruby/object:Gem::Version
|
29
|
-
version:
|
30
|
-
description:
|
29
|
+
version: '1'
|
30
|
+
description:
|
31
31
|
email:
|
32
32
|
- ruby@shopify.com
|
33
33
|
executables: []
|
@@ -118,7 +118,7 @@ metadata:
|
|
118
118
|
allowed_push_host: https://rubygems.org
|
119
119
|
homepage_uri: https://github.com/shopify/rubocop-sorbet
|
120
120
|
source_code_uri: https://github.com/shopify/rubocop-sorbet
|
121
|
-
post_install_message:
|
121
|
+
post_install_message:
|
122
122
|
rdoc_options: []
|
123
123
|
require_paths:
|
124
124
|
- lib
|
@@ -133,8 +133,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
133
133
|
- !ruby/object:Gem::Version
|
134
134
|
version: '0'
|
135
135
|
requirements: []
|
136
|
-
rubygems_version: 3.5.
|
137
|
-
signing_key:
|
136
|
+
rubygems_version: 3.5.15
|
137
|
+
signing_key:
|
138
138
|
specification_version: 4
|
139
139
|
summary: Automatic Sorbet code style checking tool.
|
140
140
|
test_files: []
|