rubocop-on-rbs 0.4.0 → 0.6.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 +20 -0
- data/config/default.yml +5 -5
- data/lib/rubocop/cop/rbs/lint/useless_overload_type_params.rb +1 -1
- data/lib/rubocop/cop/rbs/style/empty_argument.rb +124 -57
- data/lib/rubocop/rbs/cop_base.rb +29 -24
- data/lib/rubocop/rbs/on_type_helper.rb +29 -0
- data/lib/rubocop/rbs/processed_rbs_source.rb +4 -0
- data/lib/rubocop/rbs/version.rb +1 -1
- data/lib/rubocop-on-rbs.rb +1 -0
- metadata +20 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 05fc386350ef8ab36fc84937e1c3d5f2abdd95e816c8fc4a3ce80f41791475aa
|
4
|
+
data.tar.gz: 5b38f37836d5858ff196abd454bbfa14432ffdca49f8e89cfc88e61490da6d61
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4845db99745dab9b0c833fc4bf67e848aab97ed5cbe9e23279d2cf6ff867d100357dac144a261e1af279b415aa49848603a631caac38ea9f4b3a7a2732097001
|
7
|
+
data.tar.gz: e316da95415babf17a4e9d8d59008e6cf9a47ccfef2ed745b90652be9baa76b96c88ace1d0693fa58ea6229dd46282d030413fdbc0c2f649d0db373730903c8d
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,25 @@
|
|
1
1
|
## [Unreleased]
|
2
2
|
|
3
|
+
## [0.5.0] - 2024-06-17
|
4
|
+
|
5
|
+
* Fix destructive change by @ksss in https://github.com/ksss/rubocop-on-rbs/pull/17
|
6
|
+
* Introduce cache by @ksss in https://github.com/ksss/rubocop-on-rbs/pull/18
|
7
|
+
* Fix bug for EmptyArgument by @ksss in https://github.com/ksss/rubocop-on-rbs/pull/19
|
8
|
+
|
9
|
+
## [0.4.0] - 2024-06-14
|
10
|
+
|
11
|
+
* Split RuboCop task by @ksss in https://github.com/ksss/rubocop-on-rbs/pull/6
|
12
|
+
* Ignore when return untyped by @ksss in https://github.com/ksss/rubocop-on-rbs/pull/7
|
13
|
+
* Split task for steep by @ksss in https://github.com/ksss/rubocop-on-rbs/pull/8
|
14
|
+
* Add Style/EmptyArgument by @ksss in https://github.com/ksss/rubocop-on-rbs/pull/9
|
15
|
+
* Allow return variable only to use by @ksss in https://github.com/ksss/rubocop-on-rbs/pull/10
|
16
|
+
* Remove Style/MergeUntyped by @ksss in https://github.com/ksss/rubocop-on-rbs/pull/11
|
17
|
+
* Remove Lint/TypeParamsArity by @ksss in https://github.com/ksss/rubocop-on-rbs/pull/12
|
18
|
+
* Regenerate docs by @ksss in https://github.com/ksss/rubocop-on-rbs/pull/13
|
19
|
+
* Add RBS/Layout/SpaceAroundOperators by @ksss in https://github.com/ksss/rubocop-on-rbs/pull/14
|
20
|
+
* Add RBS/Style/RedundantParentheses by @ksss in https://github.com/ksss/rubocop-on-rbs/pull/15
|
21
|
+
* Add RBS/Lint/LiteralIntersection by @ksss in https://github.com/ksss/rubocop-on-rbs/pull/16
|
22
|
+
|
3
23
|
## [0.3.0] - 2024-06-11
|
4
24
|
|
5
25
|
* Implement RedundantOverloadTypeParams instead of UselessOverloadTypeParams by @ksss in https://github.com/ksss/rubocop-on-rbs/pull/1
|
data/config/default.yml
CHANGED
@@ -90,16 +90,16 @@ RBS/Lint/LiteralIntersection:
|
|
90
90
|
Description: 'Check literal intersection'
|
91
91
|
Enabled: true
|
92
92
|
|
93
|
-
RBS/Lint/UselessOverloadTypeParams:
|
94
|
-
Severity: warning
|
95
|
-
Description: 'Check redundant overload type params'
|
96
|
-
Enabled: true
|
97
|
-
|
98
93
|
RBS/Lint/Syntax:
|
99
94
|
Severity: fatal
|
100
95
|
Description: 'Check RBS syntax'
|
101
96
|
Enabled: true
|
102
97
|
|
98
|
+
RBS/Lint/UselessOverloadTypeParams:
|
99
|
+
Severity: warning
|
100
|
+
Description: 'Check redundant overload type params'
|
101
|
+
Enabled: true
|
102
|
+
|
103
103
|
RBS/Lint/WillSyntaxError:
|
104
104
|
Severity: warning
|
105
105
|
Description: 'Check RBS will syntax error'
|
@@ -19,7 +19,7 @@ module RuboCop
|
|
19
19
|
decl.overloads.each do |overload|
|
20
20
|
next if overload.method_type.type_params.empty?
|
21
21
|
|
22
|
-
type_params = overload.method_type.type_params
|
22
|
+
type_params = overload.method_type.type_params.dup
|
23
23
|
|
24
24
|
overload.method_type.each_type do |type|
|
25
25
|
used_variable_in_type(type) do |var|
|
@@ -17,85 +17,152 @@ module RuboCop
|
|
17
17
|
# # good
|
18
18
|
# def foo: () { () -> void } -> ^() -> void
|
19
19
|
class EmptyArgument < RuboCop::RBS::CopBase
|
20
|
-
|
20
|
+
class MethodTypeChecker
|
21
|
+
include RuboCop::RBS::OnTypeHelper
|
21
22
|
|
22
|
-
|
23
|
+
def initialize(base_type: nil, &block)
|
24
|
+
@base_type = base_type
|
25
|
+
@base = base_type.location.start_pos
|
26
|
+
@tokens = tokenize(base_type.location.source)
|
27
|
+
@block = block
|
28
|
+
end
|
23
29
|
|
24
|
-
|
25
|
-
|
26
|
-
if
|
27
|
-
|
28
|
-
add_offense(range) do |corrector|
|
29
|
-
corrector.insert_before(range, '()')
|
30
|
-
end
|
30
|
+
def check
|
31
|
+
check_method_argument
|
32
|
+
if @base_type.block
|
33
|
+
check_block_argument
|
31
34
|
end
|
32
|
-
|
33
|
-
|
34
|
-
block_arrow_index = tokens.find_index { |t| t.type == :pARROW } or raise
|
35
|
-
if tokens[block_arrow_index - 1].type != :pRPAREN
|
36
|
-
range = range_between(
|
37
|
-
overload.method_type.location.start_pos + tokens[block_arrow_index].location.start_pos,
|
38
|
-
overload.method_type.location.start_pos + tokens[block_arrow_index].location.start_pos
|
39
|
-
)
|
40
|
-
add_offense(range) do |corrector|
|
41
|
-
corrector.insert_before(range, '()')
|
42
|
-
end
|
43
|
-
end
|
35
|
+
@base_type.each_type do |type|
|
36
|
+
check_type(type)
|
44
37
|
end
|
38
|
+
end
|
45
39
|
|
46
|
-
|
47
|
-
|
40
|
+
# [T] () -> void
|
41
|
+
def check_method_argument
|
42
|
+
if @base_type.type_params.empty?
|
43
|
+
will_lparen_token = @tokens[0]
|
44
|
+
else
|
45
|
+
rbracket_index = @tokens.index do |token|
|
46
|
+
token.location.start_pos + @base >= @base_type.type_params.last.location.end_pos
|
47
|
+
end or raise
|
48
|
+
raise unless @tokens[rbracket_index].type == :pRBRACKET
|
49
|
+
|
50
|
+
will_lparen_token = @tokens[rbracket_index + 1]
|
51
|
+
end
|
52
|
+
|
53
|
+
if will_lparen_token.type != :pLPAREN
|
54
|
+
@block.call(
|
55
|
+
@base + will_lparen_token.location.start_pos,
|
56
|
+
@base + will_lparen_token.location.start_pos + 1
|
57
|
+
)
|
48
58
|
end
|
49
59
|
end
|
50
|
-
end
|
51
60
|
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
61
|
+
# { () [self: instance] -> void } -> void
|
62
|
+
def check_block_argument
|
63
|
+
return unless @base_type.block
|
64
|
+
return unless @base_type.block.type.each_param.first.nil?
|
65
|
+
|
66
|
+
if @base_type.block.self_type
|
67
|
+
self_type_index = bsearch_token_index(@base_type.block.self_type.location.start_pos)
|
68
|
+
# ) [self:
|
69
|
+
# ^ ^^ ^ => pRPAREN, pLBRACKET, kSELF, pCOLON
|
70
|
+
rparen = @tokens[self_type_index - 4]
|
71
|
+
after_rparen = @tokens[self_type_index - 3]
|
72
|
+
else
|
73
|
+
block_arrow_index = @tokens.find_index { |t| t.type == :pARROW } or raise
|
74
|
+
rparen = @tokens[block_arrow_index - 1]
|
75
|
+
after_rparen = @tokens[block_arrow_index]
|
76
|
+
end
|
58
77
|
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
type.each_type do |t|
|
65
|
-
check_type(t)
|
78
|
+
if rparen.type != :pRPAREN
|
79
|
+
@block.call(
|
80
|
+
@base + after_rparen.location.start_pos,
|
81
|
+
@base + after_rparen.location.start_pos + 1
|
82
|
+
)
|
66
83
|
end
|
67
84
|
end
|
68
|
-
end
|
69
85
|
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
range = range_between(
|
74
|
-
type.location.start_pos + tokens[0].location.end_pos,
|
75
|
-
type.location.start_pos + tokens[0].location.end_pos
|
76
|
-
)
|
77
|
-
add_offense(range) do |corrector|
|
78
|
-
corrector.insert_after(range, '()')
|
86
|
+
def check_type(type = @base_type)
|
87
|
+
on_type([::RBS::Types::Proc], type) do |proc_type|
|
88
|
+
check_proc(proc_type)
|
79
89
|
end
|
80
90
|
end
|
81
91
|
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
92
|
+
def check_proc(type)
|
93
|
+
proc_start_index = bsearch_token_index(type.location.start_pos)
|
94
|
+
proc_end_index = bsearch_token_index(type.location.end_pos)
|
95
|
+
if @tokens[proc_start_index + 1].type != :pLPAREN
|
96
|
+
@block.call(
|
97
|
+
@base + @tokens[proc_start_index + 1].location.start_pos,
|
98
|
+
@base + @tokens[proc_start_index + 1].location.start_pos + 1
|
88
99
|
)
|
89
|
-
|
90
|
-
|
100
|
+
end
|
101
|
+
|
102
|
+
if type.block
|
103
|
+
if type.block&.self_type
|
104
|
+
self_type_index = bsearch_token_index(type.block.self_type.location.start_pos)
|
105
|
+
# ) [self:
|
106
|
+
# ^ ^^ ^ => pRPAREN, pLBRACKET, kSELF, pCOLON
|
107
|
+
rparen = @tokens[self_type_index - 4]
|
108
|
+
after_rparen = @tokens[self_type_index - 3]
|
109
|
+
else
|
110
|
+
block_arrow_index = @tokens[proc_start_index...proc_end_index].find_index { |t|
|
111
|
+
t.type == :pARROW
|
112
|
+
} or raise
|
113
|
+
block_arrow_index += proc_start_index
|
114
|
+
rparen = @tokens[block_arrow_index - 1]
|
115
|
+
after_rparen = @tokens[block_arrow_index]
|
116
|
+
end
|
117
|
+
|
118
|
+
if rparen.type != :pRPAREN
|
119
|
+
@block.call(
|
120
|
+
@base + after_rparen.location.start_pos,
|
121
|
+
@base + after_rparen.location.start_pos + 1
|
122
|
+
)
|
91
123
|
end
|
92
124
|
end
|
93
125
|
end
|
126
|
+
|
127
|
+
private
|
128
|
+
|
129
|
+
def bsearch_token_index(pos)
|
130
|
+
@tokens.bsearch_index do |token|
|
131
|
+
token.location.start_pos + @base >= pos
|
132
|
+
end or raise
|
133
|
+
end
|
134
|
+
|
135
|
+
def tokenize(source)
|
136
|
+
::RBS::Parser.lex(source).value.reject { |t| t.type == :tTRIVIA }
|
137
|
+
end
|
94
138
|
end
|
95
139
|
|
96
|
-
|
97
|
-
|
140
|
+
extend AutoCorrector
|
141
|
+
|
142
|
+
MSG = 'Insert `()` when empty argument'
|
143
|
+
|
144
|
+
def on_rbs_def(decl)
|
145
|
+
decl.overloads.each do |overload|
|
146
|
+
MethodTypeChecker.new(base_type: overload.method_type) do |s, e|
|
147
|
+
range = range_between(s, e)
|
148
|
+
add_offense(range) do |corrector|
|
149
|
+
corrector.insert_before(range, '() ')
|
150
|
+
end
|
151
|
+
end.check
|
152
|
+
end
|
98
153
|
end
|
154
|
+
|
155
|
+
def on_rbs_constant(const)
|
156
|
+
MethodTypeChecker.new(base_type: const.type) do |s, e|
|
157
|
+
range = range_between(s, e)
|
158
|
+
add_offense(range) do |corrector|
|
159
|
+
corrector.insert_before(range, '() ')
|
160
|
+
end
|
161
|
+
end.check_type
|
162
|
+
end
|
163
|
+
alias on_rbs_global on_rbs_constant
|
164
|
+
alias on_rbs_type_alias on_rbs_constant
|
165
|
+
alias on_rbs_attribute on_rbs_constant
|
99
166
|
end
|
100
167
|
end
|
101
168
|
end
|
data/lib/rubocop/rbs/cop_base.rb
CHANGED
@@ -1,10 +1,13 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require 'zlib'
|
4
|
+
|
3
5
|
module RuboCop
|
4
6
|
module RBS
|
5
7
|
# Base class for cops that operate on RBS signatures.
|
6
8
|
class CopBase < RuboCop::Cop::Base
|
7
9
|
include RuboCop::Cop::RangeHelp
|
10
|
+
include RuboCop::RBS::OnTypeHelper
|
8
11
|
|
9
12
|
attr_reader :processed_rbs_source
|
10
13
|
|
@@ -19,18 +22,35 @@ module RuboCop
|
|
19
22
|
investigation_rbs()
|
20
23
|
end
|
21
24
|
|
25
|
+
@@cache = {}
|
26
|
+
def parse_rbs
|
27
|
+
buffer = rbs_buffer()
|
28
|
+
@processed_rbs_source = RuboCop::RBS::ProcessedRBSSource.new(buffer)
|
29
|
+
end
|
30
|
+
|
22
31
|
def investigation_rbs
|
23
32
|
return unless processed_source.buffer.name.then { |n| n.end_with?(".rbs") || n == "(string)" }
|
24
33
|
|
25
|
-
buffer
|
26
|
-
|
34
|
+
if processed_source.buffer.name == "(string)"
|
35
|
+
parse_rbs
|
36
|
+
else
|
37
|
+
crc32 = Zlib.crc32(processed_source.raw_source)
|
38
|
+
hit_path = @@cache[processed_source.buffer.name]
|
39
|
+
if hit_path
|
40
|
+
if hit_crc32 = hit_path[crc32]
|
41
|
+
@processed_rbs_source = hit_crc32
|
42
|
+
else
|
43
|
+
hit_path.clear # Other key expect clear by GC
|
44
|
+
hit_path[crc32] = parse_rbs
|
45
|
+
end
|
46
|
+
else
|
47
|
+
(@@cache[processed_source.buffer.name] ||= {})[crc32] = parse_rbs
|
48
|
+
end
|
49
|
+
end
|
27
50
|
|
28
51
|
if processed_rbs_source.error
|
29
52
|
on_rbs_parsing_error()
|
30
53
|
else
|
31
|
-
# HACK: Autocorrector needs to clear diagnostics
|
32
|
-
processed_source.diagnostics.clear
|
33
|
-
|
34
54
|
on_rbs_new_investigation()
|
35
55
|
|
36
56
|
processed_rbs_source.decls.each do |decl|
|
@@ -91,26 +111,11 @@ module RuboCop
|
|
91
111
|
::RBS::Parser.lex(source).value.reject { |t| t.type == :tTRIVIA }
|
92
112
|
end
|
93
113
|
|
94
|
-
|
95
|
-
case type
|
96
|
-
when *types
|
97
|
-
yield type
|
98
|
-
end
|
99
|
-
type.each_type do |t|
|
100
|
-
on_type(types, t, &block)
|
101
|
-
end
|
102
|
-
end
|
114
|
+
private
|
103
115
|
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
# not
|
108
|
-
else
|
109
|
-
yield type
|
110
|
-
end
|
111
|
-
type.each_type do |t|
|
112
|
-
on_not_type(types, t, &block)
|
113
|
-
end
|
116
|
+
# HACK: Required to autocorrect
|
117
|
+
def current_corrector
|
118
|
+
@current_corrector ||= RuboCop::Cop::Corrector.new(@processed_source) if @processed_rbs_source.valid_syntax?
|
114
119
|
end
|
115
120
|
end
|
116
121
|
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module RBS
|
5
|
+
module OnTypeHelper
|
6
|
+
def on_type(types, type, &block)
|
7
|
+
case type
|
8
|
+
when *types
|
9
|
+
yield type
|
10
|
+
end
|
11
|
+
type.each_type do |t|
|
12
|
+
on_type(types, t, &block)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def on_not_type(types, type, &block)
|
17
|
+
case type
|
18
|
+
when *types
|
19
|
+
# not
|
20
|
+
else
|
21
|
+
yield type
|
22
|
+
end
|
23
|
+
type.each_type do |t|
|
24
|
+
on_not_type(types, t, &block)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
data/lib/rubocop/rbs/version.rb
CHANGED
data/lib/rubocop-on-rbs.rb
CHANGED
@@ -4,6 +4,7 @@ require 'rubocop'
|
|
4
4
|
|
5
5
|
require_relative 'rubocop/rbs'
|
6
6
|
require_relative 'rubocop/rbs/version'
|
7
|
+
require_relative 'rubocop/rbs/on_type_helper'
|
7
8
|
require_relative 'rubocop/rbs/cop_base'
|
8
9
|
require_relative 'rubocop/rbs/inject'
|
9
10
|
require_relative 'rubocop/rbs/processed_rbs_source'
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rubocop-on-rbs
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.6.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- ksss
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-06-
|
11
|
+
date: 2024-06-18 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rbs
|
@@ -38,6 +38,20 @@ dependencies:
|
|
38
38
|
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '1.41'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: zlib
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
41
55
|
description: RuboCop extension for RBS file.
|
42
56
|
email:
|
43
57
|
- co000ri@gmail.com
|
@@ -80,12 +94,16 @@ files:
|
|
80
94
|
- lib/rubocop/rbs.rb
|
81
95
|
- lib/rubocop/rbs/cop_base.rb
|
82
96
|
- lib/rubocop/rbs/inject.rb
|
97
|
+
- lib/rubocop/rbs/on_type_helper.rb
|
83
98
|
- lib/rubocop/rbs/processed_rbs_source.rb
|
84
99
|
- lib/rubocop/rbs/version.rb
|
85
100
|
homepage: https://github.com/ksss/rubocop-on-rbs
|
86
101
|
licenses:
|
87
102
|
- MIT
|
88
103
|
metadata:
|
104
|
+
homepage_uri: https://github.com/ksss/rubocop-on-rbs
|
105
|
+
source_code_uri: https://github.com/ksss/rubocop-on-rbs
|
106
|
+
changelog_uri: https://github.com/ksss/rubocop-on-rbs
|
89
107
|
rubygems_mfa_required: 'true'
|
90
108
|
post_install_message:
|
91
109
|
rdoc_options: []
|