rubocop-on-rbs 2.1.0 → 2.2.0
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/CHANGELOG.md +28 -0
- data/README.md +46 -0
- data/config/default.yml +109 -0
- data/lib/rubocop/cop/rbs/lint/ambiguous_keyword_argument_key.rb +2 -43
- data/lib/rubocop/cop/rbs/lint/duplicate_overload.rb +2 -25
- data/lib/rubocop/cop/rbs/lint/literal_intersection.rb +7 -38
- data/lib/rubocop/cop/rbs/lint/new_returns_void.rb +2 -17
- data/lib/rubocop/cop/rbs/lint/rest_keyword_hash.rb +2 -22
- data/lib/rubocop/cop/rbs/lint/unused_overload_type_params.rb +2 -41
- data/lib/rubocop/cop/rbs/mixin/ambiguous_keyword_argument_key.rb +59 -0
- data/lib/rubocop/cop/rbs/mixin/block_return_boolish.rb +32 -0
- data/lib/rubocop/cop/rbs/mixin/class_with_singleton.rb +44 -0
- data/lib/rubocop/cop/rbs/mixin/classic_type.rb +72 -0
- data/lib/rubocop/cop/rbs/mixin/duplicate_overload.rb +43 -0
- data/lib/rubocop/cop/rbs/mixin/duplicated_type.rb +59 -0
- data/lib/rubocop/cop/rbs/mixin/empty_argument.rb +167 -0
- data/lib/rubocop/cop/rbs/mixin/initialize_return_type.rb +35 -0
- data/lib/rubocop/cop/rbs/mixin/instance_with_instance.rb +54 -0
- data/lib/rubocop/cop/rbs/mixin/literal_intersection.rb +56 -0
- data/lib/rubocop/cop/rbs/mixin/new_returns_void.rb +33 -0
- data/lib/rubocop/cop/rbs/mixin/optional_nil.rb +58 -0
- data/lib/rubocop/cop/rbs/mixin/redundant_parentheses.rb +161 -0
- data/lib/rubocop/cop/rbs/mixin/rest_keyword_hash.rb +40 -0
- data/lib/rubocop/cop/rbs/mixin/true_false.rb +89 -0
- data/lib/rubocop/cop/rbs/mixin/unused_overload_type_params.rb +58 -0
- data/lib/rubocop/cop/rbs/style/block_return_boolish.rb +2 -16
- data/lib/rubocop/cop/rbs/style/class_with_singleton.rb +2 -29
- data/lib/rubocop/cop/rbs/style/classic_type.rb +7 -56
- data/lib/rubocop/cop/rbs/style/duplicated_type.rb +7 -44
- data/lib/rubocop/cop/rbs/style/empty_argument.rb +7 -145
- data/lib/rubocop/cop/rbs/style/initialize_return_type.rb +2 -18
- data/lib/rubocop/cop/rbs/style/instance_with_instance.rb +2 -38
- data/lib/rubocop/cop/rbs/style/optional_nil.rb +7 -40
- data/lib/rubocop/cop/rbs/style/redundant_parentheses.rb +3 -141
- data/lib/rubocop/cop/rbs/style/true_false.rb +7 -71
- data/lib/rubocop/cop/rbs_cops.rb +17 -0
- data/lib/rubocop/cop/rbs_inline/lint/ambiguous_keyword_argument_key.rb +28 -0
- data/lib/rubocop/cop/rbs_inline/lint/duplicate_overload.rb +31 -0
- data/lib/rubocop/cop/rbs_inline/lint/literal_intersection.rb +31 -0
- data/lib/rubocop/cop/rbs_inline/lint/new_returns_void.rb +28 -0
- data/lib/rubocop/cop/rbs_inline/lint/rest_keyword_hash.rb +31 -0
- data/lib/rubocop/cop/rbs_inline/lint/syntax.rb +40 -0
- data/lib/rubocop/cop/rbs_inline/lint/unused_annotation.rb +41 -0
- data/lib/rubocop/cop/rbs_inline/lint/unused_overload_type_params.rb +28 -0
- data/lib/rubocop/cop/rbs_inline/style/block_return_boolish.rb +27 -0
- data/lib/rubocop/cop/rbs_inline/style/class_with_singleton.rb +29 -0
- data/lib/rubocop/cop/rbs_inline/style/classic_type.rb +38 -0
- data/lib/rubocop/cop/rbs_inline/style/duplicated_type.rb +37 -0
- data/lib/rubocop/cop/rbs_inline/style/empty_argument.rb +42 -0
- data/lib/rubocop/cop/rbs_inline/style/initialize_return_type.rb +37 -0
- data/lib/rubocop/cop/rbs_inline/style/instance_with_instance.rb +29 -0
- data/lib/rubocop/cop/rbs_inline/style/optional_nil.rb +32 -0
- data/lib/rubocop/cop/rbs_inline/style/redundant_parentheses.rb +96 -0
- data/lib/rubocop/cop/rbs_inline/style/true_false.rb +37 -0
- data/lib/rubocop/cop/rbs_inline_cops.rb +21 -0
- data/lib/rubocop/rbs/cop_base.rb +5 -34
- data/lib/rubocop/rbs/cop_helper.rb +22 -0
- data/lib/rubocop/rbs/version.rb +1 -1
- data/lib/rubocop/rbs_inline/cop_base.rb +110 -0
- data/lib/rubocop/rbs_inline/processed_inline_source.rb +33 -0
- data/lib/rubocop-on-rbs.rb +4 -0
- metadata +39 -15
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: '08ba6bad1ed2be5adfb8b5afeaf6917521e98618a7279354231e637727774177'
|
|
4
|
+
data.tar.gz: 9e1ac97d25171ec66ad0815bab269e652ce10b159cb372aad2bd9b0baeeb4913
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: f8a8c23cfaffc12e440c3b0b8ab6e122e6d68352c481b0b548183329c36967b275627131b25b6a7123da202c84c93e2b2442735f3080fac20b148da12f7c4561
|
|
7
|
+
data.tar.gz: 800caf959a981ead103d76f611a69ec61ce4828d7e620c48bab82a621b21eea1ca8bccf90bb4c6a7fe6080c155bc29cf2bd6c0886e3707a67e8ae3da3d718581
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,33 @@
|
|
|
1
1
|
## [Unreleased]
|
|
2
2
|
|
|
3
|
+
## [2.2.0] - 2026-09-28
|
|
4
|
+
|
|
5
|
+
* Mark all `RBSInline/*` cops as `Enabled: pending` by @ksss in https://github.com/ksss/rubocop-on-rbs/pull/164
|
|
6
|
+
* They will be enabled by default in v3.0.0. Use `NewCops: enable` to enable them now.
|
|
7
|
+
* Add `RBSInline` department for RBS inline annotations in Ruby files by @ksss in https://github.com/ksss/rubocop-on-rbs/pull/159
|
|
8
|
+
* `RBSInline/Lint/Syntax`
|
|
9
|
+
* `RBSInline/Lint/UnusedAnnotation`
|
|
10
|
+
* Replace crc32 cache with `ObjectSpace::WeakKeyMap` and drop `zlib` dependency by @ksss in https://github.com/ksss/rubocop-on-rbs/pull/160
|
|
11
|
+
* Add `RBSInline/Style` department by @ksss in https://github.com/ksss/rubocop-on-rbs/pull/161
|
|
12
|
+
* `RBSInline/Style/BlockReturnBoolish`
|
|
13
|
+
* `RBSInline/Style/ClassWithSingleton`
|
|
14
|
+
* `RBSInline/Style/ClassicType`
|
|
15
|
+
* `RBSInline/Style/DuplicatedType`
|
|
16
|
+
* `RBSInline/Style/EmptyArgument`
|
|
17
|
+
* `RBSInline/Style/InitializeReturnType`
|
|
18
|
+
* `RBSInline/Style/InstanceWithInstance`
|
|
19
|
+
* `RBSInline/Style/OptionalNil`
|
|
20
|
+
* `RBSInline/Style/RedundantParentheses`
|
|
21
|
+
* `RBSInline/Style/TrueFalse`
|
|
22
|
+
* Drop steep by @ksss in https://github.com/ksss/rubocop-on-rbs/pull/162
|
|
23
|
+
* Add `RBSInline/Lint` cops sharing implementation with `RBS/Lint` by @ksss in https://github.com/ksss/rubocop-on-rbs/pull/163
|
|
24
|
+
* `RBSInline/Lint/AmbiguousKeywordArgumentKey`
|
|
25
|
+
* `RBSInline/Lint/DuplicateOverload`
|
|
26
|
+
* `RBSInline/Lint/LiteralIntersection`
|
|
27
|
+
* `RBSInline/Lint/NewReturnsVoid`
|
|
28
|
+
* `RBSInline/Lint/RestKeywordHash`
|
|
29
|
+
* `RBSInline/Lint/UnusedOverloadTypeParams`
|
|
30
|
+
|
|
3
31
|
## [2.1.0] - 2026-09-27
|
|
4
32
|
|
|
5
33
|
* Drop support for Ruby v3.2 by @ksss in https://github.com/ksss/rubocop-on-rbs/pull/153
|
data/README.md
CHANGED
|
@@ -104,6 +104,52 @@ RBS/Style:
|
|
|
104
104
|
$ bundle exec rubocop --only RBS/Style
|
|
105
105
|
```
|
|
106
106
|
|
|
107
|
+
### RBSInline
|
|
108
|
+
|
|
109
|
+
Cops for RBS inline annotations (`#: String`, `# @rbs x: Integer`) written in Ruby files.
|
|
110
|
+
They are separated from `RBS/*` cops and run only on Ruby files that contain annotations.
|
|
111
|
+
|
|
112
|
+
All `RBSInline/*` cops are `pending` in v2.x and will be enabled by default in v3.0.0.
|
|
113
|
+
To enable them now, set `NewCops: enable` in your `.rubocop.yml`:
|
|
114
|
+
|
|
115
|
+
```yaml
|
|
116
|
+
AllCops:
|
|
117
|
+
NewCops: enable
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
Or enable only the `RBSInline` department (requires RuboCop 1.89+):
|
|
121
|
+
|
|
122
|
+
```yaml
|
|
123
|
+
RBSInline:
|
|
124
|
+
NewCops: enable
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
### RBSInline/Lint
|
|
128
|
+
|
|
129
|
+
Same as `RBS/Lint`, but for inline annotations.
|
|
130
|
+
|
|
131
|
+
```yaml
|
|
132
|
+
RBSInline/Lint:
|
|
133
|
+
Enabled: true
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
```console
|
|
137
|
+
$ bundle exec rubocop --only RBSInline/Lint
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
### RBSInline/Style
|
|
141
|
+
|
|
142
|
+
Same as `RBS/Style`, but for inline annotations.
|
|
143
|
+
|
|
144
|
+
```yaml
|
|
145
|
+
RBSInline/Style:
|
|
146
|
+
Enabled: true
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
```console
|
|
150
|
+
$ bundle exec rubocop --only RBSInline/Style
|
|
151
|
+
```
|
|
152
|
+
|
|
107
153
|
## Installation
|
|
108
154
|
|
|
109
155
|
Install the gem and add to the application's Gemfile by executing:
|
data/config/default.yml
CHANGED
|
@@ -222,3 +222,112 @@ RBS/Style/RedundantParentheses:
|
|
|
222
222
|
RBS/Style/TrueFalse:
|
|
223
223
|
Description: 'Use bool instead of true | false'
|
|
224
224
|
Enabled: true
|
|
225
|
+
|
|
226
|
+
# RBSInline
|
|
227
|
+
|
|
228
|
+
RBSInline:
|
|
229
|
+
Enabled: true
|
|
230
|
+
|
|
231
|
+
## RBSInline/Lint
|
|
232
|
+
|
|
233
|
+
RBSInline/Lint:
|
|
234
|
+
Enabled: true
|
|
235
|
+
|
|
236
|
+
RBSInline/Lint/AmbiguousKeywordArgumentKey:
|
|
237
|
+
Description: 'Check ambiguous keyword argument key'
|
|
238
|
+
Enabled: pending
|
|
239
|
+
VersionAdded: '2.2.0'
|
|
240
|
+
|
|
241
|
+
RBSInline/Lint/DuplicateOverload:
|
|
242
|
+
Description: 'Checks that there are no repeated overload bodies'
|
|
243
|
+
Enabled: pending
|
|
244
|
+
VersionAdded: '2.2.0'
|
|
245
|
+
|
|
246
|
+
RBSInline/Lint/LiteralIntersection:
|
|
247
|
+
Description: 'Check literal intersection'
|
|
248
|
+
Enabled: pending
|
|
249
|
+
VersionAdded: '2.2.0'
|
|
250
|
+
|
|
251
|
+
RBSInline/Lint/NewReturnsVoid:
|
|
252
|
+
Description: 'sigleton `new` method should not returns `void` type'
|
|
253
|
+
Enabled: pending
|
|
254
|
+
VersionAdded: '2.2.0'
|
|
255
|
+
|
|
256
|
+
RBSInline/Lint/RestKeywordHash:
|
|
257
|
+
Description: 'Check rest keyword with `Hash` type'
|
|
258
|
+
Enabled: pending
|
|
259
|
+
VersionAdded: '2.2.0'
|
|
260
|
+
|
|
261
|
+
RBSInline/Lint/Syntax:
|
|
262
|
+
Severity: error
|
|
263
|
+
Description: 'Check RBS inline annotation syntax'
|
|
264
|
+
Enabled: pending
|
|
265
|
+
VersionAdded: '2.2.0'
|
|
266
|
+
AllowedPatterns:
|
|
267
|
+
# Embedded RBS by rbs-inline gem. Not supported by RBS::InlineParser.
|
|
268
|
+
- '\A# @rbs!'
|
|
269
|
+
|
|
270
|
+
RBSInline/Lint/UnusedAnnotation:
|
|
271
|
+
Description: 'Check unused RBS inline annotation'
|
|
272
|
+
Enabled: pending
|
|
273
|
+
VersionAdded: '2.2.0'
|
|
274
|
+
|
|
275
|
+
RBSInline/Lint/UnusedOverloadTypeParams:
|
|
276
|
+
Description: 'Check redundant overload type params'
|
|
277
|
+
Enabled: pending
|
|
278
|
+
VersionAdded: '2.2.0'
|
|
279
|
+
|
|
280
|
+
## RBSInline/Style
|
|
281
|
+
|
|
282
|
+
RBSInline/Style:
|
|
283
|
+
Enabled: true
|
|
284
|
+
|
|
285
|
+
RBSInline/Style/BlockReturnBoolish:
|
|
286
|
+
Description: 'Use `bool` for block return type'
|
|
287
|
+
Enabled: pending
|
|
288
|
+
VersionAdded: '2.2.0'
|
|
289
|
+
|
|
290
|
+
RBSInline/Style/ClassWithSingleton:
|
|
291
|
+
Description: 'Check `class` with singleton context'
|
|
292
|
+
Enabled: pending
|
|
293
|
+
VersionAdded: '2.2.0'
|
|
294
|
+
|
|
295
|
+
RBSInline/Style/ClassicType:
|
|
296
|
+
Description: 'Use simple type'
|
|
297
|
+
Enabled: pending
|
|
298
|
+
VersionAdded: '2.2.0'
|
|
299
|
+
|
|
300
|
+
RBSInline/Style/DuplicatedType:
|
|
301
|
+
Description: 'Check duplicated type'
|
|
302
|
+
Enabled: pending
|
|
303
|
+
VersionAdded: '2.2.0'
|
|
304
|
+
|
|
305
|
+
RBSInline/Style/EmptyArgument:
|
|
306
|
+
Description: 'Use `()` for empty argument'
|
|
307
|
+
Enabled: pending
|
|
308
|
+
VersionAdded: '2.2.0'
|
|
309
|
+
|
|
310
|
+
RBSInline/Style/InitializeReturnType:
|
|
311
|
+
Description: 'Use `void` for initialize method'
|
|
312
|
+
Enabled: pending
|
|
313
|
+
VersionAdded: '2.2.0'
|
|
314
|
+
|
|
315
|
+
RBSInline/Style/InstanceWithInstance:
|
|
316
|
+
Description: 'Check `instance` with instance context'
|
|
317
|
+
Enabled: pending
|
|
318
|
+
VersionAdded: '2.2.0'
|
|
319
|
+
|
|
320
|
+
RBSInline/Style/OptionalNil:
|
|
321
|
+
Description: 'Use nil instead of nil?'
|
|
322
|
+
Enabled: pending
|
|
323
|
+
VersionAdded: '2.2.0'
|
|
324
|
+
|
|
325
|
+
RBSInline/Style/RedundantParentheses:
|
|
326
|
+
Description: 'Remove redundant parentheses'
|
|
327
|
+
Enabled: pending
|
|
328
|
+
VersionAdded: '2.2.0'
|
|
329
|
+
|
|
330
|
+
RBSInline/Style/TrueFalse:
|
|
331
|
+
Description: 'Use bool instead of true | false'
|
|
332
|
+
Enabled: pending
|
|
333
|
+
VersionAdded: '2.2.0'
|
|
@@ -11,51 +11,10 @@ module RuboCop
|
|
|
11
11
|
# def foo: (option?: bool, option!: bool, Option: bool) -> void
|
|
12
12
|
#
|
|
13
13
|
class AmbiguousKeywordArgumentKey < RuboCop::RBS::CopBase
|
|
14
|
+
include RuboCop::Cop::RBS::Mixin::AmbiguousKeywordArgumentKey
|
|
14
15
|
extend AutoCorrector
|
|
15
16
|
|
|
16
|
-
|
|
17
|
-
def on_rbs_def(decl)
|
|
18
|
-
decl.overloads.each do |overload|
|
|
19
|
-
func = overload.method_type.type
|
|
20
|
-
next unless func.kind_of?(::RBS::Types::Function)
|
|
21
|
-
next unless !func.required_keywords.empty? || !func.optional_keywords.empty?
|
|
22
|
-
|
|
23
|
-
location = overload.method_type.location or next
|
|
24
|
-
base_pos = location.start_pos
|
|
25
|
-
lex_result = ::RBS::Parser.lex(location.source)
|
|
26
|
-
buf = []
|
|
27
|
-
lex_result.value.each do |token|
|
|
28
|
-
case token.type
|
|
29
|
-
when :pLPAREN, :pRPAREN, :tTRIVIA
|
|
30
|
-
# skip
|
|
31
|
-
when :pCOLON
|
|
32
|
-
next if buf.empty?
|
|
33
|
-
|
|
34
|
-
case buf.last.type
|
|
35
|
-
when :pQUESTION
|
|
36
|
-
buf.shift if buf.first.type == :pQUESTION
|
|
37
|
-
actual = buf.map { |t| t.location.source }.join
|
|
38
|
-
did_you_mean = buf.reject { |t| t.location.source == '?' }.map { |t| t.location.source }.join
|
|
39
|
-
message = +"`#{actual}` is not local variable name."
|
|
40
|
-
if did_you_mean.length > 0
|
|
41
|
-
message << " Did you mean `?#{did_you_mean}` for optional keyword argument?"
|
|
42
|
-
end
|
|
43
|
-
range = range_between(buf.first.location.start_pos + base_pos, buf.last.location.end_pos + base_pos)
|
|
44
|
-
add_offense(range, message: message)
|
|
45
|
-
when :tBANGIDENT, :tUIDENT
|
|
46
|
-
buf.shift if buf.first.type == :pQUESTION
|
|
47
|
-
actual = buf.map { |t| t.location.source }.join
|
|
48
|
-
range = range_between(buf.first.location.start_pos + base_pos, buf.last.location.end_pos + base_pos)
|
|
49
|
-
add_offense(range, message: "`#{actual}` is not local variable name.")
|
|
50
|
-
end
|
|
51
|
-
when :pCOMMA
|
|
52
|
-
buf.clear
|
|
53
|
-
else
|
|
54
|
-
buf << token
|
|
55
|
-
end
|
|
56
|
-
end
|
|
57
|
-
end
|
|
58
|
-
end
|
|
17
|
+
alias on_rbs_def check_def
|
|
59
18
|
end
|
|
60
19
|
end
|
|
61
20
|
end
|
|
@@ -13,32 +13,9 @@ module RuboCop
|
|
|
13
13
|
# | () -> top
|
|
14
14
|
#
|
|
15
15
|
class DuplicateOverload < RuboCop::RBS::CopBase
|
|
16
|
-
|
|
16
|
+
include RuboCop::Cop::RBS::Mixin::DuplicateOverload
|
|
17
17
|
|
|
18
|
-
|
|
19
|
-
overloads = decl.overloads
|
|
20
|
-
overloads.each_with_index do |overload, idx|
|
|
21
|
-
next if idx == overloads.size - 1
|
|
22
|
-
|
|
23
|
-
next_overloads = overloads[(idx + 1)..-1] or next
|
|
24
|
-
next_overloads.each do |next_overload|
|
|
25
|
-
a = method_type_with_untyped_return_type(overload.method_type)
|
|
26
|
-
b = method_type_with_untyped_return_type(next_overload.method_type)
|
|
27
|
-
next unless a == b
|
|
28
|
-
|
|
29
|
-
location = next_overload.method_type.location or next
|
|
30
|
-
range = location_to_range(location)
|
|
31
|
-
add_offense(range)
|
|
32
|
-
end
|
|
33
|
-
end
|
|
34
|
-
end
|
|
35
|
-
|
|
36
|
-
private
|
|
37
|
-
|
|
38
|
-
def method_type_with_untyped_return_type(method_type)
|
|
39
|
-
type = method_type.type.with_return_type(::RBS::Types::Bases::Any.new(location: nil))
|
|
40
|
-
method_type.update(type:)
|
|
41
|
-
end
|
|
18
|
+
alias on_rbs_def check_def
|
|
42
19
|
end
|
|
43
20
|
end
|
|
44
21
|
end
|
|
@@ -14,45 +14,14 @@ module RuboCop
|
|
|
14
14
|
# 1 & _Foo
|
|
15
15
|
#
|
|
16
16
|
class LiteralIntersection < RuboCop::RBS::CopBase
|
|
17
|
-
|
|
17
|
+
include RuboCop::Cop::RBS::Mixin::LiteralIntersection
|
|
18
18
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
end
|
|
26
|
-
|
|
27
|
-
def check_type(type)
|
|
28
|
-
on_type([::RBS::Types::Intersection], type) do |intersection|
|
|
29
|
-
check_intersection(intersection)
|
|
30
|
-
end
|
|
31
|
-
end
|
|
32
|
-
|
|
33
|
-
def on_rbs_constant(type)
|
|
34
|
-
check_type(type.type)
|
|
35
|
-
end
|
|
36
|
-
alias on_rbs_global on_rbs_constant
|
|
37
|
-
alias on_rbs_type_alias on_rbs_constant
|
|
38
|
-
alias on_rbs_attribute on_rbs_constant
|
|
39
|
-
alias on_rbs_var on_rbs_constant
|
|
40
|
-
|
|
41
|
-
def check_intersection(intersection)
|
|
42
|
-
intersection.types.each do |type|
|
|
43
|
-
check_intersection_child(type)
|
|
44
|
-
end
|
|
45
|
-
end
|
|
46
|
-
|
|
47
|
-
def check_intersection_child(type)
|
|
48
|
-
case type
|
|
49
|
-
when ::RBS::Types::Literal
|
|
50
|
-
range = location_to_range(type.location)
|
|
51
|
-
add_offense(range)
|
|
52
|
-
when ::RBS::Types::Intersection
|
|
53
|
-
check_intersection(type)
|
|
54
|
-
end
|
|
55
|
-
end
|
|
19
|
+
alias on_rbs_def check_def
|
|
20
|
+
alias on_rbs_constant check_member
|
|
21
|
+
alias on_rbs_global check_member
|
|
22
|
+
alias on_rbs_type_alias check_member
|
|
23
|
+
alias on_rbs_attribute check_member
|
|
24
|
+
alias on_rbs_var check_member
|
|
56
25
|
end
|
|
57
26
|
end
|
|
58
27
|
end
|
|
@@ -16,24 +16,9 @@ module RuboCop
|
|
|
16
16
|
# def self.new: () -> instance
|
|
17
17
|
#
|
|
18
18
|
class NewReturnsVoid < RuboCop::RBS::CopBase
|
|
19
|
-
|
|
19
|
+
include RuboCop::Cop::RBS::Mixin::NewReturnsVoid
|
|
20
20
|
|
|
21
|
-
|
|
22
|
-
def on_rbs_def(decl)
|
|
23
|
-
return unless decl.kind == :singleton
|
|
24
|
-
return unless decl.name == :new
|
|
25
|
-
|
|
26
|
-
decl.overloads.each do |overload|
|
|
27
|
-
return_type = overload.method_type.type.return_type
|
|
28
|
-
case return_type
|
|
29
|
-
when ::RBS::Types::Bases::Void
|
|
30
|
-
next unless return_type.location
|
|
31
|
-
|
|
32
|
-
range = location_to_range(return_type.location)
|
|
33
|
-
add_offense(range)
|
|
34
|
-
end
|
|
35
|
-
end
|
|
36
|
-
end
|
|
21
|
+
alias on_rbs_def check_def
|
|
37
22
|
end
|
|
38
23
|
end
|
|
39
24
|
end
|
|
@@ -17,29 +17,9 @@ module RuboCop
|
|
|
17
17
|
# # e.g.) foo(a: "x", b: "y", c: "z")
|
|
18
18
|
#
|
|
19
19
|
class RestKeywordHash < RuboCop::RBS::CopBase
|
|
20
|
-
|
|
21
|
-
decl.overloads.each do |overload|
|
|
22
|
-
func = overload.method_type.type
|
|
23
|
-
next unless func.is_a?(::RBS::Types::Function)
|
|
20
|
+
include RuboCop::Cop::RBS::Mixin::RestKeywordHash
|
|
24
21
|
|
|
25
|
-
|
|
26
|
-
check_type(func.rest_keywords.type)
|
|
27
|
-
end
|
|
28
|
-
end
|
|
29
|
-
end
|
|
30
|
-
|
|
31
|
-
def check_type(type)
|
|
32
|
-
case type
|
|
33
|
-
when ::RBS::Types::ClassInstance
|
|
34
|
-
if type.name.relative!.to_s == 'Hash'
|
|
35
|
-
did_you_mean = type.args[1] or return
|
|
36
|
-
range = location_to_range(type.location)
|
|
37
|
-
message = "The type of `**` specifies only the type of value. " \
|
|
38
|
-
"Did you mean `**#{did_you_mean}`?"
|
|
39
|
-
add_offense(range, message:)
|
|
40
|
-
end
|
|
41
|
-
end
|
|
42
|
-
end
|
|
22
|
+
alias on_rbs_def check_def
|
|
43
23
|
end
|
|
44
24
|
end
|
|
45
25
|
end
|
|
@@ -14,48 +14,9 @@ module RuboCop
|
|
|
14
14
|
# def foo: [T] (T) -> T
|
|
15
15
|
#
|
|
16
16
|
class UnusedOverloadTypeParams < RuboCop::RBS::CopBase
|
|
17
|
-
|
|
17
|
+
include RuboCop::Cop::RBS::Mixin::UnusedOverloadTypeParams
|
|
18
18
|
|
|
19
|
-
|
|
20
|
-
decl.overloads.each do |overload|
|
|
21
|
-
next if overload.method_type.type_params.empty?
|
|
22
|
-
|
|
23
|
-
type_params = overload.method_type.type_params.dup
|
|
24
|
-
map = type_params.to_h { |param| [param.name, param] }
|
|
25
|
-
type_params.each do |type_param|
|
|
26
|
-
if type_param.upper_bound
|
|
27
|
-
used_variable_in_type(type_param.upper_bound) do |var|
|
|
28
|
-
map.delete(var.name)
|
|
29
|
-
end
|
|
30
|
-
end
|
|
31
|
-
end
|
|
32
|
-
|
|
33
|
-
overload.method_type.each_type do |type|
|
|
34
|
-
used_variable_in_type(type) do |var|
|
|
35
|
-
map.delete(var.name)
|
|
36
|
-
end
|
|
37
|
-
end
|
|
38
|
-
next if map.empty?
|
|
39
|
-
|
|
40
|
-
map.each do |name, type_param|
|
|
41
|
-
next unless type_param.location
|
|
42
|
-
|
|
43
|
-
t = location_to_range(type_param.location[:name])
|
|
44
|
-
add_offense(t, message: format(MSG, variable: name))
|
|
45
|
-
end
|
|
46
|
-
end
|
|
47
|
-
end
|
|
48
|
-
|
|
49
|
-
def used_variable_in_type(type, &block)
|
|
50
|
-
case type
|
|
51
|
-
when ::RBS::Types::Variable
|
|
52
|
-
yield type
|
|
53
|
-
else
|
|
54
|
-
type.each_type do |t|
|
|
55
|
-
used_variable_in_type(t, &block)
|
|
56
|
-
end
|
|
57
|
-
end
|
|
58
|
-
end
|
|
19
|
+
alias on_rbs_def check_def
|
|
59
20
|
end
|
|
60
21
|
end
|
|
61
22
|
end
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module RuboCop
|
|
4
|
+
module Cop
|
|
5
|
+
module RBS
|
|
6
|
+
module Mixin
|
|
7
|
+
# Shared implementation of `RBS/Lint/AmbiguousKeywordArgumentKey`
|
|
8
|
+
# and `RBSInline/Lint/AmbiguousKeywordArgumentKey`.
|
|
9
|
+
# @rbs module-self: RuboCop::Cop::Base
|
|
10
|
+
# @rbs module-self: RuboCop::RBS::CopHelper
|
|
11
|
+
module AmbiguousKeywordArgumentKey
|
|
12
|
+
#: (::RBS::AST::Members::MethodDefinition | ::RBS::AST::Ruby::Members::DefMember decl) -> void
|
|
13
|
+
def check_def(decl)
|
|
14
|
+
decl.overloads.each do |overload|
|
|
15
|
+
func = overload.method_type.type
|
|
16
|
+
next unless func.kind_of?(::RBS::Types::Function)
|
|
17
|
+
next unless !func.required_keywords.empty? || !func.optional_keywords.empty?
|
|
18
|
+
|
|
19
|
+
location = overload.method_type.location or next
|
|
20
|
+
base_pos = location.start_pos
|
|
21
|
+
lex_result = ::RBS::Parser.lex(location.source)
|
|
22
|
+
buf = []
|
|
23
|
+
lex_result.value.each do |token|
|
|
24
|
+
case token.type
|
|
25
|
+
when :pLPAREN, :pRPAREN, :tTRIVIA
|
|
26
|
+
# skip
|
|
27
|
+
when :pCOLON
|
|
28
|
+
next if buf.empty?
|
|
29
|
+
|
|
30
|
+
case buf.last.type
|
|
31
|
+
when :pQUESTION
|
|
32
|
+
buf.shift if buf.first.type == :pQUESTION
|
|
33
|
+
actual = buf.map { |t| t.location.source }.join
|
|
34
|
+
did_you_mean = buf.reject { |t| t.location.source == '?' }.map { |t| t.location.source }.join
|
|
35
|
+
message = +"`#{actual}` is not local variable name."
|
|
36
|
+
if did_you_mean.length > 0
|
|
37
|
+
message << " Did you mean `?#{did_you_mean}` for optional keyword argument?"
|
|
38
|
+
end
|
|
39
|
+
range = range_between(buf.first.location.start_pos + base_pos, buf.last.location.end_pos + base_pos)
|
|
40
|
+
add_offense(range, message: message)
|
|
41
|
+
when :tBANGIDENT, :tUIDENT
|
|
42
|
+
buf.shift if buf.first.type == :pQUESTION
|
|
43
|
+
actual = buf.map { |t| t.location.source }.join
|
|
44
|
+
range = range_between(buf.first.location.start_pos + base_pos, buf.last.location.end_pos + base_pos)
|
|
45
|
+
add_offense(range, message: "`#{actual}` is not local variable name.")
|
|
46
|
+
end
|
|
47
|
+
when :pCOMMA
|
|
48
|
+
buf.clear
|
|
49
|
+
else
|
|
50
|
+
buf << token
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module RuboCop
|
|
4
|
+
module Cop
|
|
5
|
+
module RBS
|
|
6
|
+
module Mixin
|
|
7
|
+
# Shared implementation of `RBS/Style/BlockReturnBoolish` and `RBSInline/Style/BlockReturnBoolish`.
|
|
8
|
+
# @rbs module-self: RuboCop::Cop::Base
|
|
9
|
+
# @rbs module-self: RuboCop::RBS::CopHelper
|
|
10
|
+
module BlockReturnBoolish
|
|
11
|
+
MSG = 'Use `boolish` instead of `bool` in block return type.'
|
|
12
|
+
|
|
13
|
+
#: (::RBS::AST::Members::MethodDefinition | ::RBS::AST::Ruby::Members::DefMember decl) -> void
|
|
14
|
+
def check_def(decl)
|
|
15
|
+
decl.overloads.each do |overload|
|
|
16
|
+
next unless overload.method_type.block
|
|
17
|
+
|
|
18
|
+
return_type = overload.method_type.block.type.return_type
|
|
19
|
+
next unless return_type.is_a?(::RBS::Types::Bases::Bool)
|
|
20
|
+
next unless return_type.location
|
|
21
|
+
|
|
22
|
+
range = location_to_range(return_type.location)
|
|
23
|
+
add_offense(range) do |corrector|
|
|
24
|
+
corrector.replace(range, 'boolish')
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module RuboCop
|
|
4
|
+
module Cop
|
|
5
|
+
module RBS
|
|
6
|
+
module Mixin
|
|
7
|
+
# Shared implementation of `RBS/Style/ClassWithSingleton` and `RBSInline/Style/ClassWithSingleton`.
|
|
8
|
+
# @rbs module-self: RuboCop::Cop::Base
|
|
9
|
+
# @rbs module-self: RuboCop::RBS::CopHelper
|
|
10
|
+
module ClassWithSingleton
|
|
11
|
+
MSG = 'Use `self` instead of `class`.'
|
|
12
|
+
|
|
13
|
+
#: (::RBS::AST::Members::MethodDefinition | ::RBS::AST::Ruby::Members::DefMember decl) -> void
|
|
14
|
+
def check_def(decl)
|
|
15
|
+
return unless decl.kind == :singleton
|
|
16
|
+
|
|
17
|
+
decl.overloads.each do |overload|
|
|
18
|
+
overload.method_type.each_type do |type|
|
|
19
|
+
check_type(type)
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
#: (::RBS::Types::t type) -> void
|
|
25
|
+
def check_type(type)
|
|
26
|
+
case type
|
|
27
|
+
when ::RBS::Types::Bases::Class
|
|
28
|
+
return unless type.location
|
|
29
|
+
|
|
30
|
+
range = location_to_range(type.location)
|
|
31
|
+
add_offense(range) do |corrector|
|
|
32
|
+
corrector.replace(range, 'self')
|
|
33
|
+
end
|
|
34
|
+
else
|
|
35
|
+
type.each_type do |t|
|
|
36
|
+
check_type(t)
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module RuboCop
|
|
4
|
+
module Cop
|
|
5
|
+
module RBS
|
|
6
|
+
module Mixin
|
|
7
|
+
# Shared implementation of `RBS/Style/ClassicType` and `RBSInline/Style/ClassicType`.
|
|
8
|
+
# @rbs module-self: RuboCop::Cop::Base
|
|
9
|
+
# @rbs module-self: RuboCop::RBS::CopHelper
|
|
10
|
+
module ClassicType
|
|
11
|
+
Types = ::RBS::Types #: module-alias
|
|
12
|
+
|
|
13
|
+
#: (::RBS::AST::Members::MethodDefinition | ::RBS::AST::Ruby::Members::DefMember decl) -> void
|
|
14
|
+
def check_def(decl)
|
|
15
|
+
decl.overloads.each do |overload|
|
|
16
|
+
overload.method_type.each_type do |type|
|
|
17
|
+
check_type(type)
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
#: (untyped member) -> void
|
|
23
|
+
def check_member(member)
|
|
24
|
+
type = member.type
|
|
25
|
+
check_type(type) if type&.location
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
#: (::RBS::Types::t type) -> untyped
|
|
29
|
+
def check_type(type)
|
|
30
|
+
find_replacement(type) do |t, replaced|
|
|
31
|
+
location = t.location or next
|
|
32
|
+
|
|
33
|
+
range = location_to_range(location)
|
|
34
|
+
add_offense(range, message: "Use `#{replaced}` instead of `#{t}`") do |corrector|
|
|
35
|
+
corrector.replace(range, replaced)
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
#: (::RBS::Types::t type) ?{ ([::RBS::Types::t, String]) -> untyped } -> untyped
|
|
41
|
+
def find_replacement(type, &block)
|
|
42
|
+
case type
|
|
43
|
+
when Types::Record,
|
|
44
|
+
Types::Tuple,
|
|
45
|
+
Types::Union,
|
|
46
|
+
Types::Intersection,
|
|
47
|
+
Types::Optional,
|
|
48
|
+
Types::Proc,
|
|
49
|
+
Types::Alias,
|
|
50
|
+
Types::Interface
|
|
51
|
+
type.each_type do |t|
|
|
52
|
+
find_replacement(t, &block)
|
|
53
|
+
end
|
|
54
|
+
when Types::ClassInstance
|
|
55
|
+
case type.name.to_s
|
|
56
|
+
when 'TrueClass', '::TrueClass'
|
|
57
|
+
block&.call([type, 'true'])
|
|
58
|
+
when 'FalseClass', '::FalseClass'
|
|
59
|
+
block&.call([type, 'false'])
|
|
60
|
+
when 'NilClass', '::NilClass'
|
|
61
|
+
block&.call([type, 'nil'])
|
|
62
|
+
end
|
|
63
|
+
type.each_type do |arg|
|
|
64
|
+
find_replacement(arg, &block)
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
end
|