steep 0.15.0 → 0.16.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/.gitmodules +1 -1
- data/CHANGELOG.md +5 -0
- data/lib/steep/cli.rb +16 -1
- data/lib/steep/drivers/annotations.rb +1 -1
- data/lib/steep/drivers/langserver.rb +13 -462
- data/lib/steep/drivers/utils/driver_helper.rb +1 -1
- data/lib/steep/drivers/watch.rb +97 -85
- data/lib/steep/drivers/worker.rb +51 -0
- data/lib/steep/project/completion_provider.rb +4 -2
- data/lib/steep/project/file.rb +1 -0
- data/lib/steep/project/hover_content.rb +5 -2
- data/lib/steep/project/target.rb +30 -20
- data/lib/steep/project.rb +9 -5
- data/lib/steep/server/base_worker.rb +56 -0
- data/lib/steep/server/code_worker.rb +151 -0
- data/lib/steep/server/interaction_worker.rb +281 -0
- data/lib/steep/server/master.rb +196 -0
- data/lib/steep/server/signature_worker.rb +148 -0
- data/lib/steep/server/utils.rb +36 -0
- data/lib/steep/server/worker_process.rb +62 -0
- data/lib/steep/signature/validator.rb +5 -5
- data/lib/steep/version.rb +1 -1
- data/lib/steep.rb +11 -0
- data/steep.gemspec +1 -1
- data/vendor/ruby-signature/README.md +18 -18
- data/vendor/ruby-signature/Rakefile +90 -15
- data/vendor/ruby-signature/rbs.gemspec +1 -0
- data/vendor/ruby-signature/stdlib/builtin/builtin.rbs +1 -0
- data/vendor/ruby-signature/stdlib/builtin/enumerable.rbs +1 -1
- data/vendor/ruby-signature/stdlib/builtin/module.rbs +2 -2
- data/vendor/ruby-signature/stdlib/json/json.rbs +335 -0
- metadata +14 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b4dda8122216dc9af384ceba2c84f7cb1076df5be7060d2aa32dbaff32140ed6
|
4
|
+
data.tar.gz: d4ce7351acc02b06cd608a10639c00bc8bb1bed8ca81596bb1ed718112392a68
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0bc09bf14d4fbfe8cea15d8f939efd2f9b75672a25fdfbbd19011461001786d15e7d84fadfa37cf67a0303f742c6b2a718855095603119276d1154c4b97cc673
|
7
|
+
data.tar.gz: 7d3d1d4f8acb18de067228fe38d52a7cb62dbd5049555fa748d96226c6ce1906fc49e034f3e19ae346c215ee89a715e04e0138b985cbedcc89b922499adc0a08
|
data/.gitmodules
CHANGED
data/CHANGELOG.md
CHANGED
@@ -2,6 +2,11 @@
|
|
2
2
|
|
3
3
|
## master
|
4
4
|
|
5
|
+
## 0.16.0 (2020-05-19)
|
6
|
+
|
7
|
+
* Spawn workers for type check performance ([#137](https://github.com/soutaro/steep/pull/137))
|
8
|
+
* Fix `check` and `signature` methods in Steepfile ([8f3e4c7](https://github.com/soutaro/steep/pull/137/commits/8f3e4c75b29ac26920f02294be06d6c68dbd4dca))
|
9
|
+
|
5
10
|
## 0.15.0 (2020-05-05)
|
6
11
|
|
7
12
|
* Add type checking configuration to dsl ([#132](https://github.com/soutaro/steep/pull/132))
|
data/lib/steep/cli.rb
CHANGED
@@ -34,7 +34,7 @@ module Steep
|
|
34
34
|
|
35
35
|
def setup_command
|
36
36
|
@command = argv.shift&.to_sym
|
37
|
-
if CLI.available_commands.include?(@command)
|
37
|
+
if CLI.available_commands.include?(@command) || @command == :worker
|
38
38
|
true
|
39
39
|
else
|
40
40
|
stderr.puts "Unknown command: #{command}"
|
@@ -159,5 +159,20 @@ module Steep
|
|
159
159
|
stdout.puts Steep::VERSION
|
160
160
|
0
|
161
161
|
end
|
162
|
+
|
163
|
+
def process_worker
|
164
|
+
Drivers::Worker.new(stdout: stdout, stderr: stderr, stdin: stdin).tap do |command|
|
165
|
+
OptionParser.new do |opts|
|
166
|
+
opts.banner = "Usage: steep worker [options] [dir]"
|
167
|
+
handle_logging_options opts
|
168
|
+
|
169
|
+
opts.on("--interaction") { command.worker_type = :interaction }
|
170
|
+
opts.on("--code") { command.worker_type = :code }
|
171
|
+
opts.on("--signature") { command.worker_type = :signature }
|
172
|
+
opts.on("--steepfile=PATH") {|path| command.steepfile = Pathname(path) }
|
173
|
+
opts.on("--name=NAME") {|name| command.worker_name = name }
|
174
|
+
end.parse!(argv)
|
175
|
+
end.run
|
176
|
+
end
|
162
177
|
end
|
163
178
|
end
|
@@ -25,7 +25,7 @@ module Steep
|
|
25
25
|
|
26
26
|
project.targets.each do |target|
|
27
27
|
Steep.logger.tagged "target=#{target.name}" do
|
28
|
-
target.load_signatures do |_, subtyping, _|
|
28
|
+
target.load_signatures(validate: false) do |_, subtyping, _|
|
29
29
|
case (status = target.status)
|
30
30
|
when nil # status set on error cases
|
31
31
|
target.source_files.each_value do |file|
|
@@ -33,11 +33,6 @@ module Steep
|
|
33
33
|
@project or raise "Empty #project"
|
34
34
|
end
|
35
35
|
|
36
|
-
def enqueue_type_check(version)
|
37
|
-
@latest_update_version = version
|
38
|
-
type_check_queue << TypeCheckRequest.new(version: version)
|
39
|
-
end
|
40
|
-
|
41
36
|
def run
|
42
37
|
@project = load_config()
|
43
38
|
|
@@ -45,466 +40,22 @@ module Steep
|
|
45
40
|
loader.load_sources([])
|
46
41
|
loader.load_signatures()
|
47
42
|
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
end
|
60
|
-
end
|
61
|
-
end
|
62
|
-
end
|
63
|
-
|
64
|
-
0
|
65
|
-
end
|
66
|
-
|
67
|
-
def write(method:, params:)
|
68
|
-
write_mutex.synchronize do
|
69
|
-
Steep.logger.debug { "Sending request: method=#{method}, params=#{params.to_json}"}
|
70
|
-
writer.write(method: method, params: params)
|
71
|
-
end
|
72
|
-
end
|
73
|
-
|
74
|
-
def handle_request(request)
|
75
|
-
id = request[:id]
|
76
|
-
method = request[:method].to_sym
|
77
|
-
|
78
|
-
Steep.logger.tagged "id=#{id}, method=#{method}" do
|
79
|
-
case method
|
80
|
-
when :initialize
|
81
|
-
yield id, LanguageServer::Protocol::Interface::InitializeResult.new(
|
82
|
-
capabilities: LanguageServer::Protocol::Interface::ServerCapabilities.new(
|
83
|
-
text_document_sync: LanguageServer::Protocol::Interface::TextDocumentSyncOptions.new(
|
84
|
-
change: LanguageServer::Protocol::Constant::TextDocumentSyncKind::FULL
|
85
|
-
),
|
86
|
-
hover_provider: true,
|
87
|
-
completion_provider: LanguageServer::Protocol::Interface::CompletionOptions.new(
|
88
|
-
trigger_characters: [".", "@"],
|
89
|
-
)
|
90
|
-
)
|
91
|
-
)
|
92
|
-
|
93
|
-
enqueue_type_check nil
|
94
|
-
|
95
|
-
when :"textDocument/completion"
|
96
|
-
Steep.logger.error request.inspect
|
97
|
-
begin
|
98
|
-
params = request[:params]
|
99
|
-
uri = URI.parse(params[:textDocument][:uri])
|
100
|
-
path = project.relative_path(Pathname(uri.path))
|
101
|
-
target = project.targets.find {|target| target.source_file?(path) }
|
102
|
-
case (status = target&.status)
|
103
|
-
when Project::Target::TypeCheckStatus
|
104
|
-
subtyping = status.subtyping
|
105
|
-
source = target.source_files[path]
|
106
|
-
|
107
|
-
line, column = params[:position].yield_self {|hash| [hash[:line]+1, hash[:character]] }
|
108
|
-
trigger = params[:context][:triggerCharacter]
|
109
|
-
|
110
|
-
Steep.logger.error "line: #{line}, column: #{column}, trigger: #{trigger}"
|
111
|
-
|
112
|
-
provider = Project::CompletionProvider.new(source_text: source.content, path: path, subtyping: subtyping)
|
113
|
-
items = begin
|
114
|
-
provider.run(line: line, column: column)
|
115
|
-
rescue Parser::SyntaxError
|
116
|
-
[]
|
117
|
-
end
|
118
|
-
|
119
|
-
completion_items = items.map do |item|
|
120
|
-
format_completion_item(item)
|
121
|
-
end
|
122
|
-
|
123
|
-
Steep.logger.debug "items = #{completion_items.inspect}"
|
124
|
-
|
125
|
-
yield id, LanguageServer::Protocol::Interface::CompletionList.new(
|
126
|
-
is_incomplete: false,
|
127
|
-
items: completion_items
|
128
|
-
)
|
129
|
-
end
|
130
|
-
|
131
|
-
rescue Typing::UnknownNodeError => exn
|
132
|
-
Steep.log_error exn, message: "Failed to compute completion: #{exn.inspect}"
|
133
|
-
yield id, nil
|
134
|
-
end
|
135
|
-
|
136
|
-
when :"textDocument/didChange"
|
137
|
-
uri = URI.parse(request[:params][:textDocument][:uri])
|
138
|
-
path = project.relative_path(Pathname(uri.path))
|
139
|
-
text = request[:params][:contentChanges][0][:text]
|
140
|
-
|
141
|
-
Steep.logger.debug { "path=#{path}, content=#{text.lines.first&.chomp}..." }
|
142
|
-
|
143
|
-
project.targets.each do |target|
|
144
|
-
Steep.logger.tagged "target=#{target.name}" do
|
145
|
-
case
|
146
|
-
when target.source_file?(path)
|
147
|
-
if text.empty? && !path.file?
|
148
|
-
Steep.logger.info { "Deleting source file: #{path}..." }
|
149
|
-
target.remove_source(path)
|
150
|
-
report_diagnostics path, []
|
151
|
-
else
|
152
|
-
Steep.logger.info { "Updating source file: #{path}..." }
|
153
|
-
target.update_source(path, text)
|
154
|
-
end
|
155
|
-
when target.possible_source_file?(path)
|
156
|
-
Steep.logger.info { "Adding source file: #{path}..." }
|
157
|
-
target.add_source(path, text)
|
158
|
-
when target.signature_file?(path)
|
159
|
-
if text.empty? && !path.file?
|
160
|
-
Steep.logger.info { "Deleting signature file: #{path}..." }
|
161
|
-
target.remove_signature(path)
|
162
|
-
report_diagnostics path, []
|
163
|
-
else
|
164
|
-
Steep.logger.info { "Updating signature file: #{path}..." }
|
165
|
-
target.update_signature(path, text)
|
166
|
-
end
|
167
|
-
when target.possible_signature_file?(path)
|
168
|
-
Steep.logger.info { "Adding signature file: #{path}..." }
|
169
|
-
target.add_signature(path, text)
|
170
|
-
end
|
171
|
-
end
|
172
|
-
end
|
173
|
-
|
174
|
-
version = request[:params][:textDocument][:version]
|
175
|
-
enqueue_type_check version
|
176
|
-
when :"textDocument/hover"
|
177
|
-
uri = URI.parse(request[:params][:textDocument][:uri])
|
178
|
-
path = project.relative_path(Pathname(uri.path))
|
179
|
-
line = request[:params][:position][:line]
|
180
|
-
column = request[:params][:position][:character]
|
181
|
-
|
182
|
-
yield id, response_to_hover(path: path, line: line, column: column)
|
183
|
-
|
184
|
-
when :shutdown
|
185
|
-
yield id, nil
|
186
|
-
|
187
|
-
when :exit
|
188
|
-
type_check_queue << nil
|
189
|
-
type_check_thread.join
|
190
|
-
exit
|
191
|
-
end
|
192
|
-
end
|
193
|
-
end
|
194
|
-
|
195
|
-
def start_type_check
|
196
|
-
@type_check_thread = Thread.start do
|
197
|
-
while request = type_check_queue.deq
|
198
|
-
if @latest_update_version == nil || @latest_update_version == request.version
|
199
|
-
begin
|
200
|
-
run_type_check()
|
201
|
-
rescue => exn
|
202
|
-
Steep.log_error exn
|
203
|
-
end
|
204
|
-
end
|
205
|
-
end
|
206
|
-
end
|
207
|
-
end
|
208
|
-
|
209
|
-
def run_type_check()
|
210
|
-
Steep.logger.tagged "#run_type_check" do
|
211
|
-
Steep.logger.info { "Running type check..." }
|
212
|
-
type_check project
|
213
|
-
|
214
|
-
Steep.logger.info { "Sending diagnostics..." }
|
215
|
-
project.targets.each do |target|
|
216
|
-
Steep.logger.tagged "target=#{target.name}, status=#{target.status.class}" do
|
217
|
-
Steep.logger.info { "Clearing signature diagnostics..." }
|
218
|
-
target.signature_files.each_value do |file|
|
219
|
-
report_diagnostics file.path, []
|
220
|
-
end
|
221
|
-
|
222
|
-
case (status = target.status)
|
223
|
-
when Project::Target::SignatureValidationErrorStatus
|
224
|
-
Steep.logger.info { "Signature validation error" }
|
225
|
-
status.errors.group_by(&:path).each do |path, errors|
|
226
|
-
diagnostics = errors.map {|error| diagnostic_for_validation_error(error) }
|
227
|
-
report_diagnostics path, diagnostics
|
228
|
-
end
|
229
|
-
when Project::Target::TypeCheckStatus
|
230
|
-
Steep.logger.info { "Type check" }
|
231
|
-
status.type_check_sources.each do |source|
|
232
|
-
diagnostics = case source.status
|
233
|
-
when Project::SourceFile::TypeCheckStatus
|
234
|
-
source.errors.map {|error| diagnostic_for_type_error(error) }
|
235
|
-
when Project::SourceFile::AnnotationSyntaxErrorStatus
|
236
|
-
[diagnostics_raw(source.status.error.message, source.status.location)]
|
237
|
-
when Project::SourceFile::ParseErrorStatus
|
238
|
-
[]
|
239
|
-
when Project::SourceFile::TypeCheckErrorStatus
|
240
|
-
Steep.log_error source.status.error
|
241
|
-
[]
|
242
|
-
end
|
243
|
-
|
244
|
-
if diagnostics
|
245
|
-
report_diagnostics source.path, diagnostics
|
246
|
-
end
|
247
|
-
end
|
248
|
-
when Project::Target::SignatureSyntaxErrorStatus
|
249
|
-
Steep.logger.info { "Signature syntax error" }
|
250
|
-
end
|
251
|
-
end
|
252
|
-
end
|
253
|
-
end
|
254
|
-
end
|
255
|
-
|
256
|
-
def report_diagnostics(path, diagnostics)
|
257
|
-
Steep.logger.info { "Reporting #{diagnostics.size} diagnostics for #{path}..." }
|
258
|
-
write(
|
259
|
-
method: :"textDocument/publishDiagnostics",
|
260
|
-
params: LanguageServer::Protocol::Interface::PublishDiagnosticsParams.new(
|
261
|
-
uri: URI.parse(project.absolute_path(path).to_s).tap {|uri| uri.scheme = "file"},
|
262
|
-
diagnostics: diagnostics,
|
263
|
-
)
|
264
|
-
)
|
265
|
-
end
|
266
|
-
|
267
|
-
def diagnostic_for_validation_error(error)
|
268
|
-
LanguageServer::Protocol::Interface::Diagnostic.new(
|
269
|
-
message: StringIO.new("").tap {|io| error.puts(io) }.string,
|
270
|
-
severity: LanguageServer::Protocol::Constant::DiagnosticSeverity::ERROR,
|
271
|
-
range: LanguageServer::Protocol::Interface::Range.new(
|
272
|
-
start: LanguageServer::Protocol::Interface::Position.new(
|
273
|
-
line: error.location.start_line - 1,
|
274
|
-
character: error.location.start_column,
|
275
|
-
),
|
276
|
-
end: LanguageServer::Protocol::Interface::Position.new(
|
277
|
-
line: error.location.end_line - 1,
|
278
|
-
character: error.location.end_column,
|
279
|
-
),
|
280
|
-
)
|
281
|
-
)
|
282
|
-
end
|
283
|
-
|
284
|
-
def diagnostics_raw(message, loc)
|
285
|
-
LanguageServer::Protocol::Interface::Diagnostic.new(
|
286
|
-
message: message,
|
287
|
-
severity: LanguageServer::Protocol::Constant::DiagnosticSeverity::ERROR,
|
288
|
-
range: LanguageServer::Protocol::Interface::Range.new(
|
289
|
-
start: LanguageServer::Protocol::Interface::Position.new(
|
290
|
-
line: loc.start_line - 1,
|
291
|
-
character: loc.start_column,
|
292
|
-
),
|
293
|
-
end: LanguageServer::Protocol::Interface::Position.new(
|
294
|
-
line: loc.end_line - 1,
|
295
|
-
character: loc.end_column,
|
296
|
-
),
|
297
|
-
)
|
298
|
-
)
|
299
|
-
end
|
300
|
-
|
301
|
-
def diagnostic_for_type_error(error)
|
302
|
-
LanguageServer::Protocol::Interface::Diagnostic.new(
|
303
|
-
message: error.to_s,
|
304
|
-
severity: LanguageServer::Protocol::Constant::DiagnosticSeverity::ERROR,
|
305
|
-
range: LanguageServer::Protocol::Interface::Range.new(
|
306
|
-
start: LanguageServer::Protocol::Interface::Position.new(
|
307
|
-
line: error.node.loc.line - 1,
|
308
|
-
character: error.node.loc.column,
|
309
|
-
),
|
310
|
-
end: LanguageServer::Protocol::Interface::Position.new(
|
311
|
-
line: error.node.loc.last_line - 1,
|
312
|
-
character: error.node.loc.last_column,
|
313
|
-
),
|
314
|
-
)
|
43
|
+
interaction_worker = Server::WorkerProcess.spawn_worker(:interaction, name: "interaction", steepfile: project.steepfile_path)
|
44
|
+
signature_worker = Server::WorkerProcess.spawn_worker(:signature, name: "signature", steepfile: project.steepfile_path)
|
45
|
+
code_workers = Server::WorkerProcess.spawn_code_workers(steepfile: project.steepfile_path)
|
46
|
+
|
47
|
+
master = Server::Master.new(
|
48
|
+
project: project,
|
49
|
+
reader: reader,
|
50
|
+
writer: writer,
|
51
|
+
interaction_worker: interaction_worker,
|
52
|
+
signature_worker: signature_worker,
|
53
|
+
code_workers: code_workers
|
315
54
|
)
|
316
|
-
end
|
317
|
-
|
318
|
-
def response_to_hover(path:, line:, column:)
|
319
|
-
Steep.logger.info { "path=#{path}, line=#{line}, column=#{column}" }
|
320
|
-
|
321
|
-
hover = Project::HoverContent.new(project: project)
|
322
|
-
content = hover.content_for(path: path, line: line+1, column: column+1)
|
323
|
-
if content
|
324
|
-
range = content.location.yield_self do |location|
|
325
|
-
start_position = { line: location.line - 1, character: location.column }
|
326
|
-
end_position = { line: location.last_line - 1, character: location.last_column }
|
327
|
-
{ start: start_position, end: end_position }
|
328
|
-
end
|
329
55
|
|
330
|
-
|
331
|
-
contents: { kind: "markdown", value: format_hover(content) },
|
332
|
-
range: range
|
333
|
-
)
|
334
|
-
end
|
335
|
-
rescue Typing::UnknownNodeError => exn
|
336
|
-
Steep.log_error exn, message: "Failed to compute hover: #{exn.inspect}"
|
337
|
-
nil
|
338
|
-
end
|
339
|
-
|
340
|
-
def format_hover(content)
|
341
|
-
case content
|
342
|
-
when Project::HoverContent::VariableContent
|
343
|
-
"`#{content.name}`: `#{content.type.to_s}`"
|
344
|
-
when Project::HoverContent::MethodCallContent
|
345
|
-
method_name = case content.method_name
|
346
|
-
when Project::HoverContent::InstanceMethodName
|
347
|
-
"#{content.method_name.class_name}##{content.method_name.method_name}"
|
348
|
-
when Project::HoverContent::SingletonMethodName
|
349
|
-
"#{content.method_name.class_name}.#{content.method_name.method_name}"
|
350
|
-
else
|
351
|
-
nil
|
352
|
-
end
|
353
|
-
|
354
|
-
if method_name
|
355
|
-
string = <<HOVER
|
356
|
-
```
|
357
|
-
#{method_name} ~> #{content.type}
|
358
|
-
```
|
359
|
-
HOVER
|
360
|
-
if content.definition
|
361
|
-
if content.definition.comment
|
362
|
-
string << "\n----\n\n#{content.definition.comment.string}"
|
363
|
-
end
|
364
|
-
|
365
|
-
string << "\n----\n\n#{content.definition.method_types.map {|x| "- `#{x}`\n" }.join()}"
|
366
|
-
end
|
367
|
-
else
|
368
|
-
"`#{content.type}`"
|
369
|
-
end
|
370
|
-
when Project::HoverContent::DefinitionContent
|
371
|
-
string = <<HOVER
|
372
|
-
```
|
373
|
-
def #{content.method_name}: #{content.method_type}
|
374
|
-
```
|
375
|
-
HOVER
|
376
|
-
if (comment = content.definition.comment)
|
377
|
-
string << "\n----\n\n#{comment.string}\n"
|
378
|
-
end
|
379
|
-
|
380
|
-
if content.definition.method_types.size > 1
|
381
|
-
string << "\n----\n\n#{content.definition.method_types.map {|x| "- `#{x}`\n" }.join()}"
|
382
|
-
end
|
383
|
-
|
384
|
-
string
|
385
|
-
when Project::HoverContent::TypeContent
|
386
|
-
"`#{content.type}`"
|
387
|
-
end
|
388
|
-
end
|
389
|
-
|
390
|
-
def format_completion_item(item)
|
391
|
-
range = LanguageServer::Protocol::Interface::Range.new(
|
392
|
-
start: LanguageServer::Protocol::Interface::Position.new(
|
393
|
-
line: item.range.start.line-1,
|
394
|
-
character: item.range.start.column
|
395
|
-
),
|
396
|
-
end: LanguageServer::Protocol::Interface::Position.new(
|
397
|
-
line: item.range.end.line-1,
|
398
|
-
character: item.range.end.column
|
399
|
-
)
|
400
|
-
)
|
56
|
+
master.start()
|
401
57
|
|
402
|
-
|
403
|
-
when Project::CompletionProvider::LocalVariableItem
|
404
|
-
LanguageServer::Protocol::Interface::CompletionItem.new(
|
405
|
-
label: item.identifier,
|
406
|
-
kind: LanguageServer::Protocol::Constant::CompletionItemKind::VARIABLE,
|
407
|
-
detail: "#{item.identifier}: #{item.type}",
|
408
|
-
text_edit: LanguageServer::Protocol::Interface::TextEdit.new(
|
409
|
-
range: range,
|
410
|
-
new_text: "#{item.identifier}"
|
411
|
-
)
|
412
|
-
)
|
413
|
-
when Project::CompletionProvider::MethodNameItem
|
414
|
-
label = "def #{item.identifier}: #{item.method_type}"
|
415
|
-
method_type_snippet = method_type_to_snippet(item.method_type)
|
416
|
-
LanguageServer::Protocol::Interface::CompletionItem.new(
|
417
|
-
label: label,
|
418
|
-
kind: LanguageServer::Protocol::Constant::CompletionItemKind::METHOD,
|
419
|
-
text_edit: LanguageServer::Protocol::Interface::TextEdit.new(
|
420
|
-
new_text: "#{item.identifier}#{method_type_snippet}",
|
421
|
-
range: range
|
422
|
-
),
|
423
|
-
documentation: item.definition.comment&.string,
|
424
|
-
insert_text_format: LanguageServer::Protocol::Constant::InsertTextFormat::SNIPPET
|
425
|
-
)
|
426
|
-
when Project::CompletionProvider::InstanceVariableItem
|
427
|
-
label = "#{item.identifier}: #{item.type}"
|
428
|
-
LanguageServer::Protocol::Interface::CompletionItem.new(
|
429
|
-
label: label,
|
430
|
-
kind: LanguageServer::Protocol::Constant::CompletionItemKind::FIELD,
|
431
|
-
text_edit: LanguageServer::Protocol::Interface::TextEdit.new(
|
432
|
-
range: range,
|
433
|
-
new_text: item.identifier,
|
434
|
-
),
|
435
|
-
insert_text_format: LanguageServer::Protocol::Constant::InsertTextFormat::SNIPPET
|
436
|
-
)
|
437
|
-
end
|
438
|
-
end
|
439
|
-
|
440
|
-
def method_type_to_snippet(method_type)
|
441
|
-
params = if method_type.type.each_param.count == 0
|
442
|
-
""
|
443
|
-
else
|
444
|
-
"(#{params_to_snippet(method_type.type)})"
|
445
|
-
end
|
446
|
-
|
447
|
-
|
448
|
-
block = if method_type.block
|
449
|
-
open, space, close = if method_type.block.type.return_type.is_a?(RBS::Types::Bases::Void)
|
450
|
-
["do", " ", "end"]
|
451
|
-
else
|
452
|
-
["{", "", "}"]
|
453
|
-
end
|
454
|
-
|
455
|
-
if method_type.block.type.each_param.count == 0
|
456
|
-
" #{open} $0 #{close}"
|
457
|
-
else
|
458
|
-
" #{open}#{space}|#{params_to_snippet(method_type.block.type)}| $0 #{close}"
|
459
|
-
end
|
460
|
-
else
|
461
|
-
""
|
462
|
-
end
|
463
|
-
|
464
|
-
"#{params}#{block}"
|
465
|
-
end
|
466
|
-
|
467
|
-
def params_to_snippet(fun)
|
468
|
-
params = []
|
469
|
-
|
470
|
-
index = 1
|
471
|
-
|
472
|
-
fun.required_positionals.each do |param|
|
473
|
-
if name = param.name
|
474
|
-
params << "${#{index}:#{param.type}}"
|
475
|
-
else
|
476
|
-
params << "${#{index}:#{param.type}}"
|
477
|
-
end
|
478
|
-
|
479
|
-
index += 1
|
480
|
-
end
|
481
|
-
|
482
|
-
if fun.rest_positionals
|
483
|
-
params << "${#{index}:*#{fun.rest_positionals.type}}"
|
484
|
-
index += 1
|
485
|
-
end
|
486
|
-
|
487
|
-
fun.trailing_positionals.each do |param|
|
488
|
-
if name = param.name
|
489
|
-
params << "${#{index}:#{param.type}}"
|
490
|
-
else
|
491
|
-
params << "${#{index}:#{param.type}}"
|
492
|
-
end
|
493
|
-
|
494
|
-
index += 1
|
495
|
-
end
|
496
|
-
|
497
|
-
fun.required_keywords.each do |keyword, param|
|
498
|
-
if name = param.name
|
499
|
-
params << "#{keyword}: ${#{index}:#{name}_}"
|
500
|
-
else
|
501
|
-
params << "#{keyword}: ${#{index}:#{param.type}_}"
|
502
|
-
end
|
503
|
-
|
504
|
-
index += 1
|
505
|
-
end
|
506
|
-
|
507
|
-
params.join(", ")
|
58
|
+
0
|
508
59
|
end
|
509
60
|
end
|
510
61
|
end
|
@@ -8,7 +8,7 @@ module Steep
|
|
8
8
|
raise "Cannot find a configuration at #{path}: `steep init` to scaffold" unless path.file?
|
9
9
|
|
10
10
|
steep_file_path = path.absolute? ? path : Pathname.pwd + path
|
11
|
-
Project.new(
|
11
|
+
Project.new(steepfile_path: steep_file_path).tap do |project|
|
12
12
|
Project::DSL.parse(project, path.read, filename: path.to_s)
|
13
13
|
end
|
14
14
|
end
|