rubocop-on-rbs 0.4.0 → 0.5.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: adb415dc438caa7d859497f2915d37fe647ba2c0a0c396a1afc79f6aec2a53ee
4
- data.tar.gz: 621b0e9338aab521860cf7e73c7b346015f3e9e51b6af06d9159b1844083281a
3
+ metadata.gz: 889ce959e28673f250187124bfd7955879317482cfdfb976f4bdb975fc918c5b
4
+ data.tar.gz: 0e0654669928cacd44ca23ad5ece90521ac21660758277fe0af42d3b33377d5b
5
5
  SHA512:
6
- metadata.gz: 6e3357ceba540c5c6ee25188804ebe95965147e47970bc39c98fd8fe60eb8f52af762c1a3a90ca9e68be9d63e2263622cffc983b029232fd23f89d6f536a12b3
7
- data.tar.gz: a9155f9687029947fb9bb4d0c47332a5bc3075e400872ebf1e58312f7d6cd47ffa0d37c4005c644adb08e88494c8c14d84a063e2550590db93c75ac7e95f0136
6
+ metadata.gz: 1556cdd4bb1116f2f49aca75d39ed229f3f3074e33d338528cb051c97cbcd952f2cb4daec81e0186e54c0794d2c265609e56483c7addcf77ad5d648b2fc68a39
7
+ data.tar.gz: c77872b3822c006c59d89a637f59366e63a58beb2a0ac7b8b351c1b4428ba353d7e1c8f2480faa5209258649eb25574008ffcb9ce2f25b815a7540b09da60c35
data/CHANGELOG.md CHANGED
@@ -1,5 +1,19 @@
1
1
  ## [Unreleased]
2
2
 
3
+ ## [0.4.0] - 2024-06-14
4
+
5
+ * Split RuboCop task by @ksss in https://github.com/ksss/rubocop-on-rbs/pull/6
6
+ * Ignore when return untyped by @ksss in https://github.com/ksss/rubocop-on-rbs/pull/7
7
+ * Split task for steep by @ksss in https://github.com/ksss/rubocop-on-rbs/pull/8
8
+ * Add Style/EmptyArgument by @ksss in https://github.com/ksss/rubocop-on-rbs/pull/9
9
+ * Allow return variable only to use by @ksss in https://github.com/ksss/rubocop-on-rbs/pull/10
10
+ * Remove Style/MergeUntyped by @ksss in https://github.com/ksss/rubocop-on-rbs/pull/11
11
+ * Remove Lint/TypeParamsArity by @ksss in https://github.com/ksss/rubocop-on-rbs/pull/12
12
+ * Regenerate docs by @ksss in https://github.com/ksss/rubocop-on-rbs/pull/13
13
+ * Add RBS/Layout/SpaceAroundOperators by @ksss in https://github.com/ksss/rubocop-on-rbs/pull/14
14
+ * Add RBS/Style/RedundantParentheses by @ksss in https://github.com/ksss/rubocop-on-rbs/pull/15
15
+ * Add RBS/Lint/LiteralIntersection by @ksss in https://github.com/ksss/rubocop-on-rbs/pull/16
16
+
3
17
  ## [0.3.0] - 2024-06-11
4
18
 
5
19
  * 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
- extend AutoCorrector
20
+ class MethodTypeChecker
21
+ include RuboCop::RBS::OnTypeHelper
21
22
 
22
- MSG = 'Insert `()` when empty argument'
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
- def on_rbs_def(decl)
25
- decl.overloads.each do |overload|
26
- if !overload.method_type.location.source.start_with?('(')
27
- range = range_between(overload.method_type.location.start_pos, overload.method_type.location.start_pos)
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
- if overload.method_type.block
33
- tokens = tokenize(overload.method_type.location.source)
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
- overload.method_type.each_type do |type|
47
- check_type(type)
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
- def on_rbs_constant(const)
53
- check_type(const.type)
54
- end
55
- alias on_rbs_global on_rbs_constant
56
- alias on_rbs_type_alias on_rbs_constant
57
- alias on_rbs_attribute on_rbs_constant
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
- def check_type(type)
60
- case type
61
- when ::RBS::Types::Proc
62
- check_proc(type)
63
- else
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
- def check_proc(type)
71
- tokens = tokenize(type.location.source)
72
- if tokens[1].type != :pLPAREN
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
- if type.block
83
- block_arrow_index = tokens.find_index { |t| t.type == :pARROW } or raise
84
- if tokens[block_arrow_index - 1].type != :pRPAREN
85
- range = range_between(
86
- type.location.start_pos + tokens[block_arrow_index].location.start_pos,
87
- type.location.start_pos + tokens[block_arrow_index].location.start_pos
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
- add_offense(range) do |corrector|
90
- corrector.insert_before(range, '()')
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
- def tokenize(source)
97
- ::RBS::Parser.lex(source).value.reject { |t| t.type == :tTRIVIA }
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
@@ -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,11 +22,31 @@ 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 = rbs_buffer()
26
- @processed_rbs_source = RuboCop::RBS::ProcessedRBSSource.new(buffer)
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()
@@ -90,28 +113,6 @@ module RuboCop
90
113
  def tokenize(source)
91
114
  ::RBS::Parser.lex(source).value.reject { |t| t.type == :tTRIVIA }
92
115
  end
93
-
94
- def on_type(types, type, &block)
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
103
-
104
- def on_not_type(types, type, &block)
105
- case type
106
- when *types
107
- # not
108
- else
109
- yield type
110
- end
111
- type.each_type do |t|
112
- on_not_type(types, t, &block)
113
- end
114
- end
115
116
  end
116
117
  end
117
118
  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
@@ -2,6 +2,6 @@
2
2
 
3
3
  module RuboCop
4
4
  module RBS
5
- VERSION = '0.4.0'
5
+ VERSION = '0.5.0'
6
6
  end
7
7
  end
@@ -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.0
4
+ version: 0.5.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-14 00:00:00.000000000 Z
11
+ date: 2024-06-17 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,6 +94,7 @@ 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