rubocop-sorbet 0.5.1 → 0.6.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/release.yml +23 -0
- data/.github/workflows/ci.yml +26 -0
- data/.gitignore +1 -0
- data/Gemfile +1 -0
- data/Gemfile.lock +25 -41
- data/README.md +22 -0
- data/Rakefile +12 -16
- data/bin/console +3 -3
- data/bin/rspec +6 -6
- data/bin/rubocop +29 -0
- data/config/default.yml +94 -10
- data/config/rbi.yml +262 -0
- data/dev.yml +1 -1
- data/lib/rubocop/cop/sorbet/binding_constants_without_type_alias.rb +4 -4
- data/lib/rubocop/cop/sorbet/callback_conditionals_binding.rb +142 -0
- data/lib/rubocop/cop/sorbet/constants_from_strings.rb +1 -1
- data/lib/rubocop/cop/sorbet/forbid_include_const_literal.rb +11 -2
- data/lib/rubocop/cop/sorbet/forbid_superclass_const_literal.rb +2 -2
- data/lib/rubocop/cop/sorbet/forbid_t_unsafe.rb +26 -0
- data/lib/rubocop/cop/sorbet/forbid_untyped_struct_props.rb +2 -2
- data/lib/rubocop/cop/sorbet/one_ancestor_per_line.rb +75 -0
- data/lib/rubocop/cop/sorbet/rbi/forbid_extend_t_sig_helpers_in_shims.rb +53 -0
- data/lib/rubocop/cop/sorbet/rbi/forbid_rbi_outside_of_allowed_paths.rb +47 -0
- data/lib/rubocop/cop/sorbet/rbi/single_line_rbi_class_module_definitions.rb +46 -0
- data/lib/rubocop/cop/sorbet/sigils/enforce_sigil_order.rb +6 -6
- data/lib/rubocop/cop/sorbet/sigils/enforce_single_sigil.rb +63 -0
- data/lib/rubocop/cop/sorbet/sigils/false_sigil.rb +3 -3
- data/lib/rubocop/cop/sorbet/sigils/has_sigil.rb +2 -2
- data/lib/rubocop/cop/sorbet/sigils/ignore_sigil.rb +3 -3
- data/lib/rubocop/cop/sorbet/sigils/strict_sigil.rb +3 -3
- data/lib/rubocop/cop/sorbet/sigils/strong_sigil.rb +3 -3
- data/lib/rubocop/cop/sorbet/sigils/true_sigil.rb +3 -3
- data/lib/rubocop/cop/sorbet/sigils/valid_sigil.rb +10 -8
- data/lib/rubocop/cop/sorbet/signatures/allow_incompatible_override.rb +3 -3
- data/lib/rubocop/cop/sorbet/signatures/checked_true_in_signature.rb +6 -6
- data/lib/rubocop/cop/sorbet/signatures/enforce_signatures.rb +30 -21
- data/lib/rubocop/cop/sorbet/signatures/keyword_argument_ordering.rb +3 -3
- data/lib/rubocop/cop/sorbet/signatures/signature_build_order.rb +24 -15
- data/lib/rubocop/cop/sorbet/signatures/signature_cop.rb +17 -2
- data/lib/rubocop/cop/sorbet_cops.rb +26 -19
- data/lib/rubocop/sorbet/version.rb +1 -1
- data/lib/rubocop/sorbet.rb +1 -1
- data/lib/rubocop-sorbet.rb +5 -5
- data/manual/cops.md +7 -1
- data/manual/cops_sorbet.md +247 -14
- data/rubocop-sorbet.gemspec +2 -2
- data/service.yml +0 -5
- data/tasks/cops_documentation.rake +60 -62
- metadata +20 -12
- data/.shopify-build/VERSION +0 -1
- data/.shopify-build/rubocop-sorbet.yml +0 -16
- data/lib/rubocop/cop/sorbet/signatures/parameters_ordering_in_signature.rb +0 -70
@@ -1,15 +1,15 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
4
|
-
require
|
5
|
-
require
|
3
|
+
require "yard"
|
4
|
+
require "rubocop"
|
5
|
+
require "rubocop-sorbet"
|
6
6
|
|
7
7
|
YARD::Rake::YardocTask.new(:yard_for_generate_documentation) do |task|
|
8
|
-
task.files = [
|
9
|
-
task.options = [
|
8
|
+
task.files = ["lib/rubocop/cop/**/*.rb"]
|
9
|
+
task.options = ["--no-output"]
|
10
10
|
end
|
11
11
|
|
12
|
-
desc(
|
12
|
+
desc("Generate docs of all cops departments")
|
13
13
|
task generate_cops_documentation: :yard_for_generate_documentation do
|
14
14
|
def cops_of_department(cops, department)
|
15
15
|
cops.with_department(department).sort!
|
@@ -27,14 +27,14 @@ task generate_cops_documentation: :yard_for_generate_documentation do
|
|
27
27
|
end
|
28
28
|
|
29
29
|
def examples(examples_object)
|
30
|
-
examples_object.each_with_object(h3(
|
31
|
-
content << h4(example.name) unless example.name ==
|
30
|
+
examples_object.each_with_object(h3("Examples").dup) do |example, content|
|
31
|
+
content << h4(example.name) unless example.name == ""
|
32
32
|
content << code_example(example)
|
33
33
|
end
|
34
34
|
end
|
35
35
|
|
36
36
|
def required_ruby_version(cop)
|
37
|
-
return
|
37
|
+
return "" unless cop.respond_to?(:required_minimum_ruby_version)
|
38
38
|
|
39
39
|
<<~NOTE
|
40
40
|
!!! Note
|
@@ -46,22 +46,22 @@ task generate_cops_documentation: :yard_for_generate_documentation do
|
|
46
46
|
|
47
47
|
def properties(config, cop)
|
48
48
|
header = [
|
49
|
-
|
50
|
-
|
49
|
+
"Enabled by default", "Safe", "Supports autocorrection", "VersionAdded",
|
50
|
+
"VersionChanged"
|
51
51
|
]
|
52
52
|
config = config.for_cop(cop)
|
53
|
-
safe_auto_correct = config.fetch(
|
53
|
+
safe_auto_correct = config.fetch("SafeAutoCorrect", true)
|
54
54
|
autocorrect = if cop.new.support_autocorrect?
|
55
|
-
"Yes #{
|
55
|
+
"Yes #{"(Unsafe)" unless safe_auto_correct}"
|
56
56
|
else
|
57
|
-
|
57
|
+
"No"
|
58
58
|
end
|
59
59
|
content = [[
|
60
|
-
config.fetch(
|
61
|
-
config.fetch(
|
60
|
+
config.fetch("Enabled") ? "Enabled" : "Disabled",
|
61
|
+
config.fetch("Safe", true) ? "Yes" : "No",
|
62
62
|
autocorrect,
|
63
|
-
config.fetch(
|
64
|
-
config.fetch(
|
63
|
+
config.fetch("VersionAdded", "-"),
|
64
|
+
config.fetch("VersionChanged", "-"),
|
65
65
|
]]
|
66
66
|
to_table(header, content) + "\n"
|
67
67
|
end
|
@@ -89,23 +89,23 @@ task generate_cops_documentation: :yard_for_generate_documentation do
|
|
89
89
|
def code_example(ruby_code)
|
90
90
|
content = +"```ruby\n"
|
91
91
|
content << ruby_code.text
|
92
|
-
.gsub(
|
92
|
+
.gsub("@good", "# good").gsub("@bad", "# bad").strip
|
93
93
|
content << "\n```\n"
|
94
94
|
content
|
95
95
|
end
|
96
96
|
|
97
97
|
def configurations(pars)
|
98
|
-
return
|
98
|
+
return "" if pars.empty?
|
99
99
|
|
100
|
-
header = [
|
101
|
-
configs = pars.each_key.reject { |key| key.start_with?(
|
100
|
+
header = ["Name", "Default value", "Configurable values"]
|
101
|
+
configs = pars.each_key.reject { |key| key.start_with?("Supported") }
|
102
102
|
content = configs.map do |name|
|
103
103
|
configurable = configurable_values(pars, name)
|
104
104
|
default = format_table_value(pars[name])
|
105
105
|
[name, default, configurable]
|
106
106
|
end
|
107
107
|
|
108
|
-
h3(
|
108
|
+
h3("Configurable attributes") + to_table(header, content)
|
109
109
|
end
|
110
110
|
|
111
111
|
def configurable_values(pars, name)
|
@@ -113,24 +113,24 @@ task generate_cops_documentation: :yard_for_generate_documentation do
|
|
113
113
|
when /^Enforced/
|
114
114
|
supported_style_name = RuboCop::Cop::Util.to_supported_styles(name)
|
115
115
|
format_table_value(pars[supported_style_name])
|
116
|
-
when
|
117
|
-
|
118
|
-
when
|
119
|
-
format_table_value(pars[
|
116
|
+
when "IndentationWidth"
|
117
|
+
"Integer"
|
118
|
+
when "Database"
|
119
|
+
format_table_value(pars["SupportedDatabases"])
|
120
120
|
else
|
121
121
|
case pars[name]
|
122
122
|
when String
|
123
|
-
|
123
|
+
"String"
|
124
124
|
when Integer
|
125
|
-
|
125
|
+
"Integer"
|
126
126
|
when Float
|
127
|
-
|
127
|
+
"Float"
|
128
128
|
when true, false
|
129
|
-
|
129
|
+
"Boolean"
|
130
130
|
when Array
|
131
|
-
|
131
|
+
"Array"
|
132
132
|
else
|
133
|
-
|
133
|
+
""
|
134
134
|
end
|
135
135
|
end
|
136
136
|
end
|
@@ -138,10 +138,10 @@ task generate_cops_documentation: :yard_for_generate_documentation do
|
|
138
138
|
|
139
139
|
def to_table(header, content)
|
140
140
|
table = [
|
141
|
-
header.join(
|
142
|
-
Array.new(header.size,
|
141
|
+
header.join(" | "),
|
142
|
+
Array.new(header.size, "---").join(" | "),
|
143
143
|
]
|
144
|
-
table.concat(content.map { |c| c.join(
|
144
|
+
table.concat(content.map { |c| c.join(" | ") })
|
145
145
|
table.join("\n") + "\n"
|
146
146
|
end
|
147
147
|
|
@@ -150,14 +150,14 @@ task generate_cops_documentation: :yard_for_generate_documentation do
|
|
150
150
|
case val
|
151
151
|
when Array
|
152
152
|
if val.empty?
|
153
|
-
|
153
|
+
"`[]`"
|
154
154
|
else
|
155
|
-
val.map { |config| format_table_value(config) }.join(
|
155
|
+
val.map { |config| format_table_value(config) }.join(", ")
|
156
156
|
end
|
157
157
|
else
|
158
|
-
"`#{val.nil? ?
|
158
|
+
"`#{val.nil? ? "<none>" : val}`"
|
159
159
|
end
|
160
|
-
value.gsub("#{Dir.pwd}/",
|
160
|
+
value.gsub("#{Dir.pwd}/", "").rstrip
|
161
161
|
end
|
162
162
|
|
163
163
|
def references(config, cop)
|
@@ -165,9 +165,9 @@ task generate_cops_documentation: :yard_for_generate_documentation do
|
|
165
165
|
urls = RuboCop::Cop::MessageAnnotator.new(
|
166
166
|
config, cop.name, cop_config, {}
|
167
167
|
).urls
|
168
|
-
return
|
168
|
+
return "" if urls.empty?
|
169
169
|
|
170
|
-
content = h3(
|
170
|
+
content = h3("References")
|
171
171
|
content << urls.map { |url| "* [#{url}](#{url})" }.join("\n")
|
172
172
|
content << "\n"
|
173
173
|
content
|
@@ -175,7 +175,7 @@ task generate_cops_documentation: :yard_for_generate_documentation do
|
|
175
175
|
|
176
176
|
def print_cops_of_department(cops, department, config)
|
177
177
|
selected_cops = cops_of_department(cops, department).select do |cop|
|
178
|
-
cop.to_s.start_with?(
|
178
|
+
cop.to_s.start_with?("RuboCop::Cop::Sorbet")
|
179
179
|
end
|
180
180
|
return if selected_cops.empty?
|
181
181
|
|
@@ -184,7 +184,7 @@ task generate_cops_documentation: :yard_for_generate_documentation do
|
|
184
184
|
content << print_cop_with_doc(cop, config)
|
185
185
|
end
|
186
186
|
file_name = "#{Dir.pwd}/manual/cops_#{department.downcase}.md"
|
187
|
-
File.open(file_name,
|
187
|
+
File.open(file_name, "w") do |file|
|
188
188
|
puts "* generated #{file_name}"
|
189
189
|
file.write(content.strip + "\n")
|
190
190
|
end
|
@@ -192,25 +192,23 @@ task generate_cops_documentation: :yard_for_generate_documentation do
|
|
192
192
|
|
193
193
|
def print_cop_with_doc(cop, config)
|
194
194
|
t = config.for_cop(cop)
|
195
|
-
non_display_keys =
|
196
|
-
|
197
|
-
VersionChanged
|
198
|
-
]
|
195
|
+
non_display_keys = ["Description", "Enabled", "StyleGuide", "Reference", "Safe", "SafeAutoCorrect", "VersionAdded",
|
196
|
+
"VersionChanged"]
|
199
197
|
pars = t.reject { |k| non_display_keys.include?(k) }
|
200
|
-
description =
|
198
|
+
description = "No documentation"
|
201
199
|
examples_object = []
|
202
200
|
YARD::Registry.all(:class).detect do |code_object|
|
203
201
|
next unless RuboCop::Cop::Badge.for(code_object.to_s) == cop.badge
|
204
202
|
|
205
203
|
description = code_object.docstring unless code_object.docstring.blank?
|
206
|
-
examples_object = code_object.tags(
|
204
|
+
examples_object = code_object.tags("example")
|
207
205
|
end
|
208
206
|
cops_body(config, cop, description, examples_object, pars)
|
209
207
|
end
|
210
208
|
|
211
209
|
def table_of_content_for_department(cops, department)
|
212
210
|
selected_cops = cops_of_department(cops, department.to_sym).select do |cop|
|
213
|
-
cop.to_s.start_with?(
|
211
|
+
cop.to_s.start_with?("RuboCop::Cop::Sorbet")
|
214
212
|
end
|
215
213
|
return if selected_cops.empty?
|
216
214
|
|
@@ -218,7 +216,7 @@ task generate_cops_documentation: :yard_for_generate_documentation do
|
|
218
216
|
filename = "cops_#{department.downcase}.md"
|
219
217
|
content = +"#### Department [#{type_title}](#{filename})\n\n"
|
220
218
|
selected_cops.each do |cop|
|
221
|
-
anchor = cop.cop_name.sub(
|
219
|
+
anchor = cop.cop_name.sub("/", "").downcase
|
222
220
|
content << "* [#{cop.cop_name}](#{filename}##{anchor})\n"
|
223
221
|
end
|
224
222
|
|
@@ -256,21 +254,21 @@ task generate_cops_documentation: :yard_for_generate_documentation do
|
|
256
254
|
|
257
255
|
def assert_manual_synchronized
|
258
256
|
# Do not print diff and yield whether exit code was zero
|
259
|
-
sh(
|
257
|
+
sh("git diff --quiet manual") do |outcome, _|
|
260
258
|
return if outcome
|
261
259
|
|
262
260
|
# Output diff before raising error
|
263
|
-
sh(
|
261
|
+
sh("GIT_PAGER=cat git diff manual")
|
264
262
|
|
265
|
-
warn
|
266
|
-
|
263
|
+
warn("The manual directory is out of sync. " \
|
264
|
+
"Run `rake generate_cops_documentation` and commit the results.")
|
267
265
|
exit!
|
268
266
|
end
|
269
267
|
end
|
270
268
|
|
271
269
|
def main
|
272
270
|
cops = RuboCop::Cop::Cop.registry
|
273
|
-
config = RuboCop::ConfigLoader.load_file(
|
271
|
+
config = RuboCop::ConfigLoader.load_file("config/default.yml")
|
274
272
|
|
275
273
|
YARD::Registry.load!
|
276
274
|
cops.departments.sort!.each do |department|
|
@@ -279,7 +277,7 @@ task generate_cops_documentation: :yard_for_generate_documentation do
|
|
279
277
|
|
280
278
|
print_table_of_contents(cops)
|
281
279
|
|
282
|
-
assert_manual_synchronized if ENV[
|
280
|
+
assert_manual_synchronized if ENV["CI"] == "true"
|
283
281
|
ensure
|
284
282
|
RuboCop::ConfigLoader.default_configuration = nil
|
285
283
|
end
|
@@ -287,9 +285,9 @@ task generate_cops_documentation: :yard_for_generate_documentation do
|
|
287
285
|
main
|
288
286
|
end
|
289
287
|
|
290
|
-
desc(
|
288
|
+
desc("Syntax check for the documentation comments")
|
291
289
|
task documentation_syntax_check: :yard_for_generate_documentation do
|
292
|
-
require
|
290
|
+
require "parser/ruby25"
|
293
291
|
|
294
292
|
ok = true
|
295
293
|
YARD::Registry.load!
|
@@ -298,11 +296,11 @@ task documentation_syntax_check: :yard_for_generate_documentation do
|
|
298
296
|
examples = YARD::Registry.all(:class).find do |code_object|
|
299
297
|
next unless RuboCop::Cop::Badge.for(code_object.to_s) == cop.badge
|
300
298
|
|
301
|
-
break code_object.tags(
|
299
|
+
break code_object.tags("example")
|
302
300
|
end
|
303
301
|
|
304
302
|
examples.to_a.each do |example|
|
305
|
-
buffer = Parser::Source::Buffer.new(
|
303
|
+
buffer = Parser::Source::Buffer.new("<code>", 1)
|
306
304
|
buffer.source = example.text
|
307
305
|
parser = Parser::Ruby25.new(RuboCop::AST::Builder.new)
|
308
306
|
parser.diagnostics.all_errors_are_fatal = true
|
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.
|
4
|
+
version: 0.6.3
|
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:
|
14
|
+
date: 2021-12-03 00:00:00.000000000 Z
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
17
17
|
name: rspec
|
@@ -31,30 +31,30 @@ dependencies:
|
|
31
31
|
name: unparser
|
32
32
|
requirement: !ruby/object:Gem::Requirement
|
33
33
|
requirements:
|
34
|
-
- - "
|
34
|
+
- - "~>"
|
35
35
|
- !ruby/object:Gem::Version
|
36
|
-
version: '0'
|
36
|
+
version: '0.6'
|
37
37
|
type: :development
|
38
38
|
prerelease: false
|
39
39
|
version_requirements: !ruby/object:Gem::Requirement
|
40
40
|
requirements:
|
41
|
-
- - "
|
41
|
+
- - "~>"
|
42
42
|
- !ruby/object:Gem::Version
|
43
|
-
version: '0'
|
43
|
+
version: '0.6'
|
44
44
|
- !ruby/object:Gem::Dependency
|
45
45
|
name: rubocop
|
46
46
|
requirement: !ruby/object:Gem::Requirement
|
47
47
|
requirements:
|
48
48
|
- - ">="
|
49
49
|
- !ruby/object:Gem::Version
|
50
|
-
version:
|
50
|
+
version: 0.90.0
|
51
51
|
type: :runtime
|
52
52
|
prerelease: false
|
53
53
|
version_requirements: !ruby/object:Gem::Requirement
|
54
54
|
requirements:
|
55
55
|
- - ">="
|
56
56
|
- !ruby/object:Gem::Version
|
57
|
-
version:
|
57
|
+
version: 0.90.0
|
58
58
|
description:
|
59
59
|
email:
|
60
60
|
- ruby@shopify.com
|
@@ -64,12 +64,12 @@ extra_rdoc_files: []
|
|
64
64
|
files:
|
65
65
|
- ".github/CODEOWNERS"
|
66
66
|
- ".github/probots.yml"
|
67
|
+
- ".github/release.yml"
|
67
68
|
- ".github/stale.yml"
|
69
|
+
- ".github/workflows/ci.yml"
|
68
70
|
- ".gitignore"
|
69
71
|
- ".rspec"
|
70
72
|
- ".rubocop.yml"
|
71
|
-
- ".shopify-build/VERSION"
|
72
|
-
- ".shopify-build/rubocop-sorbet.yml"
|
73
73
|
- ".travis.yml"
|
74
74
|
- CODE_OF_CONDUCT.md
|
75
75
|
- Gemfile
|
@@ -79,16 +79,25 @@ files:
|
|
79
79
|
- Rakefile
|
80
80
|
- bin/console
|
81
81
|
- bin/rspec
|
82
|
+
- bin/rubocop
|
82
83
|
- bin/setup
|
83
84
|
- config/default.yml
|
85
|
+
- config/rbi.yml
|
84
86
|
- dev.yml
|
85
87
|
- lib/rubocop-sorbet.rb
|
86
88
|
- lib/rubocop/cop/sorbet/binding_constants_without_type_alias.rb
|
89
|
+
- lib/rubocop/cop/sorbet/callback_conditionals_binding.rb
|
87
90
|
- lib/rubocop/cop/sorbet/constants_from_strings.rb
|
88
91
|
- lib/rubocop/cop/sorbet/forbid_include_const_literal.rb
|
89
92
|
- lib/rubocop/cop/sorbet/forbid_superclass_const_literal.rb
|
93
|
+
- lib/rubocop/cop/sorbet/forbid_t_unsafe.rb
|
90
94
|
- lib/rubocop/cop/sorbet/forbid_untyped_struct_props.rb
|
95
|
+
- lib/rubocop/cop/sorbet/one_ancestor_per_line.rb
|
96
|
+
- lib/rubocop/cop/sorbet/rbi/forbid_extend_t_sig_helpers_in_shims.rb
|
97
|
+
- lib/rubocop/cop/sorbet/rbi/forbid_rbi_outside_of_allowed_paths.rb
|
98
|
+
- lib/rubocop/cop/sorbet/rbi/single_line_rbi_class_module_definitions.rb
|
91
99
|
- lib/rubocop/cop/sorbet/sigils/enforce_sigil_order.rb
|
100
|
+
- lib/rubocop/cop/sorbet/sigils/enforce_single_sigil.rb
|
92
101
|
- lib/rubocop/cop/sorbet/sigils/false_sigil.rb
|
93
102
|
- lib/rubocop/cop/sorbet/sigils/has_sigil.rb
|
94
103
|
- lib/rubocop/cop/sorbet/sigils/ignore_sigil.rb
|
@@ -100,7 +109,6 @@ files:
|
|
100
109
|
- lib/rubocop/cop/sorbet/signatures/checked_true_in_signature.rb
|
101
110
|
- lib/rubocop/cop/sorbet/signatures/enforce_signatures.rb
|
102
111
|
- lib/rubocop/cop/sorbet/signatures/keyword_argument_ordering.rb
|
103
|
-
- lib/rubocop/cop/sorbet/signatures/parameters_ordering_in_signature.rb
|
104
112
|
- lib/rubocop/cop/sorbet/signatures/signature_build_order.rb
|
105
113
|
- lib/rubocop/cop/sorbet/signatures/signature_cop.rb
|
106
114
|
- lib/rubocop/cop/sorbet_cops.rb
|
@@ -135,7 +143,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
135
143
|
- !ruby/object:Gem::Version
|
136
144
|
version: '0'
|
137
145
|
requirements: []
|
138
|
-
rubygems_version: 3.
|
146
|
+
rubygems_version: 3.2.20
|
139
147
|
signing_key:
|
140
148
|
specification_version: 4
|
141
149
|
summary: Automatic Sorbet code style checking tool.
|
data/.shopify-build/VERSION
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
v1
|
@@ -1,16 +0,0 @@
|
|
1
|
-
containers:
|
2
|
-
default:
|
3
|
-
docker: "circleci/ruby:2.5.5"
|
4
|
-
|
5
|
-
steps:
|
6
|
-
- label: ":ruby: Specs"
|
7
|
-
dependencies:
|
8
|
-
- "bundler"
|
9
|
-
timeout: "5m"
|
10
|
-
run:
|
11
|
-
- "bundle exec rspec"
|
12
|
-
- label: "Rubocop"
|
13
|
-
dependencies:
|
14
|
-
- "bundler"
|
15
|
-
timeout: "5m"
|
16
|
-
run: "bundle exec rubocop"
|
@@ -1,70 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'rubocop'
|
4
|
-
require_relative 'signature_cop'
|
5
|
-
|
6
|
-
module RuboCop
|
7
|
-
module Cop
|
8
|
-
module Sorbet
|
9
|
-
# This cop checks for inconsistent ordering of parameters between the
|
10
|
-
# signature and the method definition. The sorbet-runtime gem raises
|
11
|
-
# when such inconsistency occurs.
|
12
|
-
#
|
13
|
-
# @example
|
14
|
-
#
|
15
|
-
# # bad
|
16
|
-
# sig { params(a: Integer, b: String).void }
|
17
|
-
# def foo(b:, a:); end
|
18
|
-
#
|
19
|
-
# # good
|
20
|
-
# sig { params(a: Integer, b: String).void }
|
21
|
-
# def foo(a:, b:); end
|
22
|
-
class ParametersOrderingInSignature < SignatureCop
|
23
|
-
def_node_search(:signature_params, <<-PATTERN)
|
24
|
-
(send _ :params ...)
|
25
|
-
PATTERN
|
26
|
-
|
27
|
-
def on_signature(node)
|
28
|
-
sig_params = signature_params(node).first
|
29
|
-
|
30
|
-
sig_params_order = extract_parameters(sig_params)
|
31
|
-
return if sig_params_order.nil?
|
32
|
-
method_node = node.parent.children[node.sibling_index + 1]
|
33
|
-
return if method_node.nil? || method_node.type != :def
|
34
|
-
method_parameters = method_node.arguments
|
35
|
-
|
36
|
-
check_for_inconsistent_param_ordering(sig_params_order, method_parameters)
|
37
|
-
end
|
38
|
-
|
39
|
-
private
|
40
|
-
|
41
|
-
def extract_parameters(sig_params)
|
42
|
-
return [] if sig_params.nil?
|
43
|
-
|
44
|
-
arguments = sig_params.arguments.first
|
45
|
-
return arguments.keys.map(&:value) if RuboCop::AST::HashNode === arguments
|
46
|
-
|
47
|
-
add_offense(
|
48
|
-
sig_params,
|
49
|
-
message: "Invalid signature."
|
50
|
-
)
|
51
|
-
end
|
52
|
-
|
53
|
-
def check_for_inconsistent_param_ordering(sig_params_order, parameters)
|
54
|
-
parameters.each_with_index do |param, index|
|
55
|
-
param_name = param.children[0]
|
56
|
-
sig_param_name = sig_params_order[index]
|
57
|
-
|
58
|
-
next if param_name == sig_param_name
|
59
|
-
|
60
|
-
add_offense(
|
61
|
-
param,
|
62
|
-
message: "Inconsistent ordering of arguments at index #{index}. " \
|
63
|
-
"Expected `#{sig_param_name}` from sig above."
|
64
|
-
)
|
65
|
-
end
|
66
|
-
end
|
67
|
-
end
|
68
|
-
end
|
69
|
-
end
|
70
|
-
end
|