steep 0.48.0 → 0.50.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 +25 -0
- data/Gemfile +3 -1
- data/Gemfile.lock +3 -3
- data/lib/steep/ast/types/any.rb +2 -0
- data/lib/steep/ast/types/boolean.rb +2 -0
- data/lib/steep/ast/types/bot.rb +2 -0
- data/lib/steep/ast/types/class.rb +2 -0
- data/lib/steep/ast/types/factory.rb +1 -1
- data/lib/steep/ast/types/helper.rb +8 -0
- data/lib/steep/ast/types/instance.rb +2 -0
- data/lib/steep/ast/types/intersection.rb +4 -0
- data/lib/steep/ast/types/literal.rb +2 -0
- data/lib/steep/ast/types/logic.rb +2 -0
- data/lib/steep/ast/types/name.rb +6 -0
- data/lib/steep/ast/types/nil.rb +2 -0
- data/lib/steep/ast/types/proc.rb +9 -0
- data/lib/steep/ast/types/record.rb +4 -0
- data/lib/steep/ast/types/self.rb +2 -0
- data/lib/steep/ast/types/top.rb +2 -0
- data/lib/steep/ast/types/tuple.rb +4 -0
- data/lib/steep/ast/types/union.rb +4 -0
- data/lib/steep/ast/types/var.rb +2 -0
- data/lib/steep/ast/types/void.rb +2 -0
- data/lib/steep/cli.rb +5 -0
- data/lib/steep/diagnostic/ruby.rb +13 -0
- data/lib/steep/drivers/check.rb +3 -2
- data/lib/steep/drivers/langserver.rb +2 -2
- data/lib/steep/drivers/stats.rb +1 -0
- data/lib/steep/drivers/utils/jobs_count.rb +1 -1
- data/lib/steep/drivers/watch.rb +1 -1
- data/lib/steep/interface/function.rb +9 -0
- data/lib/steep/project.rb +15 -1
- data/lib/steep/server/interaction_worker.rb +2 -2
- data/lib/steep/server/master.rb +9 -4
- data/lib/steep/server/type_check_worker.rb +19 -4
- data/lib/steep/server/worker_process.rb +15 -6
- data/lib/steep/services/goto_service.rb +19 -4
- data/lib/steep/services/type_check_service.rb +2 -0
- data/lib/steep/signature/validator.rb +12 -5
- data/lib/steep/subtyping/check.rb +23 -2
- data/lib/steep/type_construction.rb +116 -39
- data/lib/steep/type_inference/block_params.rb +31 -3
- data/lib/steep/version.rb +1 -1
- data/smoke/diagnostics/proc_type_expected.rb +3 -0
- data/smoke/diagnostics/test_expectations.yml +12 -0
- data/smoke/tsort/a.rb +1 -1
- data/smoke/tsort/test_expectations.yml +1 -63
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6ff552f6d8f112693dc9969f20d851ddbc6d7d2f16cebd45f802a5d703618b58
|
4
|
+
data.tar.gz: 723464fe34c81c3e83b66338dfc6fd3e7c3da2aaf30c1fc48116c7de794ca961
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: bf9f83791cfb636c65a26f404fb164fa7fc3906376e36a79a1ca4ae7eeab8020e23c5b9ce5e649a38ed79080d0aa2c00fe53a5cce8a1c76c259237f38880bbf2
|
7
|
+
data.tar.gz: 25bd9e11db283acdfc957682860e674d544b82be1b5a68bc87ca96888907966b721301c937cdaa3e06bf0226ec82fa8c78eacfaf4987637a601f75ca8d8e950c
|
data/CHANGELOG.md
CHANGED
@@ -2,6 +2,31 @@
|
|
2
2
|
|
3
3
|
## master
|
4
4
|
|
5
|
+
# 0.50.0 (2022-03-22)
|
6
|
+
|
7
|
+
* CLI option for override steep command at spawn worker ([\#511](https://github.com/soutaro/steep/pull/511))
|
8
|
+
* LSP related improvements for Sublime LSP ([\#513](https://github.com/soutaro/steep/pull/513))
|
9
|
+
* Support Windows environment ([\#514](https://github.com/soutaro/steep/pull/514))
|
10
|
+
* Let `&:foo` proc work with methods with optional parameters ([\#516](https://github.com/soutaro/steep/pull/516))
|
11
|
+
* Fix unexpected error when or-asgn/and-asgn ([\#517](https://github.com/soutaro/steep/pull/517))
|
12
|
+
* Fix goto-definition from method call inside block ([\#518](https://github.com/soutaro/steep/pull/518))
|
13
|
+
* Better splat in array typing ([\#519](https://github.com/soutaro/steep/pull/519))
|
14
|
+
|
15
|
+
## 0.49.1 (2022-03-11)
|
16
|
+
|
17
|
+
* Fix lambda typing ([\#506](https://github.com/soutaro/steep/pull/506))
|
18
|
+
* Validate type descendants ([\#507](https://github.com/soutaro/steep/pull/507))
|
19
|
+
* Fix print error with absolute path ([\#508](https://github.com/soutaro/steep/pull/508))
|
20
|
+
* Skip non-target ruby code on `steep stats` ([\#509](https://github.com/soutaro/steep/pull/509))
|
21
|
+
|
22
|
+
## 0.49.0 (2022-03-08)
|
23
|
+
|
24
|
+
* Better typing for `#flat_map` ([\#504](https://github.com/soutaro/steep/pull/504))
|
25
|
+
* Support lambdas (`->`) with block ([\#503](https://github.com/soutaro/steep/pull/503))
|
26
|
+
* Let proc type be `::Proc` class instance ([\#502](https://github.com/soutaro/steep/pull/502))
|
27
|
+
* Disable contextual typing on `bool` type ([\#501](https://github.com/soutaro/steep/pull/501))
|
28
|
+
* Type check `return` without value ([\#500](https://github.com/soutaro/steep/pull/500))
|
29
|
+
|
5
30
|
## 0.48.0 (2022-03-07)
|
6
31
|
|
7
32
|
Steep supports all of the new features of RBS 2. 🎉
|
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
steep (0.
|
4
|
+
steep (0.50.0)
|
5
5
|
activesupport (>= 5.1)
|
6
6
|
language_server-protocol (>= 3.15, < 4.0)
|
7
7
|
listen (~> 3.0)
|
@@ -24,7 +24,7 @@ PATH
|
|
24
24
|
GEM
|
25
25
|
remote: https://rubygems.org/
|
26
26
|
specs:
|
27
|
-
activesupport (7.0.2.
|
27
|
+
activesupport (7.0.2.3)
|
28
28
|
concurrent-ruby (~> 1.0, >= 1.0.2)
|
29
29
|
i18n (>= 1.6, < 2)
|
30
30
|
minitest (>= 5.1)
|
@@ -41,7 +41,7 @@ GEM
|
|
41
41
|
minitest (5.15.0)
|
42
42
|
minitest-hooks (1.5.0)
|
43
43
|
minitest (> 5.3)
|
44
|
-
parallel (1.
|
44
|
+
parallel (1.22.0)
|
45
45
|
parser (3.1.1.0)
|
46
46
|
ast (~> 2.4.1)
|
47
47
|
rainbow (3.1.1)
|
data/lib/steep/ast/types/any.rb
CHANGED
data/lib/steep/ast/types/bot.rb
CHANGED
data/lib/steep/ast/types/name.rb
CHANGED
@@ -72,6 +72,10 @@ module Steep
|
|
72
72
|
end
|
73
73
|
end
|
74
74
|
|
75
|
+
def each_child(&block)
|
76
|
+
args.each(&block)
|
77
|
+
end
|
78
|
+
|
75
79
|
include Helper::ChildrenLevel
|
76
80
|
|
77
81
|
def level
|
@@ -98,6 +102,8 @@ module Steep
|
|
98
102
|
def with_location(new_location)
|
99
103
|
self.class.new(name: name, location: new_location)
|
100
104
|
end
|
105
|
+
|
106
|
+
include Helper::NoChild
|
101
107
|
end
|
102
108
|
|
103
109
|
class Instance < Applying
|
data/lib/steep/ast/types/nil.rb
CHANGED
data/lib/steep/ast/types/proc.rb
CHANGED
@@ -90,6 +90,15 @@ module Steep
|
|
90
90
|
def block_required?
|
91
91
|
block && !block.optional?
|
92
92
|
end
|
93
|
+
|
94
|
+
def each_child(&block)
|
95
|
+
if block_given?
|
96
|
+
type.each_child(&block)
|
97
|
+
self.block&.type&.each_child(&block)
|
98
|
+
else
|
99
|
+
enum_for :each_child
|
100
|
+
end
|
101
|
+
end
|
93
102
|
end
|
94
103
|
end
|
95
104
|
end
|
data/lib/steep/ast/types/self.rb
CHANGED
data/lib/steep/ast/types/top.rb
CHANGED
data/lib/steep/ast/types/var.rb
CHANGED
data/lib/steep/ast/types/void.rb
CHANGED
data/lib/steep/cli.rb
CHANGED
@@ -72,6 +72,11 @@ module Steep
|
|
72
72
|
opts.on("-j N", "--jobs=N", "Specify the number of type check workers (defaults: #{default})") do |count|
|
73
73
|
command.jobs_count = Integer(count) if Integer(count) > 0
|
74
74
|
end
|
75
|
+
|
76
|
+
command.steep_command = "steep"
|
77
|
+
opts.on("--steep-command=COMMAND", "Specify command to exec Steep CLI for worker (defaults: steep)") do |cmd|
|
78
|
+
command.steep_command = cmd
|
79
|
+
end
|
75
80
|
end
|
76
81
|
|
77
82
|
def process_init
|
@@ -669,6 +669,19 @@ module Steep
|
|
669
669
|
end
|
670
670
|
end
|
671
671
|
|
672
|
+
class ProcTypeExpected < Base
|
673
|
+
attr_reader :type
|
674
|
+
|
675
|
+
def initialize(node:, type:)
|
676
|
+
super(node: node)
|
677
|
+
@type = type
|
678
|
+
end
|
679
|
+
|
680
|
+
def header_line
|
681
|
+
"Proc type is expected but `#{type.to_s}` is specified"
|
682
|
+
end
|
683
|
+
end
|
684
|
+
|
672
685
|
class UnsupportedSyntax < Base
|
673
686
|
attr_reader :message
|
674
687
|
|
data/lib/steep/drivers/check.rb
CHANGED
@@ -39,6 +39,7 @@ module Steep
|
|
39
39
|
steepfile: project.steepfile_path,
|
40
40
|
args: command_line_patterns,
|
41
41
|
delay_shutdown: true,
|
42
|
+
steep_command: steep_command,
|
42
43
|
count: jobs_count
|
43
44
|
)
|
44
45
|
|
@@ -214,8 +215,8 @@ module Steep
|
|
214
215
|
total = errors.sum {|notification| notification[:diagnostics].size }
|
215
216
|
|
216
217
|
errors.each do |notification|
|
217
|
-
path =
|
218
|
-
buffer = RBS::Buffer.new(name: path, content: path.read)
|
218
|
+
path = Pathname(URI.parse(notification[:uri]).path)
|
219
|
+
buffer = RBS::Buffer.new(name: project.relative_path(path), content: path.read)
|
219
220
|
printer = DiagnosticPrinter.new(buffer: buffer, stdout: stdout)
|
220
221
|
|
221
222
|
notification[:diagnostics].each do |diag|
|
@@ -37,8 +37,8 @@ module Steep
|
|
37
37
|
def run
|
38
38
|
@project = load_config()
|
39
39
|
|
40
|
-
interaction_worker = Server::WorkerProcess.spawn_worker(:interaction, name: "interaction", steepfile: project.steepfile_path)
|
41
|
-
typecheck_workers = Server::WorkerProcess.spawn_typecheck_workers(steepfile: project.steepfile_path, args: [], count: jobs_count)
|
40
|
+
interaction_worker = Server::WorkerProcess.spawn_worker(:interaction, name: "interaction", steepfile: project.steepfile_path, steep_command: steep_command)
|
41
|
+
typecheck_workers = Server::WorkerProcess.spawn_typecheck_workers(steepfile: project.steepfile_path, args: [], steep_command: steep_command, count: jobs_count)
|
42
42
|
|
43
43
|
master = Server::Master.new(
|
44
44
|
project: project,
|
data/lib/steep/drivers/stats.rb
CHANGED
data/lib/steep/drivers/watch.rb
CHANGED
@@ -41,7 +41,7 @@ module Steep
|
|
41
41
|
server_reader = LanguageServer::Protocol::Transport::Io::Reader.new(server_read)
|
42
42
|
server_writer = LanguageServer::Protocol::Transport::Io::Writer.new(server_write)
|
43
43
|
|
44
|
-
typecheck_workers = Server::WorkerProcess.spawn_typecheck_workers(steepfile: project.steepfile_path, args: dirs.map(&:to_s), count: jobs_count)
|
44
|
+
typecheck_workers = Server::WorkerProcess.spawn_typecheck_workers(steepfile: project.steepfile_path, args: dirs.map(&:to_s), steep_command: steep_command, count: jobs_count)
|
45
45
|
|
46
46
|
master = Server::Master.new(
|
47
47
|
project: project,
|
@@ -879,6 +879,11 @@ module Steep
|
|
879
879
|
!has_positional? && !has_keywords?
|
880
880
|
end
|
881
881
|
|
882
|
+
# Returns true if all arguments are non-required.
|
883
|
+
def optional?
|
884
|
+
required.empty? && required_keywords.empty?
|
885
|
+
end
|
886
|
+
|
882
887
|
# self + params returns a new params for overloading.
|
883
888
|
#
|
884
889
|
def +(other)
|
@@ -952,6 +957,10 @@ module Steep
|
|
952
957
|
)
|
953
958
|
end
|
954
959
|
|
960
|
+
def each_child(&block)
|
961
|
+
each_type(&block)
|
962
|
+
end
|
963
|
+
|
955
964
|
def each_type(&block)
|
956
965
|
if block_given?
|
957
966
|
params.each_type(&block)
|
data/lib/steep/project.rb
CHANGED
@@ -16,7 +16,21 @@ module Steep
|
|
16
16
|
steepfile_path.parent
|
17
17
|
end
|
18
18
|
|
19
|
-
def relative_path(
|
19
|
+
def relative_path(orig_path)
|
20
|
+
path = if Gem.win_platform?
|
21
|
+
path_str = URI.decode_www_form_component(
|
22
|
+
orig_path.to_s.delete_prefix("/")
|
23
|
+
)
|
24
|
+
unless path_str.start_with?(%r{[a-z]:/}i)
|
25
|
+
# FIXME: Sometimes drive letter is missing, taking from base_dir
|
26
|
+
path_str = base_dir.to_s.split("/")[0] + "/" + path_str
|
27
|
+
end
|
28
|
+
Pathname.new(
|
29
|
+
path_str
|
30
|
+
)
|
31
|
+
else
|
32
|
+
orig_path
|
33
|
+
end
|
20
34
|
path.relative_path_from(base_dir)
|
21
35
|
end
|
22
36
|
|
@@ -89,7 +89,7 @@ module Steep
|
|
89
89
|
end
|
90
90
|
|
91
91
|
LSP::Interface::Hover.new(
|
92
|
-
contents: { kind: "markdown", value: format_hover(content) },
|
92
|
+
contents: { kind: "markdown", value: format_hover(content)&.gsub(/<!--(?~-->)-->/, "") },
|
93
93
|
range: range
|
94
94
|
)
|
95
95
|
end
|
@@ -271,7 +271,7 @@ HOVER
|
|
271
271
|
),
|
272
272
|
end: LanguageServer::Protocol::Interface::Position.new(
|
273
273
|
line: job.line - 1,
|
274
|
-
character: job.column
|
274
|
+
character: job.column
|
275
275
|
)
|
276
276
|
)
|
277
277
|
|
data/lib/steep/server/master.rb
CHANGED
@@ -49,9 +49,14 @@ module Steep
|
|
49
49
|
end
|
50
50
|
|
51
51
|
def checking_path?(path)
|
52
|
-
library_paths.
|
53
|
-
|
54
|
-
|
52
|
+
[library_paths, signature_paths, code_paths].any? do |paths|
|
53
|
+
if Gem.win_platform?
|
54
|
+
# FIXME: Sometimes drive letter is missing, so comparing without drive letter.
|
55
|
+
paths.any? {|p| p.to_s.split("/", 2)[1] == path.to_s.split("/", 2)[1]}
|
56
|
+
else
|
57
|
+
paths.include?(path)
|
58
|
+
end
|
59
|
+
end
|
55
60
|
end
|
56
61
|
|
57
62
|
def checked(path)
|
@@ -739,7 +744,7 @@ module Steep
|
|
739
744
|
{ kind: "end" }
|
740
745
|
else
|
741
746
|
progress_string = ("▮"*(percentage/5)) + ("▯"*(20 - percentage/5))
|
742
|
-
{ kind: "report", percentage: percentage, message: "#{progress_string}
|
747
|
+
{ kind: "report", percentage: percentage, message: "#{progress_string}" }
|
743
748
|
end
|
744
749
|
|
745
750
|
job_queue << SendMessageJob.to_client(
|
@@ -135,6 +135,21 @@ module Steep
|
|
135
135
|
end
|
136
136
|
|
137
137
|
def handle_job(job)
|
138
|
+
job_path = if job.respond_to?(:path)
|
139
|
+
if Gem.win_platform?
|
140
|
+
# FIXME: Sometimes drive letter is missing, using base_dir
|
141
|
+
if job.path.to_s.start_with?(%r{/[a-z](:|%3A)/}i)
|
142
|
+
job.path.to_s
|
143
|
+
else
|
144
|
+
"/#{project.base_dir.to_s.split("/").first}/#{job.path}"
|
145
|
+
end
|
146
|
+
else
|
147
|
+
job.path.to_s
|
148
|
+
end
|
149
|
+
else
|
150
|
+
nil
|
151
|
+
end
|
152
|
+
|
138
153
|
case job
|
139
154
|
when StartTypeCheckJob
|
140
155
|
Steep.logger.info { "Processing StartTypeCheckJob for guid=#{job.guid}" }
|
@@ -149,7 +164,7 @@ module Steep
|
|
149
164
|
writer.write(
|
150
165
|
method: :"textDocument/publishDiagnostics",
|
151
166
|
params: LSP::Interface::PublishDiagnosticsParams.new(
|
152
|
-
uri: URI.parse(
|
167
|
+
uri: URI.parse(job_path).tap {|uri| uri.scheme = "file"},
|
153
168
|
diagnostics: diagnostics.map {|diagnostic| formatter.format(diagnostic) }.uniq
|
154
169
|
)
|
155
170
|
)
|
@@ -167,7 +182,7 @@ module Steep
|
|
167
182
|
writer.write(
|
168
183
|
method: :"textDocument/publishDiagnostics",
|
169
184
|
params: LSP::Interface::PublishDiagnosticsParams.new(
|
170
|
-
uri: URI.parse(
|
185
|
+
uri: URI.parse(job_path).tap {|uri| uri.scheme = "file"},
|
171
186
|
diagnostics: diagnostics.map {|diagnostic| formatter.format(diagnostic) }.uniq.compact
|
172
187
|
)
|
173
188
|
)
|
@@ -186,7 +201,7 @@ module Steep
|
|
186
201
|
writer.write(
|
187
202
|
method: :"textDocument/publishDiagnostics",
|
188
203
|
params: LSP::Interface::PublishDiagnosticsParams.new(
|
189
|
-
uri: URI.parse(
|
204
|
+
uri: URI.parse(job_path).tap {|uri| uri.scheme = "file"},
|
190
205
|
diagnostics: diagnostics.map {|diagnostic| formatter.format(diagnostic) }.uniq.compact
|
191
206
|
)
|
192
207
|
)
|
@@ -268,7 +283,7 @@ module Steep
|
|
268
283
|
line = job.params[:position][:line] + 1
|
269
284
|
column = job.params[:position][:character]
|
270
285
|
|
271
|
-
goto_service = Services::GotoService.new(type_check: service)
|
286
|
+
goto_service = Services::GotoService.new(type_check: service, assignment: assignment)
|
272
287
|
locations =
|
273
288
|
case
|
274
289
|
when job.definition?
|
@@ -18,13 +18,17 @@ module Steep
|
|
18
18
|
@index = index
|
19
19
|
end
|
20
20
|
|
21
|
-
def self.spawn_worker(type, name:, steepfile:, options: [], delay_shutdown: false, index: nil)
|
22
|
-
|
21
|
+
def self.spawn_worker(type, name:, steepfile:, steep_command: "steep", options: [], delay_shutdown: false, index: nil)
|
22
|
+
args = ["--name=#{name}", "--steepfile=#{steepfile}"]
|
23
|
+
args << (%w(debug info warn error fatal unknown)[Steep.logger.level].yield_self {|log_level| "--log-level=#{log_level}" })
|
24
|
+
if Steep.log_output.is_a?(String)
|
25
|
+
args << "--log-output=#{Steep.log_output}"
|
26
|
+
end
|
23
27
|
command = case type
|
24
28
|
when :interaction
|
25
|
-
[
|
29
|
+
[steep_command, "worker", "--interaction", *args, *options]
|
26
30
|
when :typecheck
|
27
|
-
[
|
31
|
+
[steep_command, "worker", "--typecheck", *args, *options]
|
28
32
|
else
|
29
33
|
raise "Unknown type: #{type}"
|
30
34
|
end
|
@@ -33,7 +37,11 @@ module Steep
|
|
33
37
|
command << "--delay-shutdown"
|
34
38
|
end
|
35
39
|
|
36
|
-
stdin, stdout, thread =
|
40
|
+
stdin, stdout, thread = if Gem.win_platform?
|
41
|
+
Open3.popen2(*command, new_pgroup: true)
|
42
|
+
else
|
43
|
+
Open3.popen2(*command, pgroup: true)
|
44
|
+
end
|
37
45
|
stderr = nil
|
38
46
|
|
39
47
|
writer = LanguageServer::Protocol::Transport::Io::Writer.new(stdin)
|
@@ -42,11 +50,12 @@ module Steep
|
|
42
50
|
new(reader: reader, writer: writer, stderr: stderr, wait_thread: thread, name: name, index: index)
|
43
51
|
end
|
44
52
|
|
45
|
-
def self.spawn_typecheck_workers(steepfile:, args:, count: [Etc.nprocessors - 1, 1].max, delay_shutdown: false)
|
53
|
+
def self.spawn_typecheck_workers(steepfile:, args:, steep_command: "steep", count: [Etc.nprocessors - 1, 1].max, delay_shutdown: false)
|
46
54
|
count.times.map do |i|
|
47
55
|
spawn_worker(:typecheck,
|
48
56
|
name: "typecheck@#{i}",
|
49
57
|
steepfile: steepfile,
|
58
|
+
steep_command: steep_command,
|
50
59
|
options: ["--max-index=#{count}", "--index=#{i}", *args],
|
51
60
|
delay_shutdown: delay_shutdown,
|
52
61
|
index: i)
|
@@ -21,10 +21,11 @@ module Steep
|
|
21
21
|
end
|
22
22
|
TypeNameQuery = Struct.new(:name, keyword_init: true)
|
23
23
|
|
24
|
-
attr_reader :type_check
|
24
|
+
attr_reader :type_check, :assignment
|
25
25
|
|
26
|
-
def initialize(type_check:)
|
26
|
+
def initialize(type_check:, assignment:)
|
27
27
|
@type_check = type_check
|
28
|
+
@assignment = assignment
|
28
29
|
end
|
29
30
|
|
30
31
|
def project
|
@@ -78,7 +79,17 @@ module Steep
|
|
78
79
|
end
|
79
80
|
end
|
80
81
|
|
81
|
-
|
82
|
+
# Drop un-assigned paths here.
|
83
|
+
# The path assignment makes sense only for `.rbs` files, because un-assigned `.rb` files are already skipped since they are not type checked.
|
84
|
+
#
|
85
|
+
locations.uniq.select do |loc|
|
86
|
+
case loc
|
87
|
+
when RBS::Location
|
88
|
+
assignment =~ loc.name
|
89
|
+
else
|
90
|
+
true
|
91
|
+
end
|
92
|
+
end
|
82
93
|
end
|
83
94
|
|
84
95
|
def test_ast_location(loc, line:, column:)
|
@@ -100,6 +111,7 @@ module Steep
|
|
100
111
|
typing, signature = type_check_path(target: target, path: relative_path, content: source.content, line: line, column: column)
|
101
112
|
if typing
|
102
113
|
node, *parents = typing.source.find_nodes(line: line, column: column)
|
114
|
+
|
103
115
|
if node
|
104
116
|
case node.type
|
105
117
|
when :const, :casgn
|
@@ -125,7 +137,10 @@ module Steep
|
|
125
137
|
end
|
126
138
|
when :send
|
127
139
|
if test_ast_location(node.location.selector, line: line, column: column)
|
128
|
-
|
140
|
+
if (parent = parents[0]) && parent.type == :block && parent.children[0] == node
|
141
|
+
node = parents[0]
|
142
|
+
end
|
143
|
+
|
129
144
|
case call = typing.call_of(node: node)
|
130
145
|
when TypeInference::MethodCall::Typed, TypeInference::MethodCall::Error
|
131
146
|
call.method_decls.each do |decl|
|
@@ -269,6 +269,8 @@ module Steep
|
|
269
269
|
end
|
270
270
|
|
271
271
|
def typecheck_source(path:, target: project.target_for_source_path(path), &block)
|
272
|
+
return unless target
|
273
|
+
|
272
274
|
Steep.logger.tagged "#typecheck_source(path=#{path})" do
|
273
275
|
Steep.measure "typecheck" do
|
274
276
|
signature_service = signature_services[target.name]
|
@@ -89,11 +89,7 @@ module Steep
|
|
89
89
|
end
|
90
90
|
end
|
91
91
|
|
92
|
-
def
|
93
|
-
Steep.logger.debug "#{Location.to_string type.location}: Validating #{type}..."
|
94
|
-
|
95
|
-
validator.validate_type type, context: [RBS::Namespace.root]
|
96
|
-
|
92
|
+
def validate_type_application(type)
|
97
93
|
name, type_params, type_args =
|
98
94
|
case type
|
99
95
|
when RBS::Types::ClassInstance
|
@@ -123,6 +119,17 @@ module Steep
|
|
123
119
|
validate_type_application_constraints(type.name, type_params, type_args, location: type.location)
|
124
120
|
end
|
125
121
|
end
|
122
|
+
|
123
|
+
type.each_type do |child|
|
124
|
+
validate_type_application(child)
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
def validate_type(type)
|
129
|
+
Steep.logger.debug "#{Location.to_string type.location}: Validating #{type}..."
|
130
|
+
|
131
|
+
validator.validate_type type, context: [RBS::Namespace.root]
|
132
|
+
validate_type_application(type)
|
126
133
|
end
|
127
134
|
|
128
135
|
def ancestor_to_type(ancestor)
|
@@ -347,7 +347,7 @@ module Steep
|
|
347
347
|
|
348
348
|
when relation.super_type.is_a?(AST::Types::Union)
|
349
349
|
Any(relation) do |result|
|
350
|
-
relation.super_type.types.each do |super_type|
|
350
|
+
relation.super_type.types.sort_by {|ty| (path = hole_path(ty)) ? -path.size : 1 }.each do |super_type|
|
351
351
|
rel = Relation.new(sub_type: relation.sub_type, super_type: super_type)
|
352
352
|
result.add(rel) do
|
353
353
|
check_type(rel)
|
@@ -357,7 +357,7 @@ module Steep
|
|
357
357
|
|
358
358
|
when relation.sub_type.is_a?(AST::Types::Intersection)
|
359
359
|
Any(relation) do |result|
|
360
|
-
relation.sub_type.types.each do |sub_type|
|
360
|
+
relation.sub_type.types.sort_by {|ty| (path = hole_path(ty)) ? -path.size : 1 }.each do |sub_type|
|
361
361
|
rel = Relation.new(sub_type: sub_type, super_type: relation.super_type)
|
362
362
|
result.add(rel) do
|
363
363
|
check_type(rel)
|
@@ -483,6 +483,9 @@ module Steep
|
|
483
483
|
check_interface(relation.map {|type| factory.interface(type, private: false) })
|
484
484
|
end
|
485
485
|
|
486
|
+
when relation.sub_type.is_a?(AST::Types::Proc) && AST::Builtin::Proc.instance_type?(relation.super_type)
|
487
|
+
Success(relation)
|
488
|
+
|
486
489
|
when relation.super_type.is_a?(AST::Types::Literal)
|
487
490
|
case
|
488
491
|
when relation.super_type.value == true && AST::Builtin::TrueClass.instance_type?(relation.sub_type)
|
@@ -971,6 +974,24 @@ module Steep
|
|
971
974
|
def expand_alias(type, &block)
|
972
975
|
factory.expand_alias(type, &block)
|
973
976
|
end
|
977
|
+
|
978
|
+
# Returns the shortest type paths for one of the _unknown_ type variables.
|
979
|
+
# Returns nil if there is no path.
|
980
|
+
def hole_path(type, path = [])
|
981
|
+
case type
|
982
|
+
when AST::Types::Var
|
983
|
+
if constraints.unknown?(type.name)
|
984
|
+
[type]
|
985
|
+
else
|
986
|
+
nil
|
987
|
+
end
|
988
|
+
else
|
989
|
+
paths = type.each_child.map do |ty|
|
990
|
+
hole_path(ty, path)&.unshift(ty)
|
991
|
+
end
|
992
|
+
paths.compact.min_by(&:size)
|
993
|
+
end
|
994
|
+
end
|
974
995
|
end
|
975
996
|
end
|
976
997
|
end
|
@@ -1005,7 +1005,7 @@ module Steep
|
|
1005
1005
|
yield_self do
|
1006
1006
|
send_node, params, body = node.children
|
1007
1007
|
if send_node.type == :lambda
|
1008
|
-
type_lambda(node,
|
1008
|
+
type_lambda(node, params_node: params, body_node: body, type_hint: hint)
|
1009
1009
|
else
|
1010
1010
|
type_send(node, send_node: send_node, block_params: params, block_body: body, unwrap: send_node.type == :csend)
|
1011
1011
|
end
|
@@ -1024,7 +1024,7 @@ module Steep
|
|
1024
1024
|
params = Parser::AST::Node.new(:args, arg_nodes)
|
1025
1025
|
|
1026
1026
|
if send_node.type == :lambda
|
1027
|
-
type_lambda(node,
|
1027
|
+
type_lambda(node, params_node: params, body_node: body, type_hint: hint)
|
1028
1028
|
else
|
1029
1029
|
type_send(node, send_node: send_node, block_params: params, block_body: body, unwrap: send_node.type == :csend)
|
1030
1030
|
end
|
@@ -1181,9 +1181,9 @@ module Steep
|
|
1181
1181
|
|
1182
1182
|
when :return
|
1183
1183
|
yield_self do
|
1184
|
-
|
1185
|
-
method_return_type = expand_alias(method_context&.return_type)
|
1184
|
+
method_return_type = expand_alias(method_context&.return_type)
|
1186
1185
|
|
1186
|
+
if node.children.size > 0
|
1187
1187
|
return_types = node.children.map do |value|
|
1188
1188
|
synthesize(
|
1189
1189
|
value,
|
@@ -1201,20 +1201,23 @@ module Steep
|
|
1201
1201
|
AST::Builtin::Array.instance_type(union_type(*return_types))
|
1202
1202
|
end
|
1203
1203
|
|
1204
|
-
|
1205
|
-
|
1206
|
-
|
1204
|
+
else
|
1205
|
+
value_type = AST::Builtin.nil_type
|
1206
|
+
end
|
1207
1207
|
|
1208
|
-
|
1209
|
-
|
1210
|
-
|
1211
|
-
|
1212
|
-
|
1213
|
-
|
1214
|
-
|
1215
|
-
|
1208
|
+
if method_return_type
|
1209
|
+
unless method_return_type.is_a?(AST::Types::Void)
|
1210
|
+
result = check_relation(sub_type: value_type, super_type: method_return_type)
|
1211
|
+
|
1212
|
+
if result.failure?
|
1213
|
+
typing.add_error(
|
1214
|
+
Diagnostic::Ruby::ReturnTypeMismatch.new(
|
1215
|
+
node: node,
|
1216
|
+
expected: method_context&.return_type,
|
1217
|
+
actual: value_type,
|
1218
|
+
result: result
|
1216
1219
|
)
|
1217
|
-
|
1220
|
+
)
|
1218
1221
|
end
|
1219
1222
|
end
|
1220
1223
|
end
|
@@ -2272,13 +2275,10 @@ module Steep
|
|
2272
2275
|
type, constr = synthesize(rhs, hint: hint)
|
2273
2276
|
constr.ivasgn(asgn, type)
|
2274
2277
|
when :send
|
2275
|
-
|
2276
|
-
|
2277
|
-
|
2278
|
-
|
2279
|
-
asgn.children[2],
|
2280
|
-
rhs
|
2281
|
-
])
|
2278
|
+
children = asgn.children.dup
|
2279
|
+
children[1] = :"#{children[1]}="
|
2280
|
+
send_arg_nodes = [*children, rhs]
|
2281
|
+
rhs_ = node.updated(:send, send_arg_nodes)
|
2282
2282
|
node_type = case node.type
|
2283
2283
|
when :or_asgn
|
2284
2284
|
:or
|
@@ -2345,11 +2345,11 @@ module Steep
|
|
2345
2345
|
interface = calculate_interface(param_type, private: true)
|
2346
2346
|
method = interface.methods[value.children[0]]
|
2347
2347
|
if method
|
2348
|
-
return_types = method.method_types.
|
2349
|
-
method_type.type.params.
|
2350
|
-
|
2351
|
-
|
2352
|
-
|
2348
|
+
return_types = method.method_types.filter_map do |method_type|
|
2349
|
+
if method_type.type.params.optional?
|
2350
|
+
method_type.type.return_type
|
2351
|
+
end
|
2352
|
+
end
|
2353
2353
|
|
2354
2354
|
unless return_types.empty?
|
2355
2355
|
type = AST::Types::Proc.new(
|
@@ -2357,7 +2357,7 @@ module Steep
|
|
2357
2357
|
params: Interface::Function::Params.empty.with_first_param(
|
2358
2358
|
Interface::Function::Params::PositionalParams::Required.new(param_type)
|
2359
2359
|
),
|
2360
|
-
return_type:
|
2360
|
+
return_type: return_types[0],
|
2361
2361
|
location: nil
|
2362
2362
|
),
|
2363
2363
|
block: nil
|
@@ -2724,34 +2724,89 @@ module Steep
|
|
2724
2724
|
end
|
2725
2725
|
end
|
2726
2726
|
|
2727
|
-
def
|
2727
|
+
def optional_proc?(type)
|
2728
|
+
if type.is_a?(AST::Types::Union)
|
2729
|
+
if type.types.size == 2
|
2730
|
+
if type.types.find {|t| t.is_a?(AST::Types::Nil) }
|
2731
|
+
if proc_type = type.types.find {|t| t.is_a?(AST::Types::Proc) }
|
2732
|
+
proc_type
|
2733
|
+
end
|
2734
|
+
end
|
2735
|
+
end
|
2736
|
+
end
|
2737
|
+
end
|
2738
|
+
|
2739
|
+
def type_lambda(node, params_node:, body_node:, type_hint:)
|
2728
2740
|
block_annotations = source.annotations(block: node, factory: checker.factory, current_module: current_namespace)
|
2729
|
-
params = TypeInference::BlockParams.from_node(
|
2741
|
+
params = TypeInference::BlockParams.from_node(params_node, annotations: block_annotations)
|
2742
|
+
|
2743
|
+
type_hint = deep_expand_alias(type_hint) if type_hint
|
2730
2744
|
|
2731
2745
|
case type_hint
|
2732
2746
|
when AST::Types::Proc
|
2733
2747
|
params_hint = type_hint.type.params
|
2734
2748
|
return_hint = type_hint.type.return_type
|
2749
|
+
block_hint = type_hint.block
|
2735
2750
|
end
|
2736
2751
|
|
2737
2752
|
block_constr = for_block(
|
2738
2753
|
block_params: params,
|
2739
2754
|
block_param_hint: params_hint,
|
2740
2755
|
block_type_hint: return_hint,
|
2756
|
+
block_block_hint: block_hint,
|
2741
2757
|
block_annotations: block_annotations,
|
2742
2758
|
node_type_hint: nil
|
2743
2759
|
)
|
2744
2760
|
|
2745
2761
|
block_constr.typing.add_context_for_body(node, context: block_constr.context)
|
2746
2762
|
|
2763
|
+
default_proc_function =
|
2764
|
+
Interface::Function.new(
|
2765
|
+
params: Interface::Function::Params.empty,
|
2766
|
+
return_type: AST::Builtin.any_type,
|
2767
|
+
location: nil
|
2768
|
+
)
|
2769
|
+
|
2747
2770
|
params.params.each do |param|
|
2748
2771
|
_, block_constr = block_constr.synthesize(param.node, hint: param.type)
|
2749
2772
|
end
|
2750
2773
|
|
2751
|
-
|
2774
|
+
block =
|
2775
|
+
if block_param = params.block_param
|
2776
|
+
if block_param_type = block_param.type
|
2777
|
+
case block_param_type
|
2778
|
+
when AST::Types::Proc
|
2779
|
+
Interface::Block.new(type: block_param_type.type, optional: false)
|
2780
|
+
else
|
2781
|
+
if proc_type = optional_proc?(block_param_type)
|
2782
|
+
Interface::Block.new(type: proc_type.type, optional: true)
|
2783
|
+
else
|
2784
|
+
block_constr.typing.add_error(
|
2785
|
+
Diagnostic::Ruby::ProcTypeExpected.new(
|
2786
|
+
node: block_param.node,
|
2787
|
+
type: block_param_type
|
2788
|
+
)
|
2789
|
+
)
|
2790
|
+
|
2791
|
+
Interface::Block.new(
|
2792
|
+
type: Interface::Function.new(
|
2793
|
+
params: Interface::Function::Params.empty,
|
2794
|
+
return_type: AST::Builtin.any_type,
|
2795
|
+
location: nil
|
2796
|
+
),
|
2797
|
+
optional: false
|
2798
|
+
)
|
2799
|
+
end
|
2800
|
+
end
|
2801
|
+
else
|
2802
|
+
block_hint
|
2803
|
+
end
|
2804
|
+
end
|
2805
|
+
|
2806
|
+
if body_node
|
2752
2807
|
return_type = block_constr.synthesize_block(
|
2753
2808
|
node: node,
|
2754
|
-
block_body:
|
2809
|
+
block_body: body_node,
|
2755
2810
|
block_type_hint: return_hint
|
2756
2811
|
)
|
2757
2812
|
|
@@ -2779,7 +2834,7 @@ module Steep
|
|
2779
2834
|
return_type: return_type,
|
2780
2835
|
location: nil
|
2781
2836
|
),
|
2782
|
-
block:
|
2837
|
+
block: block
|
2783
2838
|
)
|
2784
2839
|
|
2785
2840
|
add_typing node, type: block_type
|
@@ -3246,7 +3301,7 @@ module Steep
|
|
3246
3301
|
|
3247
3302
|
if method_type.block
|
3248
3303
|
# Method accepts block
|
3249
|
-
pairs = method_type.block && block_params_&.zip(method_type.block.type.params)
|
3304
|
+
pairs = method_type.block && block_params_&.zip(method_type.block.type.params, nil)
|
3250
3305
|
|
3251
3306
|
if pairs
|
3252
3307
|
# Block parameters are compatible with the block type
|
@@ -3254,6 +3309,7 @@ module Steep
|
|
3254
3309
|
block_params: block_params_,
|
3255
3310
|
block_param_hint: method_type.block.type.params,
|
3256
3311
|
block_type_hint: method_type.block.type.return_type,
|
3312
|
+
block_block_hint: nil,
|
3257
3313
|
block_annotations: block_annotations,
|
3258
3314
|
node_type_hint: method_type.type.return_type
|
3259
3315
|
)
|
@@ -3503,13 +3559,14 @@ module Steep
|
|
3503
3559
|
message: "Unsupported block params pattern, probably masgn?"
|
3504
3560
|
)
|
3505
3561
|
)
|
3506
|
-
block_params = TypeInference::BlockParams.new(leading_params: [], optional_params: [], rest_param: nil, trailing_params: [])
|
3562
|
+
block_params = TypeInference::BlockParams.new(leading_params: [], optional_params: [], rest_param: nil, trailing_params: [], block_param: nil)
|
3507
3563
|
end
|
3508
3564
|
|
3509
3565
|
block_constr = for_block(
|
3510
3566
|
block_params: block_params,
|
3511
3567
|
block_param_hint: nil,
|
3512
3568
|
block_type_hint: AST::Builtin.any_type,
|
3569
|
+
block_block_hint: nil,
|
3513
3570
|
block_annotations: block_annotations,
|
3514
3571
|
node_type_hint: AST::Builtin.any_type
|
3515
3572
|
)
|
@@ -3536,8 +3593,8 @@ module Steep
|
|
3536
3593
|
end
|
3537
3594
|
end
|
3538
3595
|
|
3539
|
-
def for_block(block_params:, block_param_hint:, block_type_hint:, block_annotations:, node_type_hint:)
|
3540
|
-
block_param_pairs = block_param_hint && block_params.zip(block_param_hint)
|
3596
|
+
def for_block(block_params:, block_param_hint:, block_type_hint:, block_block_hint:, block_annotations:, node_type_hint:)
|
3597
|
+
block_param_pairs = block_param_hint && block_params.zip(block_param_hint, block_block_hint)
|
3541
3598
|
|
3542
3599
|
param_types_hash = {}
|
3543
3600
|
if block_param_pairs
|
@@ -3888,6 +3945,20 @@ module Steep
|
|
3888
3945
|
constr.add_typing(node, type: AST::Types::Tuple.new(types: element_types))
|
3889
3946
|
end
|
3890
3947
|
|
3948
|
+
def try_convert(type, method)
|
3949
|
+
interface = checker.factory.interface(type, private: false)
|
3950
|
+
if entry = interface.methods[method]
|
3951
|
+
method_type = entry.method_types.find do |method_type|
|
3952
|
+
method_type.type.params.optional?
|
3953
|
+
end
|
3954
|
+
|
3955
|
+
method_type.type.return_type
|
3956
|
+
end
|
3957
|
+
rescue => exn
|
3958
|
+
Steep.log_error(exn, message: "Unexpected error when converting #{type.to_s} with #{method}")
|
3959
|
+
nil
|
3960
|
+
end
|
3961
|
+
|
3891
3962
|
def try_array_type(node, hint)
|
3892
3963
|
element_hint = hint ? hint.args[0] : nil
|
3893
3964
|
|
@@ -3898,8 +3969,14 @@ module Steep
|
|
3898
3969
|
case child.type
|
3899
3970
|
when :splat
|
3900
3971
|
type, constr = constr.synthesize(child.children[0], hint: hint)
|
3901
|
-
|
3972
|
+
|
3973
|
+
type = try_convert(type, :to_a) || type
|
3974
|
+
|
3975
|
+
case
|
3976
|
+
when AST::Builtin::Array.instance_type?(type)
|
3902
3977
|
element_types << type.args[0]
|
3978
|
+
when type.is_a?(AST::Types::Tuple)
|
3979
|
+
element_types.push(*type.types)
|
3903
3980
|
else
|
3904
3981
|
element_types.push(*flatten_array_elements(type))
|
3905
3982
|
end
|
@@ -29,12 +29,14 @@ module Steep
|
|
29
29
|
attr_reader :optional_params
|
30
30
|
attr_reader :rest_param
|
31
31
|
attr_reader :trailing_params
|
32
|
+
attr_reader :block_param
|
32
33
|
|
33
|
-
def initialize(leading_params:, optional_params:, rest_param:, trailing_params:)
|
34
|
+
def initialize(leading_params:, optional_params:, rest_param:, trailing_params:, block_param:)
|
34
35
|
@leading_params = leading_params
|
35
36
|
@optional_params = optional_params
|
36
37
|
@rest_param = rest_param
|
37
38
|
@trailing_params = trailing_params
|
39
|
+
@block_param = block_param
|
38
40
|
end
|
39
41
|
|
40
42
|
def params
|
@@ -43,6 +45,7 @@ module Steep
|
|
43
45
|
params.push(*optional_params)
|
44
46
|
params.push rest_param if rest_param
|
45
47
|
params.push(*trailing_params)
|
48
|
+
params.push(block_param) if block_param
|
46
49
|
end
|
47
50
|
end
|
48
51
|
|
@@ -51,6 +54,7 @@ module Steep
|
|
51
54
|
optional_params = []
|
52
55
|
rest_param = nil
|
53
56
|
trailing_params = []
|
57
|
+
block_param = nil
|
54
58
|
|
55
59
|
default_params = leading_params
|
56
60
|
|
@@ -72,6 +76,9 @@ module Steep
|
|
72
76
|
when :restarg
|
73
77
|
default_params = trailing_params
|
74
78
|
rest_param = Param.new(var: var, type: type, value: nil, node: arg)
|
79
|
+
when :blockarg
|
80
|
+
block_param = Param.new(var: var, type: type, value: nil, node: arg)
|
81
|
+
break
|
75
82
|
end
|
76
83
|
end
|
77
84
|
|
@@ -79,7 +86,8 @@ module Steep
|
|
79
86
|
leading_params: leading_params,
|
80
87
|
optional_params: optional_params,
|
81
88
|
rest_param: rest_param,
|
82
|
-
trailing_params: trailing_params
|
89
|
+
trailing_params: trailing_params,
|
90
|
+
block_param: block_param
|
83
91
|
)
|
84
92
|
end
|
85
93
|
|
@@ -141,7 +149,7 @@ module Steep
|
|
141
149
|
)
|
142
150
|
end
|
143
151
|
|
144
|
-
def zip(params_type)
|
152
|
+
def zip(params_type, block)
|
145
153
|
if trailing_params.any?
|
146
154
|
Steep.logger.error "Block definition with trailing required parameters are not supported yet"
|
147
155
|
end
|
@@ -204,6 +212,26 @@ module Steep
|
|
204
212
|
end
|
205
213
|
end
|
206
214
|
end
|
215
|
+
|
216
|
+
if block_param
|
217
|
+
if block
|
218
|
+
proc_type =
|
219
|
+
if block.optional?
|
220
|
+
AST::Types::Union.build(
|
221
|
+
types: [
|
222
|
+
AST::Types::Proc.new(type: block.type, block: nil),
|
223
|
+
AST::Builtin.nil_type
|
224
|
+
]
|
225
|
+
)
|
226
|
+
else
|
227
|
+
AST::Types::Proc.new(type: block.type, block: nil)
|
228
|
+
end
|
229
|
+
|
230
|
+
zip << [block_param, proc_type]
|
231
|
+
else
|
232
|
+
zip << [block_param, AST::Builtin.nil_type]
|
233
|
+
end
|
234
|
+
end
|
207
235
|
end
|
208
236
|
end
|
209
237
|
|
data/lib/steep/version.rb
CHANGED
@@ -332,6 +332,18 @@
|
|
332
332
|
severity: ERROR
|
333
333
|
message: Type `::Integer` does not have method `foo`
|
334
334
|
code: Ruby::NoMethod
|
335
|
+
- file: proc_type_expected.rb
|
336
|
+
diagnostics:
|
337
|
+
- range:
|
338
|
+
start:
|
339
|
+
line: 1
|
340
|
+
character: 4
|
341
|
+
end:
|
342
|
+
line: 1
|
343
|
+
character: 10
|
344
|
+
severity: ERROR
|
345
|
+
message: Proc type is expected but `::Integer` is specified
|
346
|
+
code: Ruby::ProcTypeExpected
|
335
347
|
- file: required_block_missing.rb
|
336
348
|
diagnostics:
|
337
349
|
- range:
|
data/smoke/tsort/a.rb
CHANGED
@@ -1,63 +1 @@
|
|
1
|
-
---
|
2
|
-
- file: a.rb
|
3
|
-
diagnostics:
|
4
|
-
- range:
|
5
|
-
start:
|
6
|
-
line: 7
|
7
|
-
character: 0
|
8
|
-
end:
|
9
|
-
line: 7
|
10
|
-
character: 38
|
11
|
-
severity: ERROR
|
12
|
-
message: |-
|
13
|
-
Cannot assign a value of type `^() -> ::Hash[::Integer, ::Array[::Integer]]` to a variable of type `^() { (::Integer) -> void } -> void`
|
14
|
-
^() -> ::Hash[::Integer, ::Array[::Integer]] <: ^() { (::Integer) -> void } -> void
|
15
|
-
code: Ruby::IncompatibleAssignment
|
16
|
-
- range:
|
17
|
-
start:
|
18
|
-
line: 7
|
19
|
-
character: 34
|
20
|
-
end:
|
21
|
-
line: 7
|
22
|
-
character: 35
|
23
|
-
severity: ERROR
|
24
|
-
message: Cannot detect the type of the expression
|
25
|
-
code: Ruby::FallbackAny
|
26
|
-
- range:
|
27
|
-
start:
|
28
|
-
line: 9
|
29
|
-
character: 0
|
30
|
-
end:
|
31
|
-
line: 9
|
32
|
-
character: 41
|
33
|
-
severity: ERROR
|
34
|
-
message: |-
|
35
|
-
Cannot assign a value of type `^(::Integer) -> ::Enumerator[::Integer, ::Array[::Integer]]` to a variable of type `^(::Integer) { (::Integer) -> void } -> void`
|
36
|
-
^(::Integer) -> ::Enumerator[::Integer, ::Array[::Integer]] <: ^(::Integer) { (::Integer) -> void } -> void
|
37
|
-
code: Ruby::IncompatibleAssignment
|
38
|
-
- range:
|
39
|
-
start:
|
40
|
-
line: 9
|
41
|
-
character: 37
|
42
|
-
end:
|
43
|
-
line: 9
|
44
|
-
character: 38
|
45
|
-
severity: ERROR
|
46
|
-
message: Cannot detect the type of the expression
|
47
|
-
code: Ruby::FallbackAny
|
48
|
-
- range:
|
49
|
-
start:
|
50
|
-
line: 12
|
51
|
-
character: 0
|
52
|
-
end:
|
53
|
-
line: 12
|
54
|
-
character: 39
|
55
|
-
severity: ERROR
|
56
|
-
message: |-
|
57
|
-
Cannot assign a value of type `::Array[::Integer]` to a variable of type `::Array[::String]`
|
58
|
-
::Array[::Integer] <: ::Array[::String]
|
59
|
-
::Integer <: ::String
|
60
|
-
::Numeric <: ::String
|
61
|
-
::Object <: ::String
|
62
|
-
::BasicObject <: ::String
|
63
|
-
code: Ruby::IncompatibleAssignment
|
1
|
+
--- []
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: steep
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.50.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Soutaro Matsumoto
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-03-
|
11
|
+
date: 2022-03-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: parser
|
@@ -356,6 +356,7 @@ files:
|
|
356
356
|
- smoke/diagnostics/method_return_type_annotation_mismatch.rb
|
357
357
|
- smoke/diagnostics/missing_keyword.rb
|
358
358
|
- smoke/diagnostics/no_method.rb
|
359
|
+
- smoke/diagnostics/proc_type_expected.rb
|
359
360
|
- smoke/diagnostics/required_block_missing.rb
|
360
361
|
- smoke/diagnostics/return_type_mismatch.rb
|
361
362
|
- smoke/diagnostics/test_expectations.yml
|