steep 1.4.0 → 1.5.0.pre.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +2 -0
- data/.vscode/steep-shared.code-snippets +41 -0
- data/CHANGELOG.md +37 -0
- data/Gemfile +2 -5
- data/Gemfile.lock +20 -17
- data/Gemfile.steep +1 -1
- data/Gemfile.steep.lock +6 -6
- data/Rakefile +198 -0
- data/Steepfile +3 -1
- data/lib/steep/ast/builtin.rb +9 -7
- data/lib/steep/ast/node/type_application.rb +13 -5
- data/lib/steep/ast/node/type_assertion.rb +28 -9
- data/lib/steep/ast/types/factory.rb +39 -7
- data/lib/steep/cli.rb +2 -1
- data/lib/steep/diagnostic/deprecated/else_on_exhaustive_case.rb +20 -0
- data/lib/steep/diagnostic/lsp_formatter.rb +3 -3
- data/lib/steep/diagnostic/ruby.rb +73 -12
- data/lib/steep/drivers/annotations.rb +1 -0
- data/lib/steep/drivers/check.rb +18 -13
- data/lib/steep/drivers/checkfile.rb +1 -1
- data/lib/steep/drivers/diagnostic_printer.rb +6 -4
- data/lib/steep/drivers/init.rb +2 -1
- data/lib/steep/drivers/print_project.rb +3 -1
- data/lib/steep/drivers/stats.rb +1 -1
- data/lib/steep/drivers/utils/driver_helper.rb +10 -8
- data/lib/steep/drivers/utils/jobs_option.rb +6 -1
- data/lib/steep/drivers/validate.rb +9 -5
- data/lib/steep/drivers/watch.rb +8 -3
- data/lib/steep/expectations.rb +144 -75
- data/lib/steep/index/signature_symbol_provider.rb +22 -13
- data/lib/steep/node_helper.rb +172 -0
- data/lib/steep/server/base_worker.rb +2 -1
- data/lib/steep/server/change_buffer.rb +17 -15
- data/lib/steep/server/interaction_worker.rb +20 -0
- data/lib/steep/server/lsp_formatter.rb +20 -1
- data/lib/steep/server/master.rb +51 -36
- data/lib/steep/server/type_check_worker.rb +18 -2
- data/lib/steep/server/worker_process.rb +19 -2
- data/lib/steep/services/completion_provider.rb +189 -3
- data/lib/steep/services/file_loader.rb +1 -1
- data/lib/steep/services/goto_service.rb +123 -27
- data/lib/steep/services/signature_help_provider.rb +1 -6
- data/lib/steep/signature/validator.rb +6 -1
- data/lib/steep/source.rb +165 -108
- data/lib/steep/subtyping/check.rb +5 -3
- data/lib/steep/subtyping/variable_variance.rb +11 -0
- data/lib/steep/thread_waiter.rb +35 -0
- data/lib/steep/type_construction.rb +416 -171
- data/lib/steep/type_inference/block_params.rb +50 -9
- data/lib/steep/type_inference/context.rb +4 -0
- data/lib/steep/type_inference/context_array.rb +6 -6
- data/lib/steep/type_inference/logic_type_interpreter.rb +202 -68
- data/lib/steep/typing.rb +5 -4
- data/lib/steep/version.rb +1 -1
- data/lib/steep.rb +21 -14
- data/sample/Steepfile +1 -0
- data/sig/shims/bundler.rbs +3 -0
- data/sig/shims/language-server_protocol.rbs +151 -10
- data/sig/shims/parser/nodes.rbs +210 -0
- data/sig/shims/parser.rbs +10 -0
- data/sig/steep/ast/builtin.rbs +2 -2
- data/sig/steep/ast/node/type_application.rbs +2 -2
- data/sig/steep/ast/node/type_assertion.rbs +8 -2
- data/sig/steep/ast/types/factory.rbs +28 -1
- data/sig/steep/diagnostic/deprecated/else_on_exhaustive_case.rbs +13 -0
- data/sig/steep/diagnostic/lsp_formatter.rbs +5 -2
- data/sig/steep/diagnostic/ruby.rbs +76 -6
- data/sig/steep/drivers/annotations.rbs +5 -5
- data/sig/steep/drivers/check.rbs +11 -11
- data/sig/steep/drivers/diagnostic_printer.rbs +9 -9
- data/sig/steep/drivers/init.rbs +6 -6
- data/sig/steep/drivers/print_project.rbs +4 -4
- data/sig/steep/drivers/utils/driver_helper.rbs +8 -6
- data/sig/steep/drivers/validate.rbs +4 -4
- data/sig/steep/drivers/watch.rbs +1 -1
- data/sig/steep/expectations.rbs +72 -0
- data/sig/steep/index/signature_symbol_provider.rbs +22 -10
- data/sig/steep/interface/block.rbs +2 -0
- data/sig/steep/interface/function.rbs +2 -2
- data/sig/steep/node_helper.rbs +56 -0
- data/sig/steep/path_helper.rbs +1 -1
- data/sig/steep/project/options.rbs +1 -1
- data/sig/steep/range_extension.rbs +2 -2
- data/sig/steep/server/master.rbs +16 -2
- data/sig/steep/server/type_check_worker.rbs +5 -1
- data/sig/steep/server/worker_process.rbs +5 -1
- data/sig/steep/services/completion_provider.rbs +31 -1
- data/sig/steep/services/goto_service.rbs +80 -19
- data/sig/steep/source.rbs +27 -4
- data/sig/steep/subtyping/variable_variance.rbs +9 -9
- data/sig/steep/thread_waiter.rbs +13 -0
- data/sig/steep/type_construction.rbs +26 -9
- data/sig/steep/type_inference/block_params.rbs +13 -1
- data/sig/steep/type_inference/context.rbs +5 -1
- data/sig/steep/type_inference/context_array.rbs +16 -15
- data/sig/steep/type_inference/logic_type_interpreter.rbs +36 -6
- data/sig/steep/type_inference/type_env_builder.rbs +4 -0
- data/sig/steep/typing.rbs +22 -20
- data/sig/steep.rbs +14 -13
- data/smoke/and/a.rb +1 -1
- data/smoke/and/test_expectations.yml +5 -7
- data/smoke/diagnostics/incompatible_annotation.rb +1 -1
- data/smoke/diagnostics/test_expectations.yml +2 -2
- data/smoke/enumerator/a.rb +0 -7
- data/smoke/enumerator/b.rb +0 -2
- data/smoke/enumerator/test_expectations.yml +17 -105
- data/smoke/lambda/a.rb +0 -5
- data/smoke/lambda/test_expectations.yml +0 -22
- data/smoke/type_case/test_expectations.yml +10 -0
- data/steep.gemspec +2 -2
- metadata +16 -9
data/lib/steep/server/master.rb
CHANGED
@@ -450,50 +450,65 @@ module Steep
|
|
450
450
|
end
|
451
451
|
end
|
452
452
|
|
453
|
-
|
454
|
-
|
455
|
-
|
456
|
-
|
457
|
-
|
453
|
+
loop_thread = Thread.new do
|
454
|
+
Steep.logger.formatter.push_tags(*tags)
|
455
|
+
Steep.logger.tagged "main" do
|
456
|
+
while job = job_queue.deq
|
457
|
+
case job
|
458
|
+
when ReceiveMessageJob
|
459
|
+
src = case job.source
|
460
|
+
when :client
|
461
|
+
:client
|
462
|
+
else
|
463
|
+
job.source.name
|
464
|
+
end
|
465
|
+
Steep.logger.tagged("ReceiveMessageJob(#{src}/#{job.message[:method]}/#{job.message[:id]})") do
|
466
|
+
if job.response? && result_controller.process_response(job.message)
|
467
|
+
# nop
|
468
|
+
Steep.logger.info { "Processed by ResultController" }
|
469
|
+
else
|
470
|
+
case job.source
|
458
471
|
when :client
|
459
|
-
|
460
|
-
|
461
|
-
job.
|
462
|
-
|
463
|
-
|
464
|
-
|
465
|
-
|
466
|
-
Steep.logger.info { "Processed by ResultController" }
|
467
|
-
else
|
468
|
-
case job.source
|
469
|
-
when :client
|
470
|
-
process_message_from_client(job.message)
|
471
|
-
|
472
|
-
if job.message[:method] == "exit"
|
473
|
-
job_queue.close()
|
472
|
+
process_message_from_client(job.message)
|
473
|
+
|
474
|
+
if job.message[:method] == "exit"
|
475
|
+
job_queue.close()
|
476
|
+
end
|
477
|
+
when WorkerProcess
|
478
|
+
process_message_from_worker(job.message, worker: job.source)
|
474
479
|
end
|
475
|
-
when WorkerProcess
|
476
|
-
process_message_from_worker(job.message, worker: job.source)
|
477
480
|
end
|
478
481
|
end
|
479
|
-
|
480
|
-
|
481
|
-
|
482
|
-
|
483
|
-
|
484
|
-
|
485
|
-
|
486
|
-
|
487
|
-
|
482
|
+
when SendMessageJob
|
483
|
+
case job.dest
|
484
|
+
when :client
|
485
|
+
Steep.logger.info { "Processing SendMessageJob: dest=client, method=#{job.message[:method] || "-"}, id=#{job.message[:id] || "-"}" }
|
486
|
+
writer.write job.message
|
487
|
+
when WorkerProcess
|
488
|
+
Steep.logger.info { "Processing SendMessageJob: dest=#{job.dest.name}, method=#{job.message[:method] || "-"}, id=#{job.message[:id] || "-"}" }
|
489
|
+
job.dest << job.message
|
490
|
+
end
|
488
491
|
end
|
489
492
|
end
|
490
493
|
end
|
494
|
+
end
|
495
|
+
|
496
|
+
waiter = ThreadWaiter.new(each_worker.to_a) {|worker| worker.wait_thread }
|
497
|
+
waiter.wait_one()
|
491
498
|
|
492
|
-
|
493
|
-
|
494
|
-
|
499
|
+
unless job_queue.closed?
|
500
|
+
# Exit by error
|
501
|
+
each_worker do |worker|
|
502
|
+
worker.kill(force: true)
|
495
503
|
end
|
504
|
+
raise "Unexpected worker process exit"
|
505
|
+
end
|
506
|
+
|
507
|
+
read_client_thread.join()
|
508
|
+
worker_threads.each do |thread|
|
509
|
+
thread.join
|
496
510
|
end
|
511
|
+
loop_thread.join
|
497
512
|
end
|
498
513
|
end
|
499
514
|
|
@@ -555,7 +570,7 @@ module Steep
|
|
555
570
|
definition_provider: true,
|
556
571
|
declaration_provider: false,
|
557
572
|
implementation_provider: true,
|
558
|
-
type_definition_provider:
|
573
|
+
type_definition_provider: true
|
559
574
|
)
|
560
575
|
)
|
561
576
|
}
|
@@ -654,7 +669,7 @@ module Steep
|
|
654
669
|
end
|
655
670
|
end
|
656
671
|
|
657
|
-
when "textDocument/definition", "textDocument/implementation"
|
672
|
+
when "textDocument/definition", "textDocument/implementation", "textDocument/typeDefinition"
|
658
673
|
if path = pathname(message[:params][:textDocument][:uri])
|
659
674
|
result_controller << group_request do |group|
|
660
675
|
typecheck_workers.each do |worker|
|
@@ -30,6 +30,14 @@ module Steep
|
|
30
30
|
)
|
31
31
|
end
|
32
32
|
|
33
|
+
def self.type_definition(id:, params:)
|
34
|
+
new(
|
35
|
+
kind: :type_definition,
|
36
|
+
id: id,
|
37
|
+
params: params
|
38
|
+
)
|
39
|
+
end
|
40
|
+
|
33
41
|
def implementation?
|
34
42
|
kind == :implementation
|
35
43
|
end
|
@@ -37,6 +45,10 @@ module Steep
|
|
37
45
|
def definition?
|
38
46
|
kind == :definition
|
39
47
|
end
|
48
|
+
|
49
|
+
def type_definition?
|
50
|
+
kind == :type_definition
|
51
|
+
end
|
40
52
|
end
|
41
53
|
|
42
54
|
include ChangeBuffer
|
@@ -75,6 +87,8 @@ module Steep
|
|
75
87
|
queue << GotoJob.definition(id: request[:id], params: request[:params])
|
76
88
|
when "textDocument/implementation"
|
77
89
|
queue << GotoJob.implementation(id: request[:id], params: request[:params])
|
90
|
+
when "textDocument/typeDefinition"
|
91
|
+
queue << GotoJob.type_definition(id: request[:id], params: request[:params])
|
78
92
|
end
|
79
93
|
end
|
80
94
|
|
@@ -266,7 +280,7 @@ module Steep
|
|
266
280
|
end
|
267
281
|
|
268
282
|
def goto(job)
|
269
|
-
path = Steep::PathHelper.to_pathname(job.params[:textDocument][:uri])
|
283
|
+
path = Steep::PathHelper.to_pathname(job.params[:textDocument][:uri]) or return []
|
270
284
|
line = job.params[:position][:line] + 1
|
271
285
|
column = job.params[:position][:character]
|
272
286
|
|
@@ -277,6 +291,8 @@ module Steep
|
|
277
291
|
goto_service.definition(path: path, line: line, column: column)
|
278
292
|
when job.implementation?
|
279
293
|
goto_service.implementation(path: path, line: line, column: column)
|
294
|
+
when job.type_definition?
|
295
|
+
goto_service.type_definition(path: path, line: line, column: column)
|
280
296
|
else
|
281
297
|
raise
|
282
298
|
end
|
@@ -293,7 +309,7 @@ module Steep
|
|
293
309
|
path = project.absolute_path(path)
|
294
310
|
|
295
311
|
{
|
296
|
-
uri: Steep::PathHelper.to_uri(path
|
312
|
+
uri: Steep::PathHelper.to_uri(path).to_s,
|
297
313
|
range: loc.as_lsp_range
|
298
314
|
}
|
299
315
|
end
|
@@ -63,6 +63,9 @@ module Steep
|
|
63
63
|
worker.commandline_args = patterns
|
64
64
|
|
65
65
|
pid = fork do
|
66
|
+
Process.setpgid(0, 0)
|
67
|
+
stdin_out.close
|
68
|
+
stdout_in.close
|
66
69
|
worker.run()
|
67
70
|
end
|
68
71
|
|
@@ -149,8 +152,22 @@ module Steep
|
|
149
152
|
reader.read(&block)
|
150
153
|
end
|
151
154
|
|
152
|
-
def kill
|
153
|
-
|
155
|
+
def kill(force: false)
|
156
|
+
Steep.logger.tagged("WorkerProcess#kill@#{name}(#{wait_thread.pid})") do
|
157
|
+
begin
|
158
|
+
signal = force ? :KILL : :TERM
|
159
|
+
Steep.logger.debug("Sending signal SIG#{signal}...")
|
160
|
+
Process.kill(signal, wait_thread.pid)
|
161
|
+
Steep.logger.debug("Successfully sent the signal.")
|
162
|
+
rescue Errno::ESRCH => error
|
163
|
+
Steep.logger.debug("Failed #{error.inspect}")
|
164
|
+
end
|
165
|
+
unless force
|
166
|
+
Steep.logger.debug("Waiting for process exit...")
|
167
|
+
wait_thread.join()
|
168
|
+
Steep.logger.debug("Confirmed process exit.")
|
169
|
+
end
|
170
|
+
end
|
154
171
|
end
|
155
172
|
end
|
156
173
|
end
|
@@ -98,6 +98,62 @@ module Steep
|
|
98
98
|
# @implements GeneratedMethodNameItem
|
99
99
|
end
|
100
100
|
|
101
|
+
class TypeNameItem < Struct.new(:env, :absolute_type_name, :relative_type_name, :range, keyword_init: true)
|
102
|
+
def decl
|
103
|
+
case
|
104
|
+
when absolute_type_name.interface?
|
105
|
+
env.interface_decls[absolute_type_name].decl
|
106
|
+
when absolute_type_name.alias?
|
107
|
+
env.type_alias_decls[absolute_type_name].decl
|
108
|
+
when absolute_type_name.class?
|
109
|
+
case entry = env.module_class_entry(absolute_type_name)
|
110
|
+
when RBS::Environment::ClassEntry, RBS::Environment::ModuleEntry
|
111
|
+
entry.primary.decl
|
112
|
+
when RBS::Environment::ClassAliasEntry, RBS::Environment::ModuleAliasEntry
|
113
|
+
entry.decl
|
114
|
+
else
|
115
|
+
raise
|
116
|
+
end
|
117
|
+
else
|
118
|
+
raise
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
def comments
|
123
|
+
comments = [] #: Array[RBS::AST::Comment]
|
124
|
+
|
125
|
+
case
|
126
|
+
when absolute_type_name.interface?
|
127
|
+
if comment = env.interface_decls[absolute_type_name].decl.comment
|
128
|
+
comments << comment
|
129
|
+
end
|
130
|
+
when absolute_type_name.alias?
|
131
|
+
if comment = env.type_alias_decls[absolute_type_name].decl.comment
|
132
|
+
comments << comment
|
133
|
+
end
|
134
|
+
when absolute_type_name.class?
|
135
|
+
case entry = env.module_class_entry(absolute_type_name)
|
136
|
+
when RBS::Environment::ClassEntry, RBS::Environment::ModuleEntry
|
137
|
+
entry.decls.each do |decl|
|
138
|
+
if comment = decl.decl.comment
|
139
|
+
comments << comment
|
140
|
+
end
|
141
|
+
end
|
142
|
+
when RBS::Environment::ClassAliasEntry, RBS::Environment::ModuleAliasEntry
|
143
|
+
if comment = entry.decl.comment
|
144
|
+
comments << comment
|
145
|
+
end
|
146
|
+
else
|
147
|
+
raise
|
148
|
+
end
|
149
|
+
else
|
150
|
+
raise
|
151
|
+
end
|
152
|
+
|
153
|
+
comments
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
101
157
|
attr_reader :source_text
|
102
158
|
attr_reader :path
|
103
159
|
attr_reader :subtyping
|
@@ -146,6 +202,39 @@ module Steep
|
|
146
202
|
end
|
147
203
|
end
|
148
204
|
|
205
|
+
if at_comment?(position)
|
206
|
+
node, *parents = source.find_nodes(line: position.line, column: position.column)
|
207
|
+
|
208
|
+
case
|
209
|
+
when node&.type == :assertion
|
210
|
+
# continue
|
211
|
+
node or raise
|
212
|
+
assertion = node.children[1] #: AST::Node::TypeAssertion
|
213
|
+
return items_for_rbs(position: position, buffer: assertion.location.buffer)
|
214
|
+
|
215
|
+
when node && parents && tapp_node = ([node] + parents).find {|n| n.type == :tapp }
|
216
|
+
tapp = tapp_node.children[1] #: AST::Node::TypeApplication
|
217
|
+
type_range = tapp.type_location.range
|
218
|
+
|
219
|
+
if type_range.begin < index && index <= type_range.end
|
220
|
+
return items_for_rbs(position: position, buffer: tapp.location.buffer)
|
221
|
+
end
|
222
|
+
else
|
223
|
+
annotation = source.each_annotation.flat_map {|_, annots| annots }.find do |a|
|
224
|
+
if a.location
|
225
|
+
a.location.start_pos < index && index <= a.location.end_pos
|
226
|
+
end
|
227
|
+
end
|
228
|
+
|
229
|
+
if annotation
|
230
|
+
annotation.location or raise
|
231
|
+
return items_for_rbs(position: position, buffer: annotation.location.buffer)
|
232
|
+
else
|
233
|
+
return []
|
234
|
+
end
|
235
|
+
end
|
236
|
+
end
|
237
|
+
|
149
238
|
Steep.measure "completion item collection" do
|
150
239
|
items_for_trigger(position: position)
|
151
240
|
end
|
@@ -154,9 +243,16 @@ module Steep
|
|
154
243
|
Steep.logger.info "recovering syntax error: #{exn.inspect}"
|
155
244
|
case possible_trigger
|
156
245
|
when "."
|
157
|
-
source_text[index-
|
158
|
-
|
159
|
-
|
246
|
+
if source_text[index-2] == "&"
|
247
|
+
source_text[index-1] = " "
|
248
|
+
source_text[index-2] = " "
|
249
|
+
type_check!(source_text, line: line, column: column)
|
250
|
+
items_for_qcall(position: position)
|
251
|
+
else
|
252
|
+
source_text[index-1] = " "
|
253
|
+
type_check!(source_text, line: line, column: column)
|
254
|
+
items_for_dot(position: position)
|
255
|
+
end
|
160
256
|
when "@"
|
161
257
|
source_text[index-1] = " "
|
162
258
|
type_check!(source_text, line: line, column: column)
|
@@ -189,6 +285,14 @@ module Steep
|
|
189
285
|
end
|
190
286
|
end
|
191
287
|
|
288
|
+
def at_comment?(position)
|
289
|
+
if source.find_comment(line: position.line, column: position.column)
|
290
|
+
true
|
291
|
+
else
|
292
|
+
false
|
293
|
+
end
|
294
|
+
end
|
295
|
+
|
192
296
|
def range_for(position, prefix: "")
|
193
297
|
if prefix.empty?
|
194
298
|
Range.new(start: position, end: position)
|
@@ -232,6 +336,19 @@ module Steep
|
|
232
336
|
|
233
337
|
method_items_for_receiver_type(receiver_type, include_private: false, prefix: prefix, position: position, items: items)
|
234
338
|
|
339
|
+
when node.type == :csend && node.children[0] && at_end?(position, of: (_ = node.loc).selector)
|
340
|
+
# foo&.ba ←
|
341
|
+
receiver_type =
|
342
|
+
case (type = typing.type_of(node: node.children[0]))
|
343
|
+
when AST::Types::Self
|
344
|
+
context.self_type
|
345
|
+
else
|
346
|
+
unwrap_optional(type)
|
347
|
+
end
|
348
|
+
prefix = node.children[1].to_s
|
349
|
+
|
350
|
+
method_items_for_receiver_type(receiver_type, include_private: false, prefix: prefix, position: position, items: items)
|
351
|
+
|
235
352
|
when node.type == :const && node.children[0] == nil && at_end?(position, of: node.loc)
|
236
353
|
# Foo ← (const)
|
237
354
|
prefix = node.children[1].to_s
|
@@ -267,6 +384,18 @@ module Steep
|
|
267
384
|
# foo::← ba
|
268
385
|
items.push(*items_for_colon2(position: position))
|
269
386
|
|
387
|
+
when node.type == :csend && at_end?(position, of: (_ = node.loc).dot)
|
388
|
+
# foo&.← ba
|
389
|
+
receiver_type =
|
390
|
+
case (type = typing.type_of(node: node.children[0]))
|
391
|
+
when AST::Types::Self
|
392
|
+
context.self_type
|
393
|
+
else
|
394
|
+
unwrap_optional(type)
|
395
|
+
end
|
396
|
+
|
397
|
+
method_items_for_receiver_type(receiver_type, include_private: false, prefix: "", position: position, items: items)
|
398
|
+
|
270
399
|
when node.type == :ivar && at_end?(position, of: node.loc)
|
271
400
|
# @fo ←
|
272
401
|
instance_variable_items_for_context(context, position: position, prefix: node.children[0].to_s, items: items)
|
@@ -311,6 +440,36 @@ module Steep
|
|
311
440
|
end
|
312
441
|
end
|
313
442
|
|
443
|
+
def items_for_qcall(position:)
|
444
|
+
# foo&. ←
|
445
|
+
shift_pos = position-2
|
446
|
+
node, *_parents = source.find_nodes(line: shift_pos.line, column: shift_pos.column)
|
447
|
+
node ||= source.node
|
448
|
+
|
449
|
+
return [] unless node
|
450
|
+
|
451
|
+
if at_end?(shift_pos, of: node.loc)
|
452
|
+
begin
|
453
|
+
context = typing.context_at(line: position.line, column: position.column)
|
454
|
+
receiver_type =
|
455
|
+
case (type = typing.type_of(node: node))
|
456
|
+
when AST::Types::Self
|
457
|
+
context.self_type
|
458
|
+
else
|
459
|
+
unwrap_optional(type)
|
460
|
+
end
|
461
|
+
|
462
|
+
items = [] #: Array[item]
|
463
|
+
method_items_for_receiver_type(receiver_type, include_private: false, prefix: "", position: position, items: items)
|
464
|
+
items
|
465
|
+
rescue Typing::UnknownNodeError
|
466
|
+
[]
|
467
|
+
end
|
468
|
+
else
|
469
|
+
[]
|
470
|
+
end
|
471
|
+
end
|
472
|
+
|
314
473
|
def items_for_colon2(position:)
|
315
474
|
# :: ←
|
316
475
|
shift_pos = position-2
|
@@ -350,6 +509,24 @@ module Steep
|
|
350
509
|
items
|
351
510
|
end
|
352
511
|
|
512
|
+
def items_for_rbs(position:, buffer:)
|
513
|
+
items = [] #: Array[item]
|
514
|
+
|
515
|
+
context = typing.context_at(line: position.line, column: position.column)
|
516
|
+
completion = TypeNameCompletion.new(env: context.env, context: context.module_context.nesting, dirs: [])
|
517
|
+
prefix = TypeNameCompletion::Prefix.parse(buffer, line: position.line, column: position.column)
|
518
|
+
|
519
|
+
size = prefix&.size || 0
|
520
|
+
range = Range.new(start: position - size, end: position)
|
521
|
+
|
522
|
+
completion.find_type_names(prefix).each do |name|
|
523
|
+
absolute, relative = completion.resolve_name_in_context(name)
|
524
|
+
items << TypeNameItem.new(relative_type_name: relative, absolute_type_name: absolute, env: context.env, range: range)
|
525
|
+
end
|
526
|
+
|
527
|
+
items
|
528
|
+
end
|
529
|
+
|
353
530
|
def method_items_for_receiver_type(type, include_private:, prefix:, position:, items:)
|
354
531
|
range = range_for(position, prefix: prefix)
|
355
532
|
context = typing.context_at(line: position.line, column: position.column)
|
@@ -485,6 +662,15 @@ module Steep
|
|
485
662
|
# an LSP option
|
486
663
|
name == :initialize
|
487
664
|
end
|
665
|
+
|
666
|
+
def unwrap_optional(type)
|
667
|
+
if type.is_a?(AST::Types::Union) && type.types.include?(AST::Builtin.nil_type)
|
668
|
+
types = type.types.reject { |t| t == AST::Builtin.nil_type }
|
669
|
+
AST::Types::Union.new(types: types, location: type.location)
|
670
|
+
else
|
671
|
+
type
|
672
|
+
end
|
673
|
+
end
|
488
674
|
end
|
489
675
|
end
|
490
676
|
end
|