steep 1.9.4 → 1.10.0.pre.1
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 +34 -3
- data/Steepfile +5 -2
- data/lib/steep/annotations_helper.rb +43 -0
- data/lib/steep/ast/ignore.rb +3 -4
- data/lib/steep/cli.rb +102 -23
- data/lib/steep/diagnostic/lsp_formatter.rb +17 -3
- data/lib/steep/diagnostic/ruby.rb +75 -0
- data/lib/steep/diagnostic/signature.rb +20 -0
- data/lib/steep/drivers/check.rb +3 -1
- data/lib/steep/drivers/diagnostic_printer/base_formatter.rb +19 -0
- data/lib/steep/drivers/diagnostic_printer/code_formatter.rb +95 -0
- data/lib/steep/drivers/diagnostic_printer/github_actions_formatter.rb +44 -0
- data/lib/steep/drivers/diagnostic_printer.rb +9 -86
- data/lib/steep/drivers/langserver.rb +4 -1
- data/lib/steep/drivers/worker.rb +2 -0
- data/lib/steep/interface/builder.rb +2 -2
- data/lib/steep/server/custom_methods.rb +12 -0
- data/lib/steep/server/interaction_worker.rb +33 -6
- data/lib/steep/server/master.rb +103 -7
- data/lib/steep/server/type_check_worker.rb +48 -2
- data/lib/steep/server/worker_process.rb +31 -20
- data/lib/steep/services/completion_provider.rb +12 -2
- data/lib/steep/services/signature_service.rb +2 -2
- data/lib/steep/services/type_check_service.rb +22 -7
- data/lib/steep/signature/validator.rb +56 -4
- data/lib/steep/source.rb +3 -1
- data/lib/steep/subtyping/check.rb +22 -16
- data/lib/steep/type_construction.rb +153 -34
- data/lib/steep/type_inference/case_when.rb +2 -0
- data/lib/steep/type_inference/logic_type_interpreter.rb +77 -15
- data/lib/steep/type_inference/method_call.rb +5 -3
- data/lib/steep/version.rb +1 -1
- data/lib/steep.rb +10 -0
- data/manual/ruby-diagnostics.md +114 -1
- data/sample/Steepfile +0 -2
- data/sample/lib/conference.rb +14 -0
- data/sample/lib/deprecated.rb +7 -0
- data/sample/sig/deprecated.rbs +16 -0
- data/steep.gemspec +4 -3
- metadata +28 -8
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2233f51ac985ee697a7f3617582dc034f32b1cd3b0732a87b8184210f2c1d7b0
|
4
|
+
data.tar.gz: 1298685cafa59f5074afa950df4c1f14cff9a8b6be9b99b914902b37e537aad3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1cb518e2f5743330e58b0c6032ed99d22f29254b91d9c8e33e3bafc3cb1a9f46247f181ee5b9b078dba13768f675f03b1c2e8fb24b53609902d6534092625282
|
7
|
+
data.tar.gz: e26fde370f8d793b13138d71dc6295ffde59e781ed2d0a39cf73e639c8440517d7fa13586d871c9eab6880ae8864c31a711beb45c49280152416d0111935f3da
|
data/CHANGELOG.md
CHANGED
@@ -1,14 +1,45 @@
|
|
1
1
|
# CHANGELOG
|
2
2
|
|
3
|
-
## 1.
|
3
|
+
## 1.10.0.pre.1 (2025-03-11)
|
4
|
+
|
5
|
+
### Type checker core
|
6
|
+
|
7
|
+
* Skip type checking forwarded argument if the method is undeclared ([#1519](https://github.com/soutaro/steep/pull/1519))
|
8
|
+
* Dedup error message on ancestors check ([#1515](https://github.com/soutaro/steep/pull/1515))
|
9
|
+
* Add deprecation validation on RBS ([#1518](https://github.com/soutaro/steep/pull/1518))
|
10
|
+
* Fix union self type refinement based on method call ([#1517](https://github.com/soutaro/steep/pull/1517))
|
11
|
+
* Check deprecations in Ruby code ([#1513](https://github.com/soutaro/steep/pull/1513))
|
12
|
+
* Support `InvalidTypeApplication` on `#update_env` ([#1507](https://github.com/soutaro/steep/pull/1507))
|
13
|
+
* Fix Source.parse crashes with selector-less sendish node ([#1433](https://github.com/soutaro/steep/pull/1433))
|
14
|
+
* Fix steep:ignore does not work with CR/LF ([#1406](https://github.com/soutaro/steep/pull/1406))
|
15
|
+
* Fix self union type checking ([#1467](https://github.com/soutaro/steep/pull/1467))
|
16
|
+
* Type narrowing union types via return type of method call ([#1497](https://github.com/soutaro/steep/pull/1497))
|
17
|
+
* Fix `else` clause of `case-when` syntax typing ([#1475](https://github.com/soutaro/steep/pull/1475))
|
18
|
+
* Strict record and tuple subtyping ([#1460](https://github.com/soutaro/steep/pull/1460))
|
19
|
+
* Allow to annotate "self" on toplevel ([#1455](https://github.com/soutaro/steep/pull/1455))
|
20
|
+
* Let annotations in `when` clause without `cond` expression work ([#1459](https://github.com/soutaro/steep/pull/1459))
|
21
|
+
* Fix `RuntimeError` on `when` clause with assertion ([#1458](https://github.com/soutaro/steep/pull/1458))
|
22
|
+
* Add diagnostic for method definition without types ([#1457](https://github.com/soutaro/steep/pull/1457))
|
23
|
+
|
24
|
+
### Commandline tool
|
25
|
+
|
26
|
+
* Implement GitHub formatter ([#1516](https://github.com/soutaro/steep/pull/1516))
|
27
|
+
* Refine `--help` messages ([#1463](https://github.com/soutaro/steep/pull/1463))
|
4
28
|
|
5
29
|
### Language server
|
6
30
|
|
7
|
-
*
|
31
|
+
* Reforking steep ([#1492](https://github.com/soutaro/steep/pull/1492))
|
32
|
+
* Set up file watcher for groups ([#1485](https://github.com/soutaro/steep/pull/1485))
|
8
33
|
|
9
34
|
### Miscellaneous
|
10
35
|
|
11
|
-
* Fix
|
36
|
+
* Fix a runtime warning for ambiguous `/`; wrap regexp in parentheses or add a space after `/` operator ([#1438](https://github.com/soutaro/steep/pull/1438))
|
37
|
+
* Fix a runtime warning for ambiguous `*` has been interpreted as an argument prefix ([#1439](https://github.com/soutaro/steep/pull/1439))
|
38
|
+
* Fix a runtime warning for key :cursor is duplicated and overwritten on line 99 ([#1440](https://github.com/soutaro/steep/pull/1440))
|
39
|
+
* Use release version of RBS ([#1511](https://github.com/soutaro/steep/pull/1511))
|
40
|
+
* Prepare for rbs-3.9 ([#1510](https://github.com/soutaro/steep/pull/1510))
|
41
|
+
* Fix typos ([#1506](https://github.com/soutaro/steep/pull/1506))
|
42
|
+
* Fix CI ([#1486](https://github.com/soutaro/steep/pull/1486))
|
12
43
|
|
13
44
|
## 1.9.3 (2024-12-26)
|
14
45
|
|
data/Steepfile
CHANGED
@@ -13,7 +13,6 @@ if (source = rbs_dep&.source).is_a?(Bundler::Source::Path)
|
|
13
13
|
end
|
14
14
|
else
|
15
15
|
FileUtils.rm_f(tmp_rbs_dir)
|
16
|
-
library "rbs"
|
17
16
|
end
|
18
17
|
|
19
18
|
target :app do
|
@@ -64,5 +63,9 @@ target :bin do
|
|
64
63
|
check "bin/generate-diagnostics-docs.rb"
|
65
64
|
signature "tmp/rbs-inline/bin"
|
66
65
|
|
67
|
-
|
66
|
+
if tmp_rbs_dir.directory?
|
67
|
+
signature tmp_rbs_dir.to_s
|
68
|
+
else
|
69
|
+
library "rbs"
|
70
|
+
end
|
68
71
|
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
module Steep
|
2
|
+
module AnnotationsHelper
|
3
|
+
module_function
|
4
|
+
|
5
|
+
def deprecated_annotation?(annotations)
|
6
|
+
annotations.reverse_each do |annotation|
|
7
|
+
if match = annotation.string.match(/deprecated(:\s*(?<message>.+))?/)
|
8
|
+
return [annotation, match[:message]]
|
9
|
+
end
|
10
|
+
if match = annotation.string.match(/steep:deprecated(:\s*(?<message>.+))?/)
|
11
|
+
return [annotation, match[:message]]
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
nil
|
16
|
+
end
|
17
|
+
|
18
|
+
def deprecated_type_name?(type_name, env)
|
19
|
+
annotations =
|
20
|
+
case
|
21
|
+
when type_name.class?
|
22
|
+
case
|
23
|
+
when decl = env.class_decls.fetch(type_name, nil)
|
24
|
+
decl.decls.flat_map { _1.decl.annotations }
|
25
|
+
when decl = env.class_alias_decls.fetch(type_name, nil)
|
26
|
+
decl.decl.annotations
|
27
|
+
end
|
28
|
+
when type_name.interface?
|
29
|
+
if decl = env.interface_decls.fetch(type_name, nil)
|
30
|
+
decl.decl.annotations
|
31
|
+
end
|
32
|
+
when type_name.alias?
|
33
|
+
if decl = env.type_alias_decls.fetch(type_name, nil)
|
34
|
+
decl.decl.annotations
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
if annotations
|
39
|
+
deprecated_annotation?(annotations)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
data/lib/steep/ast/ignore.rb
CHANGED
@@ -93,15 +93,14 @@ module Steep
|
|
93
93
|
def self.parse(comment, buffer)
|
94
94
|
return unless comment.inline?
|
95
95
|
|
96
|
-
|
96
|
+
begin_pos = buffer.loc_to_pos([comment.loc.line, comment.loc.column])
|
97
|
+
end_pos = buffer.loc_to_pos([comment.loc.last_line, comment.loc.last_column])
|
98
|
+
comment_location = RBS::Location.new(buffer, begin_pos, end_pos)
|
97
99
|
scanner = BufferScanner.new(comment_location)
|
98
100
|
|
99
101
|
scanner.scan(/#/)
|
100
102
|
scanner.skip(/\s*/)
|
101
103
|
|
102
|
-
begin_pos = comment.location.expression.begin_pos
|
103
|
-
end_pos = comment.location.expression.end_pos
|
104
|
-
|
105
104
|
case
|
106
105
|
when loc = scanner.scan(/steep:ignore:start\b/)
|
107
106
|
scanner.skip(/\s*/)
|
data/lib/steep/cli.rb
CHANGED
@@ -24,12 +24,13 @@ module Steep
|
|
24
24
|
opts.banner = <<~USAGE
|
25
25
|
Usage: steep [options]
|
26
26
|
|
27
|
-
|
27
|
+
Available commands:
|
28
|
+
#{CLI.available_commands.join(', ')}
|
28
29
|
|
29
30
|
Options:
|
30
31
|
USAGE
|
31
32
|
|
32
|
-
opts.on("--version") do
|
33
|
+
opts.on("--version", "Print Steep version") do
|
33
34
|
process_version
|
34
35
|
exit 0
|
35
36
|
end
|
@@ -60,6 +61,10 @@ module Steep
|
|
60
61
|
__send__(:"process_#{command}")
|
61
62
|
end
|
62
63
|
|
64
|
+
def handle_steepfile_option(opts, command)
|
65
|
+
opts.on("--steepfile=PATH", "Specify path to Steepfile") {|path| command.steepfile = Pathname(path) }
|
66
|
+
end
|
67
|
+
|
63
68
|
def handle_logging_options(opts)
|
64
69
|
opts.on("--log-level=LEVEL", "Specify log level: debug, info, warn, error, fatal") do |level|
|
65
70
|
Steep.logger.level = level
|
@@ -101,10 +106,16 @@ module Steep
|
|
101
106
|
def process_init
|
102
107
|
Drivers::Init.new(stdout: stdout, stderr: stderr).tap do |command|
|
103
108
|
OptionParser.new do |opts|
|
104
|
-
opts.banner =
|
109
|
+
opts.banner = <<BANNER
|
110
|
+
Usage: steep init [options]
|
111
|
+
|
112
|
+
Description:
|
113
|
+
Generates a Steepfile at specified path.
|
105
114
|
|
106
|
-
|
107
|
-
|
115
|
+
Options:
|
116
|
+
BANNER
|
117
|
+
handle_steepfile_option(opts, command)
|
118
|
+
opts.on("--force", "Overwrite the Steepfile if it already exists") { command.force_write = true }
|
108
119
|
|
109
120
|
handle_logging_options opts
|
110
121
|
end.parse!(argv)
|
@@ -114,9 +125,19 @@ module Steep
|
|
114
125
|
def process_check
|
115
126
|
Drivers::Check.new(stdout: stdout, stderr: stderr).tap do |command|
|
116
127
|
OptionParser.new do |opts|
|
117
|
-
opts.banner =
|
128
|
+
opts.banner = <<BANNER
|
129
|
+
Usage: steep check [options] [paths]
|
130
|
+
|
131
|
+
Description:
|
132
|
+
Type check the program.
|
118
133
|
|
119
|
-
|
134
|
+
If paths are specified, it type checks and validates the files at the given path.
|
135
|
+
Otherwise, it type checks and validates all files in the project or the groups if specified.
|
136
|
+
|
137
|
+
Options:
|
138
|
+
BANNER
|
139
|
+
|
140
|
+
handle_steepfile_option(opts, command)
|
120
141
|
opts.on("--with-expectations[=PATH]", "Type check with expectations saved in PATH (or steep_expectations.yml)") do |path|
|
121
142
|
command.with_expectations_path = Pathname(path || "steep_expectations.yml")
|
122
143
|
end
|
@@ -166,22 +187,33 @@ module Steep
|
|
166
187
|
end
|
167
188
|
end
|
168
189
|
|
190
|
+
opts.on("--format=FORMATTER", ["code", "github"], "Output formatters (default: code, options: code,github)") do |formatter|
|
191
|
+
command.formatter = formatter
|
192
|
+
end
|
193
|
+
|
169
194
|
handle_jobs_option command.jobs_option, opts
|
170
195
|
handle_logging_options opts
|
171
196
|
end.parse!(argv)
|
172
197
|
|
173
198
|
setup_jobs_for_ci(command.jobs_option)
|
174
199
|
|
175
|
-
command.command_line_patterns.push
|
200
|
+
command.command_line_patterns.push(*argv)
|
176
201
|
end.run
|
177
202
|
end
|
178
203
|
|
179
204
|
def process_checkfile
|
180
205
|
Drivers::Checkfile.new(stdout: stdout, stderr: stderr).tap do |command|
|
181
206
|
OptionParser.new do |opts|
|
182
|
-
opts.banner =
|
207
|
+
opts.banner = <<BANNER
|
208
|
+
Usage: steep checkfile [options] [files]
|
209
|
+
|
210
|
+
Description:
|
211
|
+
Deprecated: Use `steep check` instead.
|
212
|
+
|
213
|
+
Options:
|
214
|
+
BANNER
|
183
215
|
|
184
|
-
opts
|
216
|
+
handle_steepfile_option(opts, command)
|
185
217
|
opts.on("--all-rbs", "Type check all RBS files") { command.all_rbs = true }
|
186
218
|
opts.on("--all-ruby", "Type check all Ruby files") { command.all_ruby = true }
|
187
219
|
opts.on("--stdin", "Read files to type check from stdin") do
|
@@ -197,16 +229,23 @@ module Steep
|
|
197
229
|
|
198
230
|
setup_jobs_for_ci(command.jobs_option)
|
199
231
|
|
200
|
-
command.command_line_args.push
|
232
|
+
command.command_line_args.push(*argv)
|
201
233
|
end.run
|
202
234
|
end
|
203
235
|
|
204
236
|
def process_stats
|
205
237
|
Drivers::Stats.new(stdout: stdout, stderr: stderr).tap do |command|
|
206
238
|
OptionParser.new do |opts|
|
207
|
-
opts.banner =
|
239
|
+
opts.banner = <<BANNER
|
240
|
+
Usage: steep stats [options] [sources]
|
208
241
|
|
209
|
-
|
242
|
+
Description:
|
243
|
+
Displays statistics about the typing of method calls.
|
244
|
+
|
245
|
+
Options:
|
246
|
+
BANNER
|
247
|
+
|
248
|
+
handle_steepfile_option(opts, command)
|
210
249
|
opts.on("--format=FORMAT", "Specify output format: csv, table") {|format| command.format = format }
|
211
250
|
handle_jobs_option command.jobs_option, opts
|
212
251
|
handle_logging_options opts
|
@@ -214,7 +253,7 @@ module Steep
|
|
214
253
|
|
215
254
|
setup_jobs_for_ci(command.jobs_option)
|
216
255
|
|
217
|
-
command.command_line_patterns.push
|
256
|
+
command.command_line_patterns.push(*argv)
|
218
257
|
end.run
|
219
258
|
end
|
220
259
|
|
@@ -226,19 +265,33 @@ module Steep
|
|
226
265
|
def process_annotations
|
227
266
|
Drivers::Annotations.new(stdout: stdout, stderr: stderr).tap do |command|
|
228
267
|
OptionParser.new do |opts|
|
229
|
-
opts.banner =
|
268
|
+
opts.banner = <<BANNER
|
269
|
+
Usage: steep annotations [options] [sources]
|
270
|
+
|
271
|
+
Description:
|
272
|
+
Prints the type annotations in the Ruby code.
|
273
|
+
|
274
|
+
Options:
|
275
|
+
BANNER
|
230
276
|
handle_logging_options opts
|
231
277
|
end.parse!(argv)
|
232
278
|
|
233
|
-
command.command_line_patterns.push
|
279
|
+
command.command_line_patterns.push(*argv)
|
234
280
|
end.run
|
235
281
|
end
|
236
282
|
|
237
283
|
def process_project
|
238
284
|
Drivers::PrintProject.new(stdout: stdout, stderr: stderr).tap do |command|
|
239
285
|
OptionParser.new do |opts|
|
240
|
-
opts.banner =
|
241
|
-
|
286
|
+
opts.banner = <<BANNER
|
287
|
+
Usage: steep project [options]
|
288
|
+
|
289
|
+
Description:
|
290
|
+
Prints the project configuration.
|
291
|
+
|
292
|
+
Options:
|
293
|
+
BANNER
|
294
|
+
handle_steepfile_option(opts, command)
|
242
295
|
opts.on("--[no-]print-files", "Print files") {|v|
|
243
296
|
command.print_files = v ? true : false
|
244
297
|
}
|
@@ -250,7 +303,15 @@ module Steep
|
|
250
303
|
def process_watch
|
251
304
|
Drivers::Watch.new(stdout: stdout, stderr: stderr).tap do |command|
|
252
305
|
OptionParser.new do |opts|
|
253
|
-
opts.banner =
|
306
|
+
opts.banner = <<BANNER
|
307
|
+
Usage: steep watch [options] [dirs]
|
308
|
+
|
309
|
+
Description:
|
310
|
+
Monitors file changes and automatically type checks updated files.
|
311
|
+
Using LSP is recommended for better performance and more features.
|
312
|
+
|
313
|
+
Options:
|
314
|
+
BANNER
|
254
315
|
opts.on("--severity-level=LEVEL", /^error|warning|information|hint$/, "Specify the minimum diagnostic severity to be recognized as an error (defaults: warning): error, warning, information, or hint") do |level|
|
255
316
|
# @type var level: String
|
256
317
|
command.severity_level = _ = level.to_sym
|
@@ -269,7 +330,16 @@ module Steep
|
|
269
330
|
def process_langserver
|
270
331
|
Drivers::Langserver.new(stdout: stdout, stderr: stderr, stdin: stdin).tap do |command|
|
271
332
|
OptionParser.new do |opts|
|
272
|
-
opts.
|
333
|
+
opts.banner = <<BANNER
|
334
|
+
Usage: steep langserver [options]
|
335
|
+
|
336
|
+
Description:
|
337
|
+
Starts language server, which is assumed to be invoked from language client.
|
338
|
+
|
339
|
+
Options:
|
340
|
+
BANNER
|
341
|
+
handle_steepfile_option(opts, command)
|
342
|
+
opts.on("--refork") { command.refork = true }
|
273
343
|
handle_jobs_option command.jobs_option, opts
|
274
344
|
handle_logging_options opts
|
275
345
|
end.parse!(argv)
|
@@ -300,8 +370,8 @@ module Steep
|
|
300
370
|
opts.banner = <<BANNER
|
301
371
|
Usage: steep binstub [options]
|
302
372
|
|
303
|
-
|
304
|
-
|
373
|
+
Description:
|
374
|
+
Generate a binstub which set up ruby executables and bundlers.
|
305
375
|
|
306
376
|
Options:
|
307
377
|
BANNER
|
@@ -372,6 +442,15 @@ TEMPLATE
|
|
372
442
|
end
|
373
443
|
|
374
444
|
def process_version
|
445
|
+
OptionParser.new do |opts|
|
446
|
+
opts.banner = <<BANNER
|
447
|
+
Usage: steep version [options]
|
448
|
+
|
449
|
+
Description:
|
450
|
+
Prints Steep version.
|
451
|
+
BANNER
|
452
|
+
end.parse!(argv)
|
453
|
+
|
375
454
|
stdout.puts Steep::VERSION
|
376
455
|
0
|
377
456
|
end
|
@@ -384,7 +463,7 @@ TEMPLATE
|
|
384
463
|
|
385
464
|
opts.on("--interaction") { command.worker_type = :interaction }
|
386
465
|
opts.on("--typecheck") { command.worker_type = :typecheck }
|
387
|
-
opts
|
466
|
+
handle_steepfile_option(opts, command)
|
388
467
|
opts.on("--name=NAME") {|name| command.worker_name = name }
|
389
468
|
opts.on("--delay-shutdown") { command.delay_shutdown = true }
|
390
469
|
opts.on("--max-index=COUNT") {|count| command.max_index = Integer(count) }
|
@@ -49,13 +49,27 @@ module Steep
|
|
49
49
|
} #: LSP::Interface::CodeDescription::json
|
50
50
|
end
|
51
51
|
|
52
|
-
|
52
|
+
tags = [] #: Array[LSP::Constant::DiagnosticTag::t]
|
53
|
+
|
54
|
+
case diagnostic
|
55
|
+
when Ruby::DeprecatedReference
|
56
|
+
tags << LSP::Constant::DiagnosticTag::DEPRECATED
|
57
|
+
when Signature::DeprecatedTypeName
|
58
|
+
tags << LSP::Constant::DiagnosticTag::DEPRECATED
|
59
|
+
severity = LSP::Constant::DiagnosticSeverity::WARNING
|
60
|
+
end
|
61
|
+
|
62
|
+
json = {
|
53
63
|
message: diagnostic.full_message,
|
54
64
|
code: diagnostic.diagnostic_code,
|
55
65
|
severity: severity,
|
56
66
|
range: range,
|
57
|
-
codeDescription: description
|
58
|
-
}
|
67
|
+
codeDescription: description,
|
68
|
+
} #: LSP::Interface::Diagnostic::json
|
69
|
+
|
70
|
+
json[:tags] = tags unless tags.empty?
|
71
|
+
|
72
|
+
json
|
59
73
|
end
|
60
74
|
end
|
61
75
|
|
@@ -977,6 +977,72 @@ module Steep
|
|
977
977
|
end
|
978
978
|
end
|
979
979
|
|
980
|
+
class UndeclaredMethodDefinition < Base
|
981
|
+
attr_reader :method_name, :type_name
|
982
|
+
|
983
|
+
def initialize(method_name:, type_name:, node:)
|
984
|
+
@method_name = method_name
|
985
|
+
@type_name = type_name
|
986
|
+
super(node: node, location: (_ = node.loc).name)
|
987
|
+
end
|
988
|
+
|
989
|
+
def header_line
|
990
|
+
name =
|
991
|
+
case node.type
|
992
|
+
when :def
|
993
|
+
"#{type_name}##{method_name}"
|
994
|
+
when :defs
|
995
|
+
"#{type_name}.#{method_name}"
|
996
|
+
else
|
997
|
+
raise
|
998
|
+
end
|
999
|
+
"Method `#{name}` is not declared in RBS"
|
1000
|
+
end
|
1001
|
+
end
|
1002
|
+
|
1003
|
+
class MethodDefinitionInUndeclaredModule < Base
|
1004
|
+
attr_reader :method_name
|
1005
|
+
|
1006
|
+
def initialize(method_name:, node:)
|
1007
|
+
@method_name = method_name
|
1008
|
+
super(node: node, location: (_ = node.loc).name)
|
1009
|
+
end
|
1010
|
+
|
1011
|
+
def header_line
|
1012
|
+
"Method `#{method_name}` is defined in undeclared module"
|
1013
|
+
end
|
1014
|
+
end
|
1015
|
+
|
1016
|
+
class DeprecatedReference < Base
|
1017
|
+
attr_reader :message
|
1018
|
+
|
1019
|
+
def initialize(node:, location:, message:)
|
1020
|
+
super(node: node, location: location)
|
1021
|
+
@message = message
|
1022
|
+
end
|
1023
|
+
|
1024
|
+
def header_line
|
1025
|
+
header =
|
1026
|
+
case node&.type
|
1027
|
+
when :send, :csend, :block, :numblock
|
1028
|
+
"The method is deprecated"
|
1029
|
+
when :const, :casgn
|
1030
|
+
"The constant is deprecated"
|
1031
|
+
when :gvar, :gvasgn
|
1032
|
+
"The global variable is deprecated"
|
1033
|
+
else
|
1034
|
+
raise "Unexpected node: #{node}"
|
1035
|
+
end
|
1036
|
+
|
1037
|
+
if message
|
1038
|
+
header = +header
|
1039
|
+
header.concat(": ", message)
|
1040
|
+
end
|
1041
|
+
|
1042
|
+
header
|
1043
|
+
end
|
1044
|
+
end
|
1045
|
+
|
980
1046
|
ALL = ObjectSpace.each_object(Class).with_object([]) do |klass, array|
|
981
1047
|
if klass < Base
|
982
1048
|
array << klass
|
@@ -997,6 +1063,7 @@ module Steep
|
|
997
1063
|
BlockBodyTypeMismatch => :warning,
|
998
1064
|
BlockTypeMismatch => :warning,
|
999
1065
|
BreakTypeMismatch => :hint,
|
1066
|
+
DeprecatedReference => :warning,
|
1000
1067
|
DifferentMethodParameterKind => :hint,
|
1001
1068
|
FallbackAny => :hint,
|
1002
1069
|
FalseAssertion => :hint,
|
@@ -1010,6 +1077,7 @@ module Steep
|
|
1010
1077
|
InvalidIgnoreComment => :warning,
|
1011
1078
|
MethodArityMismatch => :error,
|
1012
1079
|
MethodBodyTypeMismatch => :error,
|
1080
|
+
MethodDefinitionInUndeclaredModule => :information,
|
1013
1081
|
MethodDefinitionMissing => nil,
|
1014
1082
|
MethodParameterMismatch => :error,
|
1015
1083
|
MethodReturnTypeAnnotationMismatch => :hint,
|
@@ -1026,6 +1094,7 @@ module Steep
|
|
1026
1094
|
SyntaxError => :information,
|
1027
1095
|
TypeArgumentMismatchError => :hint,
|
1028
1096
|
UnannotatedEmptyCollection => :warning,
|
1097
|
+
UndeclaredMethodDefinition => :warning,
|
1029
1098
|
UnexpectedBlockGiven => :warning,
|
1030
1099
|
UnexpectedDynamicMethod => :hint,
|
1031
1100
|
UnexpectedError => :hint,
|
@@ -1057,6 +1126,7 @@ module Steep
|
|
1057
1126
|
BlockBodyTypeMismatch => :error,
|
1058
1127
|
BlockTypeMismatch => :error,
|
1059
1128
|
BreakTypeMismatch => :error,
|
1129
|
+
DeprecatedReference => :warning,
|
1060
1130
|
DifferentMethodParameterKind => :error,
|
1061
1131
|
FallbackAny => :warning,
|
1062
1132
|
FalseAssertion => :error,
|
@@ -1070,6 +1140,7 @@ module Steep
|
|
1070
1140
|
InvalidIgnoreComment => :warning,
|
1071
1141
|
MethodArityMismatch => :error,
|
1072
1142
|
MethodBodyTypeMismatch => :error,
|
1143
|
+
MethodDefinitionInUndeclaredModule => :warning,
|
1073
1144
|
MethodDefinitionMissing => :hint,
|
1074
1145
|
MethodParameterMismatch => :error,
|
1075
1146
|
MethodReturnTypeAnnotationMismatch => :error,
|
@@ -1086,6 +1157,7 @@ module Steep
|
|
1086
1157
|
SyntaxError => :information,
|
1087
1158
|
TypeArgumentMismatchError => :error,
|
1088
1159
|
UnannotatedEmptyCollection => :error,
|
1160
|
+
UndeclaredMethodDefinition => :warning,
|
1089
1161
|
UnexpectedBlockGiven => :error,
|
1090
1162
|
UnexpectedDynamicMethod => :information,
|
1091
1163
|
UnexpectedError => :information,
|
@@ -1117,6 +1189,7 @@ module Steep
|
|
1117
1189
|
BlockBodyTypeMismatch => :information,
|
1118
1190
|
BlockTypeMismatch => :information,
|
1119
1191
|
BreakTypeMismatch => :hint,
|
1192
|
+
DeprecatedReference => :warning,
|
1120
1193
|
DifferentMethodParameterKind => nil,
|
1121
1194
|
FallbackAny => nil,
|
1122
1195
|
FalseAssertion => nil,
|
@@ -1130,6 +1203,7 @@ module Steep
|
|
1130
1203
|
InvalidIgnoreComment => :warning,
|
1131
1204
|
MethodArityMismatch => :information,
|
1132
1205
|
MethodBodyTypeMismatch => :warning,
|
1206
|
+
MethodDefinitionInUndeclaredModule => :hint,
|
1133
1207
|
MethodDefinitionMissing => nil,
|
1134
1208
|
MethodParameterMismatch => :warning,
|
1135
1209
|
MethodReturnTypeAnnotationMismatch => nil,
|
@@ -1146,6 +1220,7 @@ module Steep
|
|
1146
1220
|
SyntaxError => :information,
|
1147
1221
|
TypeArgumentMismatchError => nil,
|
1148
1222
|
UnannotatedEmptyCollection => :hint,
|
1223
|
+
UndeclaredMethodDefinition => :information,
|
1149
1224
|
UnexpectedBlockGiven => :hint,
|
1150
1225
|
UnexpectedDynamicMethod => nil,
|
1151
1226
|
UnexpectedError => :hint,
|
@@ -460,6 +460,26 @@ module Steep
|
|
460
460
|
end
|
461
461
|
end
|
462
462
|
|
463
|
+
class DeprecatedTypeName < Base
|
464
|
+
attr_reader :type_name
|
465
|
+
attr_reader :message
|
466
|
+
|
467
|
+
def initialize(type_name, message, location:)
|
468
|
+
super(location: location)
|
469
|
+
@type_name = type_name
|
470
|
+
@message = message
|
471
|
+
end
|
472
|
+
|
473
|
+
def header_line
|
474
|
+
buffer = "Type `#{type_name}` is deprecated"
|
475
|
+
if message
|
476
|
+
buffer = +buffer
|
477
|
+
buffer << ": " << message
|
478
|
+
end
|
479
|
+
buffer
|
480
|
+
end
|
481
|
+
end
|
482
|
+
|
463
483
|
|
464
484
|
def self.from_rbs_error(error, factory:)
|
465
485
|
case error
|
data/lib/steep/drivers/check.rb
CHANGED
@@ -16,6 +16,7 @@ module Steep
|
|
16
16
|
attr_accessor :validate_group_signatures
|
17
17
|
attr_accessor :validate_project_signatures
|
18
18
|
attr_accessor :validate_library_signatures
|
19
|
+
attr_accessor :formatter
|
19
20
|
|
20
21
|
include Utils::DriverHelper
|
21
22
|
|
@@ -30,6 +31,7 @@ module Steep
|
|
30
31
|
@validate_group_signatures = true
|
31
32
|
@validate_project_signatures = false
|
32
33
|
@validate_library_signatures = false
|
34
|
+
@formatter = 'code'
|
33
35
|
end
|
34
36
|
|
35
37
|
def active_group?(group)
|
@@ -322,7 +324,7 @@ module Steep
|
|
322
324
|
errors.each do |notification|
|
323
325
|
path = Steep::PathHelper.to_pathname(notification[:uri]) or raise
|
324
326
|
buffer = RBS::Buffer.new(name: project.relative_path(path), content: path.read)
|
325
|
-
printer = DiagnosticPrinter.new(buffer: buffer, stdout: stdout)
|
327
|
+
printer = DiagnosticPrinter.new(buffer: buffer, stdout: stdout, formatter: formatter)
|
326
328
|
|
327
329
|
notification[:diagnostics].each do |diag|
|
328
330
|
printer.print(diag)
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Steep
|
2
|
+
module Drivers
|
3
|
+
class DiagnosticPrinter
|
4
|
+
class BaseFormatter
|
5
|
+
attr_reader :stdout
|
6
|
+
attr_reader :buffer
|
7
|
+
|
8
|
+
def initialize(stdout:, buffer:)
|
9
|
+
@stdout = stdout
|
10
|
+
@buffer = buffer
|
11
|
+
end
|
12
|
+
|
13
|
+
def path
|
14
|
+
Pathname(buffer.name)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|