steep 0.43.1 → 0.46.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/.github/dependabot.yml +8 -0
- data/.github/workflows/ruby.yml +4 -2
- data/.gitignore +0 -1
- data/CHANGELOG.md +41 -0
- data/Gemfile +0 -1
- data/Gemfile.lock +77 -0
- data/bin/output_test.rb +8 -2
- data/lib/steep/ast/builtin.rb +7 -1
- data/lib/steep/ast/types/factory.rb +19 -25
- data/lib/steep/cli.rb +7 -1
- data/lib/steep/diagnostic/lsp_formatter.rb +59 -6
- data/lib/steep/diagnostic/ruby.rb +188 -60
- data/lib/steep/diagnostic/signature.rb +34 -0
- data/lib/steep/drivers/check.rb +3 -0
- data/lib/steep/drivers/init.rb +10 -3
- data/lib/steep/drivers/utils/driver_helper.rb +15 -0
- data/lib/steep/drivers/validate.rb +1 -1
- data/lib/steep/drivers/watch.rb +3 -0
- data/lib/steep/equatable.rb +21 -0
- data/lib/steep/index/source_index.rb +55 -5
- data/lib/steep/interface/block.rb +4 -0
- data/lib/steep/interface/function.rb +798 -579
- data/lib/steep/project/dsl.rb +105 -33
- data/lib/steep/project/options.rb +12 -53
- data/lib/steep/project/target.rb +21 -8
- data/lib/steep/server/interaction_worker.rb +239 -20
- data/lib/steep/server/master.rb +22 -1
- data/lib/steep/server/type_check_worker.rb +74 -9
- data/lib/steep/services/file_loader.rb +26 -19
- data/lib/steep/services/goto_service.rb +322 -0
- data/lib/steep/services/hover_content.rb +132 -80
- data/lib/steep/services/type_check_service.rb +25 -0
- data/lib/steep/source.rb +7 -10
- data/lib/steep/type_construction.rb +496 -518
- data/lib/steep/type_inference/block_params.rb +2 -5
- data/lib/steep/type_inference/method_params.rb +483 -0
- data/lib/steep/type_inference/send_args.rb +610 -128
- data/lib/steep/typing.rb +46 -21
- data/lib/steep/version.rb +1 -1
- data/lib/steep.rb +4 -1
- data/sample/Steepfile +10 -3
- data/sig/steep/type_inference/send_args.rbs +42 -0
- data/smoke/alias/Steepfile +2 -1
- data/smoke/and/Steepfile +2 -1
- data/smoke/array/Steepfile +2 -1
- data/smoke/array/test_expectations.yml +3 -3
- data/smoke/block/Steepfile +2 -2
- data/smoke/block/c.rb +0 -1
- data/smoke/case/Steepfile +2 -1
- data/smoke/class/Steepfile +2 -1
- data/smoke/class/test_expectations.yml +12 -15
- data/smoke/const/Steepfile +2 -1
- data/smoke/const/test_expectations.yml +0 -10
- data/smoke/diagnostics/Steepfile +2 -1
- data/smoke/diagnostics/a.rbs +0 -4
- data/smoke/diagnostics/different_method_parameter_kind.rb +9 -0
- data/smoke/diagnostics/method_arity_mismatch.rb +2 -2
- data/smoke/diagnostics/method_parameter_mismatch.rb +10 -0
- data/smoke/diagnostics/test_expectations.yml +108 -57
- data/smoke/diagnostics-rbs/Steepfile +1 -1
- data/smoke/diagnostics-rbs/mixin-class-error.rbs +6 -0
- data/smoke/diagnostics-rbs/test_expectations.yml +12 -0
- data/smoke/diagnostics-rbs-duplicated/Steepfile +2 -1
- data/smoke/diagnostics-ruby-unsat/Steepfile +6 -0
- data/smoke/diagnostics-ruby-unsat/a.rbs +3 -0
- data/smoke/diagnostics-ruby-unsat/test_expectations.yml +27 -0
- data/smoke/{diagnostics → diagnostics-ruby-unsat}/unsatisfiable_constraint.rb +0 -1
- data/smoke/dstr/Steepfile +2 -1
- data/smoke/ensure/Steepfile +2 -1
- data/smoke/ensure/test_expectations.yml +3 -3
- data/smoke/enumerator/Steepfile +2 -1
- data/smoke/enumerator/test_expectations.yml +1 -1
- data/smoke/extension/Steepfile +2 -1
- data/smoke/hash/Steepfile +2 -1
- data/smoke/hello/Steepfile +2 -1
- data/smoke/if/Steepfile +2 -1
- data/smoke/implements/Steepfile +2 -1
- data/smoke/initialize/Steepfile +2 -1
- data/smoke/integer/Steepfile +2 -1
- data/smoke/interface/Steepfile +2 -1
- data/smoke/kwbegin/Steepfile +2 -1
- data/smoke/lambda/Steepfile +2 -1
- data/smoke/literal/Steepfile +2 -1
- data/smoke/literal/test_expectations.yml +2 -2
- data/smoke/map/Steepfile +2 -1
- data/smoke/method/Steepfile +2 -1
- data/smoke/method/test_expectations.yml +11 -10
- data/smoke/module/Steepfile +2 -1
- data/smoke/regexp/Steepfile +2 -1
- data/smoke/regression/Steepfile +2 -1
- data/smoke/regression/issue_372.rb +8 -0
- data/smoke/regression/issue_372.rbs +4 -0
- data/smoke/regression/test_expectations.yml +0 -12
- data/smoke/rescue/Steepfile +2 -1
- data/smoke/rescue/test_expectations.yml +3 -3
- data/smoke/self/Steepfile +2 -1
- data/smoke/skip/Steepfile +2 -1
- data/smoke/stdout/Steepfile +2 -1
- data/smoke/super/Steepfile +2 -1
- data/smoke/toplevel/Steepfile +2 -1
- data/smoke/toplevel/test_expectations.yml +3 -3
- data/smoke/tsort/Steepfile +4 -5
- data/smoke/tsort/test_expectations.yml +2 -2
- data/smoke/type_case/Steepfile +2 -1
- data/smoke/unexpected/Steepfile +2 -1
- data/smoke/yield/Steepfile +2 -1
- data/steep.gemspec +2 -2
- metadata +24 -10
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: e43c16938ef0238a9b3e44934a3e183ec663722b4c1161f9bd016dfcd2442b9b
|
|
4
|
+
data.tar.gz: 20168ebc69417b83c9eff010d44aac53ac43f47c572c8acc99d52d08ec11866d
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 33c2bd116ea87f549ffb29fbc2382e7c000405a74280fcc4a1a8553ae52e6b7af3d5611a150c828d494fe50f37e120e58e45f286bd374bbd35958ee0c760c872
|
|
7
|
+
data.tar.gz: 0466f3f59d18bf0ba34ce522bc6a1cceed85c1f6ca4df66b6647a557bec165c64dd9d594f673833dc24a0b5a9d0eb04795bff37dc391e22cf560b566c6f08319
|
data/.github/workflows/ruby.yml
CHANGED
data/.gitignore
CHANGED
data/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,47 @@
|
|
|
2
2
|
|
|
3
3
|
## master
|
|
4
4
|
|
|
5
|
+
## 0.46.0 (2021-08-30)
|
|
6
|
+
|
|
7
|
+
This release updates Steepfile DSL syntax, introducing `stdlib_path` and `configure_code_diagnostics` syntax (methods).
|
|
8
|
+
|
|
9
|
+
* `stdlib_path` allows configuring core/stdlib RBS file locations.
|
|
10
|
+
* `configure_code_diagnostics` allows configuring _severity_ of each type errors.
|
|
11
|
+
|
|
12
|
+
See the PRs for the explanation of these methods.
|
|
13
|
+
You can try `steep init` to generate updated `Steepfile` template.
|
|
14
|
+
|
|
15
|
+
* Flexible diagnostics configuration ([\#422](https://github.com/soutaro/steep/pull/422), [\#423](https://github.com/soutaro/steep/pull/423))
|
|
16
|
+
* Revise Steepfile _path_ DSL ([\#421](https://github.com/soutaro/steep/pull/421))
|
|
17
|
+
* Avoid to stop process by invalid jobs_count ([\#419](https://github.com/soutaro/steep/pull/419))
|
|
18
|
+
* Fix `Steep::Typing::UnknownNodeError` when hover method with numblock ([\#415](https://github.com/soutaro/steep/pull/415))
|
|
19
|
+
|
|
20
|
+
## 0.45.0 (2021-08-22)
|
|
21
|
+
|
|
22
|
+
* Fix error reporting on `RBS::MixinClassError` ([\#411](https://github.com/soutaro/steep/pull/411))
|
|
23
|
+
* Compact error reporting for method body type mismatch ([\#414](https://github.com/soutaro/steep/pull/414))
|
|
24
|
+
* Fix NoMethodError with csend/numblock ([\#412](https://github.com/soutaro/steep/pull/412))
|
|
25
|
+
* LSP completion for RBS files ([\#404](https://github.com/soutaro/steep/pull/404))
|
|
26
|
+
* Allow break without value from bot methods ([\#398](https://github.com/soutaro/steep/pull/398))
|
|
27
|
+
* Type check on lvar assignments ([\#390](https://github.com/soutaro/steep/pull/390))
|
|
28
|
+
* Assign different error code to break without value ([\#387](https://github.com/soutaro/steep/pull/387))
|
|
29
|
+
* Support Ruby3 Keyword Arguments ([\#386](https://github.com/soutaro/steep/pull/386))
|
|
30
|
+
* LSP hover for RBS files ([\#385](https://github.com/soutaro/steep/pull/385), [\#397](https://github.com/soutaro/steep/pull/397))
|
|
31
|
+
* Fix FileLoader to skip files not matching to the given pattern ([\#382](https://github.com/soutaro/steep/pull/382))
|
|
32
|
+
* Ruby3 support for numbered block parameters and end-less def ([\#381](https://github.com/soutaro/steep/pull/381))
|
|
33
|
+
|
|
34
|
+
## 0.44.1 (2021-04-23)
|
|
35
|
+
|
|
36
|
+
* Disable goto declaration and goto type declaration (because they are not implemented) ([#377](https://github.com/soutaro/steep/pull/377))
|
|
37
|
+
* Fix goto from block calls ([#378](https://github.com/soutaro/steep/pull/378))
|
|
38
|
+
|
|
39
|
+
## 0.44.0 (2021-04-22)
|
|
40
|
+
|
|
41
|
+
* Implement LSP go to definition/implementation ([#371](https://github.com/soutaro/steep/pull/371), [#375](https://github.com/soutaro/steep/pull/375))
|
|
42
|
+
* Fix typing on passing optional block ([#373](https://github.com/soutaro/steep/pull/373))
|
|
43
|
+
* Do not crash when completion request `context` is missing ([#370](https://github.com/soutaro/steep/pull/370))
|
|
44
|
+
* Update RBS ([#376](https://github.com/soutaro/steep/pull/376))
|
|
45
|
+
|
|
5
46
|
## 0.43.1 (2021-04-01)
|
|
6
47
|
|
|
7
48
|
* Fix LSP `textDocument/didSave` notification handling ([#368](https://github.com/soutaro/steep/issues/368))
|
data/Gemfile
CHANGED
data/Gemfile.lock
ADDED
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
PATH
|
|
2
|
+
remote: .
|
|
3
|
+
specs:
|
|
4
|
+
steep (0.46.0)
|
|
5
|
+
activesupport (>= 5.1)
|
|
6
|
+
language_server-protocol (>= 3.15, < 4.0)
|
|
7
|
+
listen (~> 3.0)
|
|
8
|
+
parallel (>= 1.0.0)
|
|
9
|
+
parser (>= 3.0)
|
|
10
|
+
rainbow (>= 2.2.2, < 4.0)
|
|
11
|
+
rbs (>= 1.2.0)
|
|
12
|
+
terminal-table (>= 2, < 4)
|
|
13
|
+
|
|
14
|
+
PATH
|
|
15
|
+
remote: test/gems/with_steep_types
|
|
16
|
+
specs:
|
|
17
|
+
with_steep_types (1.0.0)
|
|
18
|
+
|
|
19
|
+
PATH
|
|
20
|
+
remote: test/gems/without_steep_types
|
|
21
|
+
specs:
|
|
22
|
+
without_steep_types (1.0.0)
|
|
23
|
+
|
|
24
|
+
GEM
|
|
25
|
+
remote: https://rubygems.org/
|
|
26
|
+
specs:
|
|
27
|
+
activesupport (6.1.4.1)
|
|
28
|
+
concurrent-ruby (~> 1.0, >= 1.0.2)
|
|
29
|
+
i18n (>= 1.6, < 2)
|
|
30
|
+
minitest (>= 5.1)
|
|
31
|
+
tzinfo (~> 2.0)
|
|
32
|
+
zeitwerk (~> 2.3)
|
|
33
|
+
ast (2.4.2)
|
|
34
|
+
concurrent-ruby (1.1.9)
|
|
35
|
+
ffi (1.15.3)
|
|
36
|
+
i18n (1.8.10)
|
|
37
|
+
concurrent-ruby (~> 1.0)
|
|
38
|
+
language_server-protocol (3.16.0.2)
|
|
39
|
+
listen (3.7.0)
|
|
40
|
+
rb-fsevent (~> 0.10, >= 0.10.3)
|
|
41
|
+
rb-inotify (~> 0.9, >= 0.9.10)
|
|
42
|
+
minitest (5.14.4)
|
|
43
|
+
minitest-hooks (1.5.0)
|
|
44
|
+
minitest (> 5.3)
|
|
45
|
+
parallel (1.20.1)
|
|
46
|
+
parser (3.0.2.0)
|
|
47
|
+
ast (~> 2.4.1)
|
|
48
|
+
racc (1.5.2)
|
|
49
|
+
rainbow (3.0.0)
|
|
50
|
+
rake (13.0.6)
|
|
51
|
+
rb-fsevent (0.11.0)
|
|
52
|
+
rb-inotify (0.10.1)
|
|
53
|
+
ffi (~> 1.0)
|
|
54
|
+
rbs (1.5.1)
|
|
55
|
+
stackprof (0.2.17)
|
|
56
|
+
terminal-table (3.0.1)
|
|
57
|
+
unicode-display_width (>= 1.1.1, < 3)
|
|
58
|
+
tzinfo (2.0.4)
|
|
59
|
+
concurrent-ruby (~> 1.0)
|
|
60
|
+
unicode-display_width (2.0.0)
|
|
61
|
+
zeitwerk (2.4.2)
|
|
62
|
+
|
|
63
|
+
PLATFORMS
|
|
64
|
+
ruby
|
|
65
|
+
|
|
66
|
+
DEPENDENCIES
|
|
67
|
+
minitest (~> 5.0)
|
|
68
|
+
minitest-hooks
|
|
69
|
+
racc (~> 1.4)
|
|
70
|
+
rake
|
|
71
|
+
stackprof
|
|
72
|
+
steep!
|
|
73
|
+
with_steep_types!
|
|
74
|
+
without_steep_types!
|
|
75
|
+
|
|
76
|
+
BUNDLED WITH
|
|
77
|
+
2.2.22
|
data/bin/output_test.rb
CHANGED
|
@@ -16,6 +16,8 @@ end
|
|
|
16
16
|
|
|
17
17
|
failed_tests = []
|
|
18
18
|
|
|
19
|
+
ALLOW_FAILURE = ["diagnostics-ruby-unsat"]
|
|
20
|
+
|
|
19
21
|
test_dirs.each do |dir|
|
|
20
22
|
puts "Running test #{dir}..."
|
|
21
23
|
|
|
@@ -30,8 +32,12 @@ test_dirs.each do |dir|
|
|
|
30
32
|
output, status = Open3.capture2(*command, chdir: dir.to_s)
|
|
31
33
|
|
|
32
34
|
unless status.success?
|
|
33
|
-
|
|
34
|
-
|
|
35
|
+
unless ALLOW_FAILURE.include?(dir.basename.to_s)
|
|
36
|
+
failed_tests << dir.basename
|
|
37
|
+
puts " Failed! 🤕"
|
|
38
|
+
else
|
|
39
|
+
puts " Failed! 🤕 (ALLOW_FAILURE)"
|
|
40
|
+
end
|
|
35
41
|
else
|
|
36
42
|
puts " Succeed! 👍"
|
|
37
43
|
end
|
data/lib/steep/ast/builtin.rb
CHANGED
|
@@ -10,8 +10,14 @@ module Steep
|
|
|
10
10
|
@arity = arity
|
|
11
11
|
end
|
|
12
12
|
|
|
13
|
-
def instance_type(*args)
|
|
13
|
+
def instance_type(*args, fill_untyped: false)
|
|
14
|
+
if fill_untyped
|
|
15
|
+
(arity - args.size).times do
|
|
16
|
+
args << Builtin.any_type
|
|
17
|
+
end
|
|
18
|
+
end
|
|
14
19
|
arity == args.size or raise "Mulformed instance type: name=#{module_name}, args=#{args}"
|
|
20
|
+
|
|
15
21
|
Types::Name::Instance.new(name: module_name, args: args)
|
|
16
22
|
end
|
|
17
23
|
|
|
@@ -194,7 +194,7 @@ module Steep
|
|
|
194
194
|
end
|
|
195
195
|
|
|
196
196
|
def params(type)
|
|
197
|
-
Interface::Function::Params.
|
|
197
|
+
Interface::Function::Params.build(
|
|
198
198
|
required: type.required_positionals.map {|param| type(param.type) },
|
|
199
199
|
optional: type.optional_positionals.map {|param| type(param.type) },
|
|
200
200
|
rest: type.rest_positionals&.yield_self {|param| type(param.type) },
|
|
@@ -621,12 +621,7 @@ module Steep
|
|
|
621
621
|
Interface::MethodType.new(
|
|
622
622
|
type_params: [],
|
|
623
623
|
type: Interface::Function.new(
|
|
624
|
-
params: Interface::Function::Params.
|
|
625
|
-
optional: [],
|
|
626
|
-
rest: nil,
|
|
627
|
-
required_keywords: {},
|
|
628
|
-
optional_keywords: {},
|
|
629
|
-
rest_keywords: nil),
|
|
624
|
+
params: Interface::Function::Params.build(required: [AST::Types::Literal.new(value: index)]),
|
|
630
625
|
return_type: elem_type,
|
|
631
626
|
location: nil
|
|
632
627
|
),
|
|
@@ -643,12 +638,7 @@ module Steep
|
|
|
643
638
|
Interface::MethodType.new(
|
|
644
639
|
type_params: [],
|
|
645
640
|
type: Interface::Function.new(
|
|
646
|
-
params: Interface::Function::Params.
|
|
647
|
-
optional: [],
|
|
648
|
-
rest: nil,
|
|
649
|
-
required_keywords: {},
|
|
650
|
-
optional_keywords: {},
|
|
651
|
-
rest_keywords: nil),
|
|
641
|
+
params: Interface::Function::Params.build(required: [AST::Types::Literal.new(value: index), elem_type]),
|
|
652
642
|
return_type: elem_type,
|
|
653
643
|
location: nil
|
|
654
644
|
),
|
|
@@ -712,12 +702,14 @@ module Steep
|
|
|
712
702
|
Interface::MethodType.new(
|
|
713
703
|
type_params: [],
|
|
714
704
|
type: Interface::Function.new(
|
|
715
|
-
params: Interface::Function::Params.
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
705
|
+
params: Interface::Function::Params.build(
|
|
706
|
+
required: [key_type],
|
|
707
|
+
optional: [],
|
|
708
|
+
rest: nil,
|
|
709
|
+
required_keywords: {},
|
|
710
|
+
optional_keywords: {},
|
|
711
|
+
rest_keywords: nil
|
|
712
|
+
),
|
|
721
713
|
return_type: value_type,
|
|
722
714
|
location: nil
|
|
723
715
|
),
|
|
@@ -735,12 +727,14 @@ module Steep
|
|
|
735
727
|
Interface::MethodType.new(
|
|
736
728
|
type_params: [],
|
|
737
729
|
type: Interface::Function.new(
|
|
738
|
-
params: Interface::Function::Params.
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
730
|
+
params: Interface::Function::Params.build(
|
|
731
|
+
required: [key_type, value_type],
|
|
732
|
+
optional: [],
|
|
733
|
+
rest: nil,
|
|
734
|
+
required_keywords: {},
|
|
735
|
+
optional_keywords: {},
|
|
736
|
+
rest_keywords: nil
|
|
737
|
+
),
|
|
744
738
|
return_type: value_type,
|
|
745
739
|
location: nil),
|
|
746
740
|
block: nil,
|
data/lib/steep/cli.rb
CHANGED
|
@@ -70,7 +70,7 @@ module Steep
|
|
|
70
70
|
default = physical_processor_count + modifier
|
|
71
71
|
command.jobs_count = default
|
|
72
72
|
opts.on("-j N", "--jobs=N", "Specify the number of type check workers (defaults: #{default})") do |count|
|
|
73
|
-
command.jobs_count = Integer(count)
|
|
73
|
+
command.jobs_count = Integer(count) if Integer(count) > 0
|
|
74
74
|
end
|
|
75
75
|
end
|
|
76
76
|
|
|
@@ -99,6 +99,9 @@ module Steep
|
|
|
99
99
|
opts.on("--save-expectations[=PATH]", "Save expectations with current type check result to PATH (or steep_expectations.yml)") do |path|
|
|
100
100
|
check.save_expectations_path = Pathname(path || "steep_expectations.yml")
|
|
101
101
|
end
|
|
102
|
+
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|
|
|
103
|
+
check.severity_level = level.to_sym
|
|
104
|
+
end
|
|
102
105
|
handle_jobs_option check, opts
|
|
103
106
|
handle_logging_options opts
|
|
104
107
|
end.parse!(argv)
|
|
@@ -155,6 +158,9 @@ module Steep
|
|
|
155
158
|
Drivers::Watch.new(stdout: stdout, stderr: stderr).tap do |command|
|
|
156
159
|
OptionParser.new do |opts|
|
|
157
160
|
opts.banner = "Usage: steep watch [options] [dirs]"
|
|
161
|
+
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|
|
|
162
|
+
command.severity_level = level.to_sym
|
|
163
|
+
end
|
|
158
164
|
handle_jobs_option command, opts
|
|
159
165
|
handle_logging_options opts
|
|
160
166
|
end.parse!(argv)
|
|
@@ -3,13 +3,66 @@ module Steep
|
|
|
3
3
|
class LSPFormatter
|
|
4
4
|
LSP = LanguageServer::Protocol
|
|
5
5
|
|
|
6
|
+
attr_reader :config
|
|
7
|
+
attr_reader :default_severity
|
|
8
|
+
|
|
9
|
+
ERROR = :error
|
|
10
|
+
WARNING = :warning
|
|
11
|
+
INFORMATION = :information
|
|
12
|
+
HINT = :hint
|
|
13
|
+
|
|
14
|
+
def initialize(config = {}, default_severity: ERROR)
|
|
15
|
+
@config = config
|
|
16
|
+
@default_severity = default_severity
|
|
17
|
+
|
|
18
|
+
config.each do |klass, severity|
|
|
19
|
+
validate_severity(klass, severity)
|
|
20
|
+
validate_class(klass)
|
|
21
|
+
end
|
|
22
|
+
validate_severity(:default, default_severity)
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def validate_class(klass)
|
|
26
|
+
unless klass < Diagnostic::Ruby::Base
|
|
27
|
+
raise "Unexpected diagnostics class `#{klass}` given"
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def validate_severity(klass, severity)
|
|
32
|
+
case severity
|
|
33
|
+
when ERROR, WARNING, INFORMATION, HINT, nil
|
|
34
|
+
# ok
|
|
35
|
+
else
|
|
36
|
+
raise "Unexpected severity `#{severity}` is specified for #{klass}"
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
6
40
|
def format(diagnostic)
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
41
|
+
severity = severity_for(diagnostic)
|
|
42
|
+
|
|
43
|
+
if severity
|
|
44
|
+
LSP::Interface::Diagnostic.new(
|
|
45
|
+
message: diagnostic.full_message,
|
|
46
|
+
code: diagnostic.diagnostic_code,
|
|
47
|
+
severity: severity,
|
|
48
|
+
range: diagnostic.location.as_lsp_range
|
|
49
|
+
).to_hash
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def severity_for(diagnostic)
|
|
54
|
+
case config.fetch(diagnostic.class, default_severity)
|
|
55
|
+
when ERROR
|
|
56
|
+
LSP::Constant::DiagnosticSeverity::ERROR
|
|
57
|
+
when WARNING
|
|
58
|
+
LSP::Constant::DiagnosticSeverity::WARNING
|
|
59
|
+
when INFORMATION
|
|
60
|
+
LSP::Constant::DiagnosticSeverity::INFORMATION
|
|
61
|
+
when HINT
|
|
62
|
+
LSP::Constant::DiagnosticSeverity::HINT
|
|
63
|
+
when nil
|
|
64
|
+
nil
|
|
65
|
+
end
|
|
13
66
|
end
|
|
14
67
|
end
|
|
15
68
|
end
|
|
@@ -71,46 +71,104 @@ module Steep
|
|
|
71
71
|
end
|
|
72
72
|
end
|
|
73
73
|
|
|
74
|
-
class
|
|
74
|
+
class UnexpectedPositionalArgument < Base
|
|
75
75
|
attr_reader :node
|
|
76
|
+
attr_reader :method_type
|
|
76
77
|
attr_reader :method_name
|
|
77
|
-
attr_reader :receiver_type
|
|
78
|
-
attr_reader :method_types
|
|
79
78
|
|
|
80
|
-
def initialize(node:, method_name:,
|
|
81
|
-
|
|
82
|
-
when :send
|
|
83
|
-
node.loc.selector
|
|
84
|
-
when :block
|
|
85
|
-
node.children[0].yield_self do |node|
|
|
86
|
-
node.loc.selector
|
|
87
|
-
end
|
|
88
|
-
when :super
|
|
89
|
-
node.loc.expression
|
|
90
|
-
else
|
|
91
|
-
Steep.logger.error { "Unexpected node given: #{node.type} (IncompatibleArguments#initialize)"}
|
|
92
|
-
node.loc.expression
|
|
93
|
-
end
|
|
94
|
-
super(node: node, location: location)
|
|
95
|
-
@receiver_type = receiver_type
|
|
96
|
-
@method_types = method_types
|
|
79
|
+
def initialize(node:, method_name:, method_type:)
|
|
80
|
+
super(node: node)
|
|
97
81
|
@method_name = method_name
|
|
82
|
+
@method_type = method_type
|
|
98
83
|
end
|
|
99
84
|
|
|
100
85
|
def header_line
|
|
101
|
-
"
|
|
86
|
+
"Unexpected positional argument"
|
|
102
87
|
end
|
|
88
|
+
end
|
|
103
89
|
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
90
|
+
class InsufficientPositionalArguments < Base
|
|
91
|
+
attr_reader :node
|
|
92
|
+
attr_reader :method_name
|
|
93
|
+
attr_reader :method_type
|
|
94
|
+
|
|
95
|
+
def initialize(node:, method_name:, method_type:)
|
|
96
|
+
send = case node.type
|
|
97
|
+
when :send, :csend
|
|
98
|
+
node
|
|
99
|
+
when :block, :numblock
|
|
100
|
+
node.children[0]
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
loc = if send
|
|
104
|
+
send.loc.selector.with(end_pos: send.loc.expression.end_pos)
|
|
105
|
+
else
|
|
106
|
+
node.loc.expression
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
super(node: node, location: loc)
|
|
110
|
+
@method_name = method_name
|
|
111
|
+
@method_type = method_type
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
def header_line
|
|
115
|
+
"More positional arguments are required"
|
|
116
|
+
end
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
class UnexpectedKeywordArgument < Base
|
|
120
|
+
attr_reader :node
|
|
121
|
+
attr_reader :method_name
|
|
122
|
+
attr_reader :method_type
|
|
123
|
+
|
|
124
|
+
def initialize(node:, method_name:, method_type:)
|
|
125
|
+
loc = case node.type
|
|
126
|
+
when :pair
|
|
127
|
+
node.children[0].location.expression
|
|
128
|
+
when :kwsplat
|
|
129
|
+
node.location.expression
|
|
130
|
+
else
|
|
131
|
+
raise
|
|
132
|
+
end
|
|
133
|
+
super(node: node, location: loc)
|
|
134
|
+
@method_name = method_name
|
|
135
|
+
@method_type = method_type
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
def header_line
|
|
139
|
+
"Unexpected keyword argument"
|
|
140
|
+
end
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
class InsufficientKeywordArguments < Base
|
|
144
|
+
attr_reader :node
|
|
145
|
+
attr_reader :method_name
|
|
146
|
+
attr_reader :method_type
|
|
147
|
+
attr_reader :missing_keywords
|
|
148
|
+
|
|
149
|
+
def initialize(node:, method_name:, method_type:, missing_keywords:)
|
|
150
|
+
send = case node.type
|
|
151
|
+
when :send, :csend
|
|
152
|
+
node
|
|
153
|
+
when :block, :numblock
|
|
154
|
+
node.children[0]
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
loc = if send
|
|
158
|
+
send.loc.selector.with(end_pos: send.loc.expression.end_pos)
|
|
159
|
+
else
|
|
160
|
+
node.loc.expression
|
|
161
|
+
end
|
|
162
|
+
|
|
163
|
+
super(node: node, location: loc)
|
|
164
|
+
|
|
165
|
+
@method_name = method_name
|
|
166
|
+
@method_type = method_type
|
|
167
|
+
@missing_keywords = missing_keywords
|
|
168
|
+
end
|
|
169
|
+
|
|
170
|
+
def header_line
|
|
171
|
+
"More keyword arguments are required: #{missing_keywords.join(", ")}"
|
|
114
172
|
end
|
|
115
173
|
end
|
|
116
174
|
|
|
@@ -292,6 +350,23 @@ module Steep
|
|
|
292
350
|
end
|
|
293
351
|
end
|
|
294
352
|
|
|
353
|
+
class ImplicitBreakValueMismatch < Base
|
|
354
|
+
attr_reader :jump_type
|
|
355
|
+
attr_reader :result
|
|
356
|
+
|
|
357
|
+
include ResultPrinter
|
|
358
|
+
|
|
359
|
+
def initialize(node:, jump_type:, result:)
|
|
360
|
+
super(node: node)
|
|
361
|
+
@jump_type = jump_type
|
|
362
|
+
@result = result
|
|
363
|
+
end
|
|
364
|
+
|
|
365
|
+
def header_line
|
|
366
|
+
"Breaking without a value may result an error because a value of type `#{jump_type}` is expected"
|
|
367
|
+
end
|
|
368
|
+
end
|
|
369
|
+
|
|
295
370
|
class UnexpectedJump < Base
|
|
296
371
|
def header_line
|
|
297
372
|
"Cannot jump from here"
|
|
@@ -323,6 +398,36 @@ module Steep
|
|
|
323
398
|
end
|
|
324
399
|
end
|
|
325
400
|
|
|
401
|
+
class MethodParameterMismatch < Base
|
|
402
|
+
attr_reader :method_param
|
|
403
|
+
attr_reader :method_type
|
|
404
|
+
|
|
405
|
+
def initialize(method_param:, method_type:)
|
|
406
|
+
super(node: method_param.node)
|
|
407
|
+
@method_param = method_param
|
|
408
|
+
@method_type = method_type
|
|
409
|
+
end
|
|
410
|
+
|
|
411
|
+
def header_line
|
|
412
|
+
"The method parameter is incompatible with the declaration `#{method_type}`"
|
|
413
|
+
end
|
|
414
|
+
end
|
|
415
|
+
|
|
416
|
+
class DifferentMethodParameterKind < Base
|
|
417
|
+
attr_reader :method_param
|
|
418
|
+
attr_reader :method_type
|
|
419
|
+
|
|
420
|
+
def initialize(method_param:, method_type:)
|
|
421
|
+
super(node: method_param.node)
|
|
422
|
+
@method_param = method_param
|
|
423
|
+
@method_type = method_type
|
|
424
|
+
end
|
|
425
|
+
|
|
426
|
+
def header_line
|
|
427
|
+
"The method parameter has different kind from the declaration `#{method_type}`"
|
|
428
|
+
end
|
|
429
|
+
end
|
|
430
|
+
|
|
326
431
|
class IncompatibleMethodTypeAnnotation < Base
|
|
327
432
|
attr_reader :interface_method
|
|
328
433
|
attr_reader :annotation_method
|
|
@@ -366,7 +471,7 @@ module Steep
|
|
|
366
471
|
include ResultPrinter
|
|
367
472
|
|
|
368
473
|
def initialize(node:, expected:, actual:, result:)
|
|
369
|
-
super(node: node)
|
|
474
|
+
super(node: node, location: node.loc.name)
|
|
370
475
|
@expected = expected
|
|
371
476
|
@actual = actual
|
|
372
477
|
@result = result
|
|
@@ -552,34 +657,6 @@ module Steep
|
|
|
552
657
|
end
|
|
553
658
|
end
|
|
554
659
|
|
|
555
|
-
class UnexpectedKeyword < Base
|
|
556
|
-
attr_reader :unexpected_keywords
|
|
557
|
-
|
|
558
|
-
def initialize(node:, unexpected_keywords:)
|
|
559
|
-
super(node: node)
|
|
560
|
-
@unexpected_keywords = unexpected_keywords
|
|
561
|
-
end
|
|
562
|
-
|
|
563
|
-
def header_line
|
|
564
|
-
keywords = unexpected_keywords.sort.map {|x| "`#{x}`" }
|
|
565
|
-
"Cannot specify unexpected keyword arguments: #{keywords.join(", ")}"
|
|
566
|
-
end
|
|
567
|
-
end
|
|
568
|
-
|
|
569
|
-
class MissingKeyword < Base
|
|
570
|
-
attr_reader :missing_keywords
|
|
571
|
-
|
|
572
|
-
def initialize(node:, missing_keywords:)
|
|
573
|
-
super(node: node)
|
|
574
|
-
@missing_keywords = missing_keywords
|
|
575
|
-
end
|
|
576
|
-
|
|
577
|
-
def header_line
|
|
578
|
-
keywords = missing_keywords.sort.map {|x| "`#{x}`" }
|
|
579
|
-
"Cannot omit required keywords: #{keywords.join(", ")}"
|
|
580
|
-
end
|
|
581
|
-
end
|
|
582
|
-
|
|
583
660
|
class UnsupportedSyntax < Base
|
|
584
661
|
attr_reader :message
|
|
585
662
|
|
|
@@ -623,6 +700,57 @@ module Steep
|
|
|
623
700
|
"SyntaxError: #{message}"
|
|
624
701
|
end
|
|
625
702
|
end
|
|
703
|
+
|
|
704
|
+
ALL = ObjectSpace.each_object(Class).with_object([]) do |klass, array|
|
|
705
|
+
if klass < Base
|
|
706
|
+
array << klass
|
|
707
|
+
end
|
|
708
|
+
end
|
|
709
|
+
|
|
710
|
+
def self.all_error
|
|
711
|
+
@all_error ||= ALL.each.with_object({}) do |klass, hash|
|
|
712
|
+
hash[klass] = LSPFormatter::ERROR
|
|
713
|
+
end.freeze
|
|
714
|
+
end
|
|
715
|
+
|
|
716
|
+
def self.default
|
|
717
|
+
@default ||= all_error.merge(
|
|
718
|
+
{
|
|
719
|
+
ImplicitBreakValueMismatch => :warning,
|
|
720
|
+
FallbackAny => :information,
|
|
721
|
+
ElseOnExhaustiveCase => :warning,
|
|
722
|
+
UnknownConstantAssigned => :warning,
|
|
723
|
+
MethodDefinitionMissing => :information
|
|
724
|
+
}
|
|
725
|
+
).freeze
|
|
726
|
+
end
|
|
727
|
+
|
|
728
|
+
def self.strict
|
|
729
|
+
@strict ||= all_error.merge(
|
|
730
|
+
{
|
|
731
|
+
NoMethod => nil,
|
|
732
|
+
ImplicitBreakValueMismatch => nil,
|
|
733
|
+
FallbackAny => nil,
|
|
734
|
+
ElseOnExhaustiveCase => nil,
|
|
735
|
+
UnknownConstantAssigned => nil,
|
|
736
|
+
MethodDefinitionMissing => nil
|
|
737
|
+
}
|
|
738
|
+
).freeze
|
|
739
|
+
end
|
|
740
|
+
|
|
741
|
+
def self.lenient
|
|
742
|
+
@lenient ||= all_error.merge(
|
|
743
|
+
{
|
|
744
|
+
NoMethod => nil,
|
|
745
|
+
ImplicitBreakValueMismatch => nil,
|
|
746
|
+
FallbackAny => nil,
|
|
747
|
+
ElseOnExhaustiveCase => nil,
|
|
748
|
+
UnknownConstantAssigned => nil,
|
|
749
|
+
MethodDefinitionMissing => nil,
|
|
750
|
+
UnexpectedJump => nil
|
|
751
|
+
}
|
|
752
|
+
).freeze
|
|
753
|
+
end
|
|
626
754
|
end
|
|
627
755
|
end
|
|
628
756
|
end
|