steep 1.9.0.dev.2 → 1.9.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 +76 -0
- data/README.md +9 -4
- data/Rakefile +1 -0
- data/Steepfile +11 -0
- data/bin/generate-diagnostics-docs.rb +112 -0
- data/lib/steep/ast/builtin.rb +1 -0
- data/lib/steep/ast/ignore.rb +1 -1
- data/lib/steep/ast/types/factory.rb +2 -0
- data/lib/steep/cli.rb +9 -2
- data/lib/steep/diagnostic/lsp_formatter.rb +8 -1
- data/lib/steep/diagnostic/ruby.rb +65 -3
- data/lib/steep/diagnostic/signature.rb +4 -4
- data/lib/steep/drivers/check.rb +3 -3
- data/lib/steep/drivers/diagnostic_printer.rb +1 -1
- data/lib/steep/drivers/init.rb +6 -3
- data/lib/steep/expectations.rb +1 -1
- data/lib/steep/interface/builder.rb +2 -3
- data/lib/steep/interface/function.rb +13 -0
- data/lib/steep/interface/method_type.rb +5 -0
- data/lib/steep/interface/shape.rb +1 -1
- data/lib/steep/project/dsl.rb +2 -0
- data/lib/steep/server/change_buffer.rb +1 -1
- data/lib/steep/server/interaction_worker.rb +5 -5
- data/lib/steep/server/master.rb +2 -17
- data/lib/steep/server/type_check_controller.rb +2 -2
- data/lib/steep/server/type_check_worker.rb +1 -1
- data/lib/steep/services/completion_provider.rb +4 -4
- data/lib/steep/services/goto_service.rb +3 -3
- data/lib/steep/services/hover_provider/rbs.rb +1 -1
- data/lib/steep/services/hover_provider/ruby.rb +6 -6
- data/lib/steep/services/signature_help_provider.rb +8 -8
- data/lib/steep/services/type_check_service.rb +8 -8
- data/lib/steep/signature/validator.rb +3 -3
- data/lib/steep/source.rb +4 -4
- data/lib/steep/subtyping/check.rb +3 -3
- data/lib/steep/subtyping/constraints.rb +4 -4
- data/lib/steep/type_construction.rb +84 -45
- data/lib/steep/type_inference/block_params.rb +3 -3
- data/lib/steep/type_inference/context.rb +1 -1
- data/lib/steep/type_inference/method_params.rb +1 -1
- data/lib/steep/type_inference/type_env.rb +3 -3
- data/lib/steep/version.rb +1 -1
- data/manual/annotations.md +37 -0
- data/manual/ignore.md +20 -0
- data/manual/ruby-diagnostics.md +1812 -0
- data/steep.gemspec +1 -1
- metadata +8 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7f7a4597973dff6192b6977a32875ed18b7da16a70d34bf5e811cb8a719b18d5
|
4
|
+
data.tar.gz: 8b9ec7e28728c0f6e35e962fed6dd8a43828d41763ae2ffce831b787a501b200
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f11cb6ec05bc38e2e8130b7e6860409c63a9d1ba3ef93ca14dcc3781800c00d97e59506343e8191c97741865a1fa1895dfd9ff69928b574df423e32983a315b5
|
7
|
+
data.tar.gz: d6b544a988c8f0adae6705a5b7085907bb7148dde0eeb857a3aae7b9c44b2787f47ea40aa1c0b54b5d5da650f07e4f94e0a754ead23baca844cb2f21ae6c7eaa
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,81 @@
|
|
1
1
|
# CHANGELOG
|
2
2
|
|
3
|
+
## 1.9.0 (2024-12-06)
|
4
|
+
|
5
|
+
### Type checker core
|
6
|
+
|
7
|
+
* Report diagnostic on unknown record key ([#1385](https://github.com/soutaro/steep/pull/1385))
|
8
|
+
* Report annotation syntax error ([#1384](https://github.com/soutaro/steep/pull/1384))
|
9
|
+
* emit UnreachableBranch to the "void" condition ([#1356](https://github.com/soutaro/steep/pull/1356))
|
10
|
+
* Support &method(:name) call for block_pass ([#1276](https://github.com/soutaro/steep/pull/1276))
|
11
|
+
* Emit SingletonTypeMismatch when class/module mismatch ([#1274](https://github.com/soutaro/steep/pull/1274))
|
12
|
+
* refactor: Use Array#fetch instead of Array#[] to resolve type errors ([#1287](https://github.com/soutaro/steep/pull/1287))
|
13
|
+
* refactor: Use Hash#fetch instead of Hash#[] to resolve type errors ([#1286](https://github.com/soutaro/steep/pull/1286))
|
14
|
+
* Expand `array(splat(expr` node ([#1347](https://github.com/soutaro/steep/pull/1347))
|
15
|
+
* Add `UnannotatedEmptyCollection` diagnostic ([#1338](https://github.com/soutaro/steep/pull/1338))
|
16
|
+
* Update type checking strategy ([#1308](https://github.com/soutaro/steep/pull/1308))
|
17
|
+
* Fix untyped hash typing ([#1299](https://github.com/soutaro/steep/pull/1299))
|
18
|
+
* Support `implicitly-returns-nil` ([#1258](https://github.com/soutaro/steep/pull/1258))
|
19
|
+
* Fix record shape ([#1265](https://github.com/soutaro/steep/pull/1265))
|
20
|
+
* Remove unused rules ([#1238](https://github.com/soutaro/steep/pull/1238))
|
21
|
+
|
22
|
+
### Commandline tool
|
23
|
+
|
24
|
+
* Introduces a new `target.*` syntax for everything in the target ([#1387](https://github.com/soutaro/steep/pull/1387))
|
25
|
+
* Symbolize target/group names ([#1364](https://github.com/soutaro/steep/pull/1364))
|
26
|
+
* Update Steepfile template ([#1355](https://github.com/soutaro/steep/pull/1355))
|
27
|
+
* Delete `target` from `--validate` option ([#1346](https://github.com/soutaro/steep/pull/1346))
|
28
|
+
* Install rbs collection automatically ([#1345](https://github.com/soutaro/steep/pull/1345))
|
29
|
+
|
30
|
+
### Language server
|
31
|
+
|
32
|
+
* Add link to diagnostic manual ([#1388](https://github.com/soutaro/steep/pull/1388))
|
33
|
+
* Stop accumulating diagnostics ([#1367](https://github.com/soutaro/steep/pull/1367))
|
34
|
+
* Send server version to client ([#1341](https://github.com/soutaro/steep/pull/1341))
|
35
|
+
* Add custom methods to trigger type check manually ([#1340](https://github.com/soutaro/steep/pull/1340))
|
36
|
+
* Type check thread helpers ([#1335](https://github.com/soutaro/steep/pull/1335))
|
37
|
+
* Use `URI::RFC2396_Parser` ([#1329](https://github.com/soutaro/steep/pull/1329))
|
38
|
+
* Handle file deletion notification ([#1300](https://github.com/soutaro/steep/pull/1300))
|
39
|
+
* Refactor communication between master and type check worker ([#1285](https://github.com/soutaro/steep/pull/1285))
|
40
|
+
* Skip sending response to `$/steep/typecheck` request from `steep langserver` ([#1267](https://github.com/soutaro/steep/pull/1267))
|
41
|
+
|
42
|
+
### Miscellaneous
|
43
|
+
|
44
|
+
* Use rbs-3.7 ([#1383](https://github.com/soutaro/steep/pull/1383))
|
45
|
+
* Move diagnostic docs ([#1370](https://github.com/soutaro/steep/pull/1370))
|
46
|
+
* Add anchor ([#1359](https://github.com/soutaro/steep/pull/1359))
|
47
|
+
* Update example to not use `^` as a hash function ([#1360](https://github.com/soutaro/steep/pull/1360))
|
48
|
+
* doc: Add diagnostics for Ruby page ([#1249](https://github.com/soutaro/steep/pull/1249))
|
49
|
+
* Update filename example in initial Steepfile ([#1230](https://github.com/soutaro/steep/pull/1230))
|
50
|
+
* docs: Add document for steep:ignore comment ([#1353](https://github.com/soutaro/steep/pull/1353))
|
51
|
+
* docs: Add document for type assertion and type application ([#1235](https://github.com/soutaro/steep/pull/1235))
|
52
|
+
* Print test names in CI for investigation ([#1354](https://github.com/soutaro/steep/pull/1354))
|
53
|
+
* Fix typo ([#1352](https://github.com/soutaro/steep/pull/1352))
|
54
|
+
* Set up type checking tests ([#1339](https://github.com/soutaro/steep/pull/1339))
|
55
|
+
* Fix typo ([#1248](https://github.com/soutaro/steep/pull/1248))
|
56
|
+
|
57
|
+
## 1.8.3 (2024-10-29)
|
58
|
+
|
59
|
+
### Type checker core
|
60
|
+
|
61
|
+
* Fix untyped hash typing ([#1299](https://github.com/soutaro/steep/pull/1299), Backport in [#1301](https://github.com/soutaro/steep/pull/1301))
|
62
|
+
|
63
|
+
### Language server
|
64
|
+
|
65
|
+
* Handle file deletion notification ([#1300](https://github.com/soutaro/steep/pull/1300), Backport in [#1301](https://github.com/soutaro/steep/pull/1301))
|
66
|
+
|
67
|
+
## 1.8.2 (2024-10-24)
|
68
|
+
|
69
|
+
### Language server
|
70
|
+
|
71
|
+
* Ignore `didChangeWatchedFiles notification` for open files ([#1290](https://github.com/soutaro/steep/pull/1290))
|
72
|
+
|
73
|
+
## 1.8.1 (2024-10-08)
|
74
|
+
|
75
|
+
### Language server
|
76
|
+
|
77
|
+
* Skip sending response to `$/steep/typecheck` request from `steep langserver` ([#1268](https://github.com/soutaro/steep/pull/1268), backport [#1267](https://github.com/soutaro/steep/pull/1267))
|
78
|
+
|
3
79
|
## 1.8.0 (2024-09-30)
|
4
80
|
|
5
81
|
### Type checker core
|
data/README.md
CHANGED
@@ -120,7 +120,7 @@ class Email
|
|
120
120
|
end
|
121
121
|
|
122
122
|
def hash
|
123
|
-
self.class
|
123
|
+
[self.class, address].hash
|
124
124
|
end
|
125
125
|
end
|
126
126
|
|
@@ -144,7 +144,7 @@ class Phone
|
|
144
144
|
end
|
145
145
|
|
146
146
|
def hash
|
147
|
-
self.class
|
147
|
+
[self.class, country, number].hash
|
148
148
|
end
|
149
149
|
end
|
150
150
|
```
|
@@ -201,11 +201,16 @@ Generally, these are by our design.
|
|
201
201
|
|
202
202
|
`rbs prototype` offers options: `rbi` to generate prototype from Sorbet RBI and `runtime` to generate from runtime API.
|
203
203
|
|
204
|
-
##
|
204
|
+
## Docs
|
205
205
|
|
206
|
-
There are some
|
206
|
+
There are some documents in the `manul` and `guide` directories.
|
207
207
|
|
208
208
|
* [Guides](guides)
|
209
|
+
* [Manual](manual)
|
210
|
+
|
211
|
+
The `doc` directory contains a few internal design docs.
|
212
|
+
|
213
|
+
* [Internal docs](doc)
|
209
214
|
|
210
215
|
## Examples
|
211
216
|
|
data/Rakefile
CHANGED
data/Steepfile
CHANGED
@@ -0,0 +1,112 @@
|
|
1
|
+
# rbs_inline: enabled
|
2
|
+
|
3
|
+
require "rbs"
|
4
|
+
require "steep"
|
5
|
+
|
6
|
+
class RubyDiagnosticsVisitor < RBS::AST::Visitor
|
7
|
+
attr_reader :classes #: Hash[String, String]
|
8
|
+
attr_reader :templates #: Hash[Symbol, String]
|
9
|
+
|
10
|
+
def initialize #: void
|
11
|
+
@classes = {}
|
12
|
+
@templates = {}
|
13
|
+
end
|
14
|
+
|
15
|
+
# @rbs ...
|
16
|
+
def visit_declaration_class(node)
|
17
|
+
unless node.annotations.find { _1.string == "diagnostics--skip" }
|
18
|
+
if node.comment
|
19
|
+
name = node.name.to_s
|
20
|
+
classes[name] = node.comment.string
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
super
|
25
|
+
end
|
26
|
+
|
27
|
+
# @rbs ...
|
28
|
+
def visit_member_method_definition(node)
|
29
|
+
if node.annotations.find { _1.string == "diagnostics--template" }
|
30
|
+
if node.comment
|
31
|
+
templates[node.name] = node.comment.string
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
# @rbs (IO) -> void
|
37
|
+
def format_templates(io)
|
38
|
+
io.puts "## Configuration Templates"
|
39
|
+
|
40
|
+
io.puts <<~MD
|
41
|
+
Steep provides several templates to configure diagnostics for Ruby code.
|
42
|
+
You can use these templates or customize them to suit your needs via `#configure_code_diagnostics` method in `Steepfile`.
|
43
|
+
|
44
|
+
The following templates are available:
|
45
|
+
|
46
|
+
MD
|
47
|
+
|
48
|
+
io.puts "<dl>"
|
49
|
+
templates.keys.sort.each do |key|
|
50
|
+
body = templates.fetch(key)
|
51
|
+
|
52
|
+
io.puts "<dt><code>Ruby.#{key}</code></dt>"
|
53
|
+
io.puts "<dd>#{body}</dd>"
|
54
|
+
end
|
55
|
+
io.puts "</dl>"
|
56
|
+
io.puts
|
57
|
+
end
|
58
|
+
|
59
|
+
# @rbs (IO) -> void
|
60
|
+
def format_class(io)
|
61
|
+
classes.keys.sort.each do |key|
|
62
|
+
content = classes[key]
|
63
|
+
|
64
|
+
# io.puts "<h2 id='Ruby::#{key}'>Ruby::#{key}</h2>"
|
65
|
+
io.puts "<a name='Ruby::#{key}'></a>"
|
66
|
+
io.puts "## Ruby::#{key}"
|
67
|
+
io.puts
|
68
|
+
io.puts content
|
69
|
+
io.puts
|
70
|
+
|
71
|
+
configs = templates.keys
|
72
|
+
|
73
|
+
io.puts "### Severity"
|
74
|
+
io.puts
|
75
|
+
io.puts "| #{configs.map { "#{_1}" }.join(" | ")} |"
|
76
|
+
io.puts "| #{configs.map{"-"}.join(" | ")} |"
|
77
|
+
|
78
|
+
line = configs.map {|config|
|
79
|
+
hash = Steep::Diagnostic::Ruby.__send__(config) #: Hash[Class, untyped]
|
80
|
+
const =Steep::Diagnostic::Ruby.const_get(key.to_sym)
|
81
|
+
"#{hash[const] || "-"}"
|
82
|
+
}
|
83
|
+
io.puts "| #{line.join(" | ")} |"
|
84
|
+
io.puts
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
# @rbs (Pathname) { (instance) -> void } -> void
|
89
|
+
def self.visit_file(path, &block)
|
90
|
+
STDERR.puts "Reading #{path}..."
|
91
|
+
buffer = RBS::Buffer.new(name: path, content: path.read)
|
92
|
+
_, _dirs, decls = RBS::Parser.parse_signature(buffer)
|
93
|
+
|
94
|
+
visitor = new()
|
95
|
+
visitor.visit_all(decls)
|
96
|
+
|
97
|
+
yield visitor
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
diagnostic_dir = Pathname(__dir__ || raise) + "../sig/steep/diagnostic"
|
102
|
+
output_dir = Pathname(__dir__ || raise) + "../manual"
|
103
|
+
|
104
|
+
RubyDiagnosticsVisitor.visit_file(diagnostic_dir + "ruby.rbs") do |visitor|
|
105
|
+
STDERR.puts ">> Writing #{output_dir + "ruby-diagnostics.md"}..."
|
106
|
+
(output_dir + "ruby-diagnostics.md").open("w") do |io|
|
107
|
+
io.puts "# Ruby Code Diagnostics"
|
108
|
+
io.puts
|
109
|
+
visitor.format_templates(io)
|
110
|
+
visitor.format_class(io)
|
111
|
+
end
|
112
|
+
end
|
data/lib/steep/ast/builtin.rb
CHANGED
data/lib/steep/ast/ignore.rb
CHANGED
data/lib/steep/cli.rb
CHANGED
@@ -128,10 +128,17 @@ module Steep
|
|
128
128
|
end
|
129
129
|
|
130
130
|
opts.on("--group=GROUP", "Specify target/group name to type check") do |arg|
|
131
|
-
# @type var
|
131
|
+
# @type var arg: String
|
132
132
|
target, group = arg.split(".")
|
133
133
|
target or raise
|
134
|
-
|
134
|
+
case group
|
135
|
+
when "*"
|
136
|
+
command.active_group_names << [target.to_sym, true]
|
137
|
+
when nil
|
138
|
+
command.active_group_names << [target.to_sym, nil]
|
139
|
+
else
|
140
|
+
command.active_group_names << [target.to_sym, group.to_sym]
|
141
|
+
end
|
135
142
|
end
|
136
143
|
|
137
144
|
opts.on("--[no-]type-check", "Type check Ruby code") do |v|
|
@@ -43,11 +43,18 @@ module Steep
|
|
43
43
|
if severity
|
44
44
|
range = diagnostic.location&.as_lsp_range || raise("#{diagnostic.class} object (#{diagnostic.full_message}) instance must have `#location`")
|
45
45
|
|
46
|
+
if diagnostic.is_a?(Ruby::Base)
|
47
|
+
description = {
|
48
|
+
href: "https://github.com/soutaro/steep/tree/v#{VERSION}/manual/ruby-diagnostics.md##{URI.encode_uri_component(diagnostic.diagnostic_code)}"
|
49
|
+
} #: LSP::Interface::CodeDescription::json
|
50
|
+
end
|
51
|
+
|
46
52
|
{
|
47
53
|
message: diagnostic.full_message,
|
48
54
|
code: diagnostic.diagnostic_code,
|
49
55
|
severity: severity,
|
50
|
-
range: range
|
56
|
+
range: range,
|
57
|
+
codeDescription: description
|
51
58
|
}
|
52
59
|
end
|
53
60
|
end
|
@@ -409,6 +409,33 @@ module Steep
|
|
409
409
|
end
|
410
410
|
end
|
411
411
|
|
412
|
+
class ClassModuleMismatch < Base
|
413
|
+
attr_reader :name
|
414
|
+
|
415
|
+
def initialize(node:, name:)
|
416
|
+
case node.type
|
417
|
+
when :module, :class
|
418
|
+
location = node.loc.name # steep:ignore NoMethod
|
419
|
+
else
|
420
|
+
raise "Unexpected node: #{node.type}"
|
421
|
+
end
|
422
|
+
super(node: node, location: location) # steep:ignore NoMethod
|
423
|
+
|
424
|
+
@name = name
|
425
|
+
end
|
426
|
+
|
427
|
+
def header_line
|
428
|
+
case node&.type
|
429
|
+
when :module
|
430
|
+
"#{name} is declared as a class in RBS"
|
431
|
+
when :class
|
432
|
+
"#{name} is declared as a module in RBS"
|
433
|
+
else
|
434
|
+
raise
|
435
|
+
end
|
436
|
+
end
|
437
|
+
end
|
438
|
+
|
412
439
|
class MethodArityMismatch < Base
|
413
440
|
attr_reader :method_type
|
414
441
|
|
@@ -794,6 +821,19 @@ module Steep
|
|
794
821
|
end
|
795
822
|
end
|
796
823
|
|
824
|
+
class AnnotationSyntaxError < Base
|
825
|
+
attr_reader :message
|
826
|
+
|
827
|
+
def initialize(message: ,location:)
|
828
|
+
super(node: nil, location: location)
|
829
|
+
@message = message
|
830
|
+
end
|
831
|
+
|
832
|
+
def header_line
|
833
|
+
"Type annotation has a syntax error: #{message}"
|
834
|
+
end
|
835
|
+
end
|
836
|
+
|
797
837
|
class FalseAssertion < Base
|
798
838
|
attr_reader :node, :assertion_type, :node_type
|
799
839
|
|
@@ -924,6 +964,19 @@ module Steep
|
|
924
964
|
end
|
925
965
|
end
|
926
966
|
|
967
|
+
class UnknownRecordKey < Base
|
968
|
+
attr_reader :key
|
969
|
+
|
970
|
+
def initialize(key:, node:)
|
971
|
+
super(node: node)
|
972
|
+
@key = key
|
973
|
+
end
|
974
|
+
|
975
|
+
def header_line
|
976
|
+
"Unknown key `#{key.inspect}` is given to a record type"
|
977
|
+
end
|
978
|
+
end
|
979
|
+
|
927
980
|
ALL = ObjectSpace.each_object(Class).with_object([]) do |klass, array|
|
928
981
|
if klass < Base
|
929
982
|
array << klass
|
@@ -939,6 +992,7 @@ module Steep
|
|
939
992
|
def self.default
|
940
993
|
@default ||= _ = all_error.merge(
|
941
994
|
{
|
995
|
+
AnnotationSyntaxError => :error,
|
942
996
|
ArgumentTypeMismatch => :error,
|
943
997
|
BlockBodyTypeMismatch => :warning,
|
944
998
|
BlockTypeMismatch => :warning,
|
@@ -968,7 +1022,8 @@ module Steep
|
|
968
1022
|
ReturnTypeMismatch => :error,
|
969
1023
|
SetterBodyTypeMismatch => :information,
|
970
1024
|
SetterReturnTypeMismatch => :information,
|
971
|
-
|
1025
|
+
ClassModuleMismatch => :error,
|
1026
|
+
SyntaxError => :information,
|
972
1027
|
TypeArgumentMismatchError => :hint,
|
973
1028
|
UnannotatedEmptyCollection => :warning,
|
974
1029
|
UnexpectedBlockGiven => :warning,
|
@@ -983,6 +1038,7 @@ module Steep
|
|
983
1038
|
UnexpectedYield => :warning,
|
984
1039
|
UnknownConstant => :warning,
|
985
1040
|
UnknownGlobalVariable => :warning,
|
1041
|
+
UnknownRecordKey => :information,
|
986
1042
|
UnknownInstanceVariable => :information,
|
987
1043
|
UnreachableBranch => :hint,
|
988
1044
|
UnreachableValueBranch => :hint,
|
@@ -996,6 +1052,7 @@ module Steep
|
|
996
1052
|
def self.strict
|
997
1053
|
@strict ||= _ = all_error.merge(
|
998
1054
|
{
|
1055
|
+
AnnotationSyntaxError => :error,
|
999
1056
|
ArgumentTypeMismatch => :error,
|
1000
1057
|
BlockBodyTypeMismatch => :error,
|
1001
1058
|
BlockTypeMismatch => :error,
|
@@ -1025,7 +1082,8 @@ module Steep
|
|
1025
1082
|
ReturnTypeMismatch => :error,
|
1026
1083
|
SetterBodyTypeMismatch => :error,
|
1027
1084
|
SetterReturnTypeMismatch => :error,
|
1028
|
-
|
1085
|
+
ClassModuleMismatch => :error,
|
1086
|
+
SyntaxError => :information,
|
1029
1087
|
TypeArgumentMismatchError => :error,
|
1030
1088
|
UnannotatedEmptyCollection => :error,
|
1031
1089
|
UnexpectedBlockGiven => :error,
|
@@ -1040,6 +1098,7 @@ module Steep
|
|
1040
1098
|
UnexpectedYield => :error,
|
1041
1099
|
UnknownConstant => :error,
|
1042
1100
|
UnknownGlobalVariable => :error,
|
1101
|
+
UnknownRecordKey => :warning,
|
1043
1102
|
UnknownInstanceVariable => :error,
|
1044
1103
|
UnreachableBranch => :information,
|
1045
1104
|
UnreachableValueBranch => :warning,
|
@@ -1053,6 +1112,7 @@ module Steep
|
|
1053
1112
|
def self.lenient
|
1054
1113
|
@lenient ||= _ = all_error.merge(
|
1055
1114
|
{
|
1115
|
+
AnnotationSyntaxError => :error,
|
1056
1116
|
ArgumentTypeMismatch => :information,
|
1057
1117
|
BlockBodyTypeMismatch => :information,
|
1058
1118
|
BlockTypeMismatch => :information,
|
@@ -1082,7 +1142,8 @@ module Steep
|
|
1082
1142
|
ReturnTypeMismatch => :warning,
|
1083
1143
|
SetterBodyTypeMismatch => nil,
|
1084
1144
|
SetterReturnTypeMismatch => nil,
|
1085
|
-
|
1145
|
+
ClassModuleMismatch => nil,
|
1146
|
+
SyntaxError => :information,
|
1086
1147
|
TypeArgumentMismatchError => nil,
|
1087
1148
|
UnannotatedEmptyCollection => :hint,
|
1088
1149
|
UnexpectedBlockGiven => :hint,
|
@@ -1097,6 +1158,7 @@ module Steep
|
|
1097
1158
|
UnexpectedYield => :information,
|
1098
1159
|
UnknownConstant => :hint,
|
1099
1160
|
UnknownGlobalVariable => :hint,
|
1161
|
+
UnknownRecordKey => :hint,
|
1100
1162
|
UnknownInstanceVariable => :hint,
|
1101
1163
|
UnreachableBranch => :hint,
|
1102
1164
|
UnreachableValueBranch => :hint,
|
@@ -456,7 +456,7 @@ module Steep
|
|
456
456
|
end
|
457
457
|
|
458
458
|
def header_line
|
459
|
-
"The default type of `#{param_name}` doesn't satisfy upper bound
|
459
|
+
"The default type of `#{param_name}` doesn't satisfy upper bound constraint: #{relation}"
|
460
460
|
end
|
461
461
|
end
|
462
462
|
|
@@ -468,7 +468,7 @@ module Steep
|
|
468
468
|
when RBS::DuplicatedDeclarationError
|
469
469
|
Diagnostic::Signature::DuplicatedDeclaration.new(
|
470
470
|
type_name: error.name,
|
471
|
-
location: error.decls
|
471
|
+
location: error.decls.fetch(0).location
|
472
472
|
)
|
473
473
|
when RBS::GenericParameterMismatchError
|
474
474
|
Diagnostic::Signature::GenericParameterMismatch.new(
|
@@ -494,7 +494,7 @@ module Steep
|
|
494
494
|
Diagnostic::Signature::InvalidMethodOverload.new(
|
495
495
|
class_name: error.type_name,
|
496
496
|
method_name: error.method_name,
|
497
|
-
location: error.members
|
497
|
+
location: error.members.fetch(0).location
|
498
498
|
)
|
499
499
|
when RBS::DuplicatedMethodDefinitionError
|
500
500
|
Diagnostic::Signature::DuplicatedMethodDefinition.new(
|
@@ -518,7 +518,7 @@ module Steep
|
|
518
518
|
Diagnostic::Signature::RecursiveAlias.new(
|
519
519
|
class_name: error.type.name,
|
520
520
|
names: error.defs.map(&:name),
|
521
|
-
location: error.defs
|
521
|
+
location: error.defs.fetch(0).original&.location
|
522
522
|
)
|
523
523
|
when RBS::RecursiveAncestorError
|
524
524
|
Diagnostic::Signature::RecursiveAncestor.new(
|
data/lib/steep/drivers/check.rb
CHANGED
@@ -38,12 +38,12 @@ module Steep
|
|
38
38
|
case group
|
39
39
|
when Project::Target
|
40
40
|
active_group_names.any? {|target_name, group_name|
|
41
|
-
target_name == group.name && group_name == nil
|
41
|
+
target_name == group.name && (group_name == nil || group_name == true)
|
42
42
|
}
|
43
43
|
when Project::Group
|
44
44
|
active_group_names.any? {|target_name, group_name|
|
45
45
|
target_name == group.target.name &&
|
46
|
-
(group_name == group.name || group_name
|
46
|
+
(group_name == group.name || group_name == true)
|
47
47
|
}
|
48
48
|
end
|
49
49
|
end
|
@@ -206,7 +206,7 @@ module Steep
|
|
206
206
|
|
207
207
|
def load_files(files, target, group, params:)
|
208
208
|
if type_check_code
|
209
|
-
files.each_group_source_path(group) do |path|
|
209
|
+
files.each_group_source_path(group, true) do |path|
|
210
210
|
params[:code_paths] << [target.name.to_s, target.project.absolute_path(path).to_s]
|
211
211
|
end
|
212
212
|
end
|
@@ -82,7 +82,7 @@ module Steep
|
|
82
82
|
start_pos = diagnostic[:range][:start]
|
83
83
|
end_pos = diagnostic[:range][:end]
|
84
84
|
|
85
|
-
line = buffer.lines
|
85
|
+
line = buffer.lines.fetch(start_pos[:line])
|
86
86
|
|
87
87
|
leading = line[0...start_pos[:character]] || ""
|
88
88
|
if start_pos[:line] == end_pos[:line]
|
data/lib/steep/drivers/init.rb
CHANGED
@@ -12,9 +12,10 @@ module Steep
|
|
12
12
|
#
|
13
13
|
# target :lib do
|
14
14
|
# signature "sig"
|
15
|
+
# ignore_signature "sig/test"
|
15
16
|
#
|
16
17
|
# check "lib" # Directory name
|
17
|
-
# check "
|
18
|
+
# check "path/to/source.rb" # File name
|
18
19
|
# check "app/models/**/*.rb" # Glob
|
19
20
|
# # ignore "lib/templates/*.rb"
|
20
21
|
#
|
@@ -31,9 +32,11 @@ module Steep
|
|
31
32
|
# end
|
32
33
|
|
33
34
|
# target :test do
|
34
|
-
#
|
35
|
+
# unreferenced! # Skip type checking the `lib` code when types in `test` target is changed
|
36
|
+
# signature "sig/test" # Put RBS files for tests under `sig/test`
|
37
|
+
# check "test" # Type check Ruby scripts under `test`
|
35
38
|
#
|
36
|
-
#
|
39
|
+
# configure_code_diagnostics(D::Ruby.lenient) # Weak type checking for test code
|
37
40
|
#
|
38
41
|
# # library "pathname" # Standard libraries
|
39
42
|
# end
|
data/lib/steep/expectations.rb
CHANGED
@@ -203,7 +203,7 @@ module Steep
|
|
203
203
|
array = [] #: Array[{ "file" => String, "diagnostics" => Array[untyped] }]
|
204
204
|
|
205
205
|
diagnostics.each_key.sort.each do |key|
|
206
|
-
ds = diagnostics
|
206
|
+
ds = diagnostics.fetch(key)
|
207
207
|
array << {
|
208
208
|
"file" => key.to_s,
|
209
209
|
'diagnostics' => ds.sort_by(&:sort_key).map(&:to_hash)
|
@@ -66,7 +66,7 @@ module Steep
|
|
66
66
|
def shape(type, config)
|
67
67
|
Steep.logger.tagged "shape(#{type})" do
|
68
68
|
if shape = raw_shape(type, config)
|
69
|
-
# Optimization that skips
|
69
|
+
# Optimization that skips unnecessary substitution
|
70
70
|
if type.free_variables.include?(AST::Types::Self.instance)
|
71
71
|
shape
|
72
72
|
else
|
@@ -172,7 +172,7 @@ module Steep
|
|
172
172
|
if bound = config.upper_bound(type.name)
|
173
173
|
new_config = Config.new(self_type: bound, variable_bounds: config.variable_bounds)
|
174
174
|
sub = Substitution.build([], self_type: type)
|
175
|
-
# We have to use `self_shape`
|
175
|
+
# We have to use `self_shape` instead of `raw_shape` here.
|
176
176
|
# Keep the `self` types included in the `bound`'s shape, and replace it to the type variable.
|
177
177
|
self_shape(bound, new_config)&.subst(sub, type: type)
|
178
178
|
end
|
@@ -838,4 +838,3 @@ module Steep
|
|
838
838
|
end
|
839
839
|
end
|
840
840
|
end
|
841
|
-
|
@@ -1057,6 +1057,19 @@ module Steep
|
|
1057
1057
|
)
|
1058
1058
|
end
|
1059
1059
|
|
1060
|
+
def accept_one_arg?
|
1061
|
+
return false unless params
|
1062
|
+
return false unless params.keyword_params.requireds.empty?
|
1063
|
+
head = params.positional_params or return false
|
1064
|
+
|
1065
|
+
case head.head
|
1066
|
+
when Params::PositionalParams::Required
|
1067
|
+
!head.tail.is_a?(Params::PositionalParams::Required)
|
1068
|
+
else
|
1069
|
+
true
|
1070
|
+
end
|
1071
|
+
end
|
1072
|
+
|
1060
1073
|
def to_s
|
1061
1074
|
if params
|
1062
1075
|
"#{params} -> #{return_type}"
|