steep 1.4.0.dev.3 → 1.4.0.dev.4

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ef7faa0702c27679ca29580b02273241fcfac188f2462f79a95ea26e633a231d
4
- data.tar.gz: b9a7add36c30c5fcb76b89bb5a994fcea4e8749ddb06b9b43d5ebcada4fa51f6
3
+ metadata.gz: 0c5431b7816a655799dcfc5ab49aff4d630062176b52b14f377b4d6ca754674f
4
+ data.tar.gz: ea016b12eac32d93fffcbb315009aeb143626fd831669b36ade6c7d01b55a475
5
5
  SHA512:
6
- metadata.gz: f5b67c4723ec0aec87a215eb874f73ebc62de658b50cc4118399691f9451d0d540ea4640623d94771430839a40399097da2310c98f40e6c50669ceba8d1de026
7
- data.tar.gz: d6da7929577c2071c43b6c13ca28b2b0017626ffb760618b2a5551d1824c1c0ba3cbad6c915c522ea1d784caa4bd13ac5364e052972a4573a717c72fd029528d
6
+ metadata.gz: a6e97f6c64d6e5dfc86a0d28e6129b1fe66aa75e1b28290092c47b12dda165fc9ce87187f8f27358cef169d2a3a2b3eb4eae42aa4702dd11d9586aad8d7733e2
7
+ data.tar.gz: 94f611f5db76c09c853af7f5a333d43a0650e21fadde356990acb447231a86eb18bc3b63aa1ed1ead1c6d39066427eedf14f7379932dc077a1b4f9446184e749
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- steep (1.4.0.dev.3)
4
+ steep (1.4.0.dev.4)
5
5
  activesupport (>= 5.1)
6
6
  csv (>= 3.0.9)
7
7
  fileutils (>= 1.1.0)
@@ -46,7 +46,7 @@ GEM
46
46
  minitest (> 5.3)
47
47
  minitest-slow_test (0.2.0)
48
48
  minitest (>= 5.0)
49
- parallel (1.22.1)
49
+ parallel (1.23.0)
50
50
  parser (3.2.2.0)
51
51
  ast (~> 2.4.1)
52
52
  rainbow (3.1.1)
@@ -58,7 +58,7 @@ GEM
58
58
  ruby-debug-ide (0.7.3)
59
59
  rake (>= 0.8.1)
60
60
  securerandom (0.2.2)
61
- stackprof (0.2.23)
61
+ stackprof (0.2.25)
62
62
  strscan (3.0.6)
63
63
  terminal-table (3.0.2)
64
64
  unicode-display_width (>= 1.1.1, < 3)
data/Gemfile.steep.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  GEM
2
2
  remote: https://rubygems.org/
3
3
  specs:
4
- activesupport (7.0.4.2)
4
+ activesupport (7.0.4.3)
5
5
  concurrent-ruby (~> 1.0, >= 1.0.2)
6
6
  i18n (>= 1.6, < 2)
7
7
  minitest (>= 5.1)
@@ -10,7 +10,7 @@ GEM
10
10
  concurrent-ruby (1.2.2)
11
11
  csv (3.2.6)
12
12
  ffi (1.15.5)
13
- fileutils (1.7.0)
13
+ fileutils (1.7.1)
14
14
  i18n (1.12.0)
15
15
  concurrent-ruby (~> 1.0)
16
16
  json (2.6.3)
@@ -19,18 +19,17 @@ GEM
19
19
  rb-fsevent (~> 0.10, >= 0.10.3)
20
20
  rb-inotify (~> 0.9, >= 0.9.10)
21
21
  logger (1.5.3)
22
- minitest (5.17.0)
22
+ minitest (5.18.0)
23
23
  parallel (1.22.1)
24
- parser (3.2.1.0)
24
+ parser (3.2.2.0)
25
25
  ast (~> 2.4.1)
26
- pathname (0.2.1)
27
26
  rainbow (3.1.1)
28
27
  rb-fsevent (0.11.2)
29
28
  rb-inotify (0.10.1)
30
29
  ffi (~> 1.0)
31
30
  rbs (3.0.4)
32
31
  securerandom (0.2.2)
33
- steep (1.4.0.dev.2)
32
+ steep (1.4.0.dev.3)
34
33
  activesupport (>= 5.1)
35
34
  csv (>= 3.0.9)
36
35
  fileutils (>= 1.1.0)
@@ -40,7 +39,6 @@ GEM
40
39
  logger (>= 1.3.0)
41
40
  parallel (>= 1.0.0)
42
41
  parser (>= 3.1)
43
- pathname (>= 0.2.1)
44
42
  rainbow (>= 2.2.2, < 4.0)
45
43
  rbs (>= 2.8.0)
46
44
  securerandom (>= 0.1)
@@ -914,8 +914,7 @@ module Steep
914
914
  end
915
915
 
916
916
  def self.all_error
917
- @all_error ||= ALL.each.with_object({}) do |klass, hash|
918
- # @type var hash: Hash[singleton(Base), LSPFormatter::severity]
917
+ @all_error ||= ALL.each.with_object({}) do |klass, hash| #$ Hash[singleton(Base), LSPFormatter::severity]
919
918
  hash[klass] = LSPFormatter::ERROR
920
919
  end.freeze
921
920
  end
@@ -373,15 +373,15 @@ module Steep
373
373
  types1 = shape1.methods[name]&.method_types or raise
374
374
  types2 = shape2.methods[name]&.method_types or raise
375
375
 
376
- if types1 == types2
376
+ if types1 == types2 && types1.map {|type| type.method_decls.to_a }.to_set == types2.map {|type| type.method_decls.to_a }.to_set
377
377
  shape.methods[name] = (shape1.methods[name] or raise)
378
378
  else
379
- method_types = {}
379
+ method_types = {} #: Hash[MethodType, true]
380
380
 
381
381
  types1.each do |type1|
382
382
  types2.each do |type2|
383
383
  if type1 == type2
384
- method_types[type1] = true
384
+ method_types[type1.with(method_decls: type1.method_decls + type2.method_decls)] = true
385
385
  else
386
386
  if type = MethodType.union(type1, type2, subtyping)
387
387
  method_types[type] = true
@@ -4,6 +4,10 @@ module Steep
4
4
  def to_s
5
5
  "#{type_name}##{method_name}"
6
6
  end
7
+
8
+ def relative
9
+ InstanceMethodName.new(type_name: type_name.relative!, method_name: method_name)
10
+ end
7
11
  end
8
12
 
9
13
  SingletonMethodName = _ = Struct.new(:type_name, :method_name, keyword_init: true) do
@@ -11,6 +15,10 @@ module Steep
11
15
  def to_s
12
16
  "#{type_name}.#{method_name}"
13
17
  end
18
+
19
+ def relative
20
+ SingletonMethodName.new(type_name: type_name.relative!, method_name: method_name)
21
+ end
14
22
  end
15
23
 
16
24
  class ::Object
@@ -6,6 +6,7 @@ module Steep
6
6
  ApplyChangeJob = _ = Class.new()
7
7
  HoverJob = _ = Struct.new(:id, :path, :line, :column, keyword_init: true)
8
8
  CompletionJob = _ = Struct.new(:id, :path, :line, :column, :trigger, keyword_init: true)
9
+ SignatureHelpJob = _ = Struct.new(:id, :path, :line, :column, keyword_init: true)
9
10
 
10
11
  LSP = LanguageServer::Protocol
11
12
 
@@ -35,6 +36,8 @@ module Steep
35
36
  writer.write({ id: job.id, result: process_hover(job) })
36
37
  when CompletionJob
37
38
  writer.write({ id: job.id, result: process_completion(job) })
39
+ when SignatureHelpJob
40
+ writer.write({ id: job.id, result: process_signature_help(job) })
38
41
  end
39
42
  end
40
43
  end
@@ -53,7 +56,7 @@ module Steep
53
56
  when "textDocument/hover"
54
57
  id = request[:id]
55
58
 
56
- path = project.relative_path(Steep::PathHelper.to_pathname!(request[:params][:textDocument][:uri]))
59
+ path = project.relative_path(PathHelper.to_pathname!(request[:params][:textDocument][:uri]))
57
60
  line = request[:params][:position][:line]+1
58
61
  column = request[:params][:position][:character]
59
62
 
@@ -64,11 +67,18 @@ module Steep
64
67
 
65
68
  params = request[:params]
66
69
 
67
- path = project.relative_path(Steep::PathHelper.to_pathname!(params[:textDocument][:uri]))
70
+ path = project.relative_path(PathHelper.to_pathname!(params[:textDocument][:uri]))
68
71
  line, column = params[:position].yield_self {|hash| [hash[:line]+1, hash[:character]] }
69
72
  trigger = params.dig(:context, :triggerCharacter)
70
73
 
71
74
  queue << CompletionJob.new(id: id, path: path, line: line, column: column, trigger: trigger)
75
+ when "textDocument/signatureHelp"
76
+ id = request[:id]
77
+ params = request[:params]
78
+ path = project.relative_path(PathHelper.to_pathname!(params[:textDocument][:uri]))
79
+ line, column = params[:position].yield_self {|hash| [hash[:line]+1, hash[:character]] }
80
+
81
+ queue << SignatureHelpJob.new(id: id, path: path, line: line, column: column)
72
82
  end
73
83
  end
74
84
 
@@ -81,16 +91,13 @@ module Steep
81
91
  if content
82
92
  range = content.location.yield_self do |location|
83
93
  lsp_range = location.as_lsp_range
84
- start_position = { line: lsp_range[:start][:line], character: lsp_range[:start][:character] }
85
- end_position = { line: lsp_range[:end][:line], character: lsp_range[:end][:character] }
86
- { start: start_position, end: end_position }
94
+ start_position = LSP::Interface::Position.new(line: lsp_range[:start][:line], character: lsp_range[:start][:character])
95
+ end_position = LSP::Interface::Position.new(line: lsp_range[:end][:line], character: lsp_range[:end][:character])
96
+ LSP::Interface::Range.new(start: start_position, end: end_position)
87
97
  end
88
98
 
89
99
  LSP::Interface::Hover.new(
90
- contents: {
91
- kind: "markdown",
92
- value: LSPFormatter.format_hover_content(content).to_s
93
- },
100
+ contents: LSP::Interface::MarkupContent.new(kind: "markdown", value: LSPFormatter.format_hover_content(content).to_s),
94
101
  range: range
95
102
  )
96
103
  end
@@ -136,7 +143,7 @@ module Steep
136
143
  context = nil #: RBS::Resolver::context
137
144
 
138
145
  case sig_service.status
139
- when Steep::Services::SignatureService::SyntaxErrorStatus, Steep::Services::SignatureService::AncestorErrorStatus
146
+ when Services::SignatureService::SyntaxErrorStatus, Services::SignatureService::AncestorErrorStatus
140
147
 
141
148
  if buffer = sig_service.latest_env.buffers.find {|buf| Pathname(buf.name) == Pathname(relative_path) }
142
149
  dirs = sig_service.latest_env.signatures[buffer][0]
@@ -172,23 +179,22 @@ module Steep
172
179
  type_names = completion.find_type_names(prefix)
173
180
  prefix_size = prefix ? prefix.size : 0
174
181
 
175
- completion_items = type_names.map {|type_name|
182
+ completion_items = type_names.map do |type_name|
176
183
  absolute_name, relative_name = completion.resolve_name_in_context(type_name)
177
-
178
184
  format_completion_item_for_rbs(sig_service, absolute_name, job, relative_name.to_s, prefix_size)
179
- }
185
+ end
180
186
 
181
187
  ["untyped", "void", "bool", "class", "module", "instance", "nil"].each do |name|
182
- completion_items << LanguageServer::Protocol::Interface::CompletionItem.new(
188
+ completion_items << LSP::Interface::CompletionItem.new(
183
189
  label: name,
184
190
  detail: "(builtin type)",
185
- text_edit: LanguageServer::Protocol::Interface::TextEdit.new(
186
- range: LanguageServer::Protocol::Interface::Range.new(
187
- start: LanguageServer::Protocol::Interface::Position.new(
191
+ text_edit: LSP::Interface::TextEdit.new(
192
+ range: LSP::Interface::Range.new(
193
+ start: LSP::Interface::Position.new(
188
194
  line: job.line - 1,
189
195
  character: job.column - prefix_size
190
196
  ),
191
- end: LanguageServer::Protocol::Interface::Position.new(
197
+ end: LSP::Interface::Position.new(
192
198
  line: job.line - 1,
193
199
  character: job.column
194
200
  )
@@ -211,12 +217,12 @@ module Steep
211
217
  end
212
218
 
213
219
  def format_completion_item_for_rbs(sig_service, type_name, job, complete_text, prefix_size)
214
- range = LanguageServer::Protocol::Interface::Range.new(
215
- start: LanguageServer::Protocol::Interface::Position.new(
220
+ range = LSP::Interface::Range.new(
221
+ start: LSP::Interface::Position.new(
216
222
  line: job.line - 1,
217
223
  character: job.column - prefix_size
218
224
  ),
219
- end: LanguageServer::Protocol::Interface::Position.new(
225
+ end: LSP::Interface::Position.new(
220
226
  line: job.line - 1,
221
227
  character: job.column
222
228
  )
@@ -227,88 +233,63 @@ module Steep
227
233
  env = sig_service.latest_env #: RBS::Environment
228
234
  class_entry = env.module_class_entry(type_name) or raise
229
235
 
230
- comment =
231
- case class_entry
232
- when RBS::Environment::ClassEntry, RBS::Environment::ModuleEntry
233
- class_entry.decls.flat_map {|decl| [decl.decl.comment] }.first
234
- when RBS::Environment::ClassAliasEntry, RBS::Environment::ModuleAliasEntry
235
- class_entry.decl.comment
236
- end
236
+ case class_entry
237
+ when RBS::Environment::ClassEntry, RBS::Environment::ModuleEntry
238
+ comments = class_entry.decls.map {|decl| decl.decl.comment }.compact
239
+ decl = class_entry.primary.decl
240
+ when RBS::Environment::ClassAliasEntry, RBS::Environment::ModuleAliasEntry
241
+ comments = [class_entry.decl.comment].compact
242
+ decl = class_entry.decl
243
+ end
237
244
 
238
- LanguageServer::Protocol::Interface::CompletionItem.new(
245
+ LSP::Interface::CompletionItem.new(
239
246
  label: complete_text,
240
- detail: type_name.to_s,
241
- documentation: format_comment(comment),
242
- text_edit: LanguageServer::Protocol::Interface::TextEdit.new(
247
+ label_details: LSP::Interface::CompletionItemLabelDetails.new(description: LSPFormatter.declaration_summary(decl)),
248
+ documentation: LSPFormatter.markup_content { LSPFormatter.format_rbs_completion_docs(type_name, decl, comments) },
249
+ text_edit: LSP::Interface::TextEdit.new(
243
250
  range: range,
244
251
  new_text: complete_text
245
252
  ),
246
- kind: LSP::Constant::CompletionItemKind::CLASS,
247
- insert_text_format: LSP::Constant::InsertTextFormat::SNIPPET,
248
- sort_text: complete_text,
249
- filter_text: complete_text
253
+ kind: LSP::Constant::CompletionItemKind::CLASS
250
254
  )
251
255
  when :alias
252
256
  alias_decl = sig_service.latest_env.type_alias_decls[type_name]&.decl or raise
253
257
 
254
- LanguageServer::Protocol::Interface::CompletionItem.new(
258
+ LSP::Interface::CompletionItem.new(
255
259
  label: complete_text,
256
- detail: type_name.to_s,
257
- text_edit: LanguageServer::Protocol::Interface::TextEdit.new(
260
+ label_details: LSP::Interface::CompletionItemLabelDetails.new(description: LSPFormatter.declaration_summary(alias_decl)),
261
+ text_edit: LSP::Interface::TextEdit.new(
258
262
  range: range,
259
263
  new_text: complete_text
260
264
  ),
261
- documentation: format_comment(alias_decl.comment),
262
- # https://github.com/microsoft/vscode-languageserver-node/blob/6d78fc4d25719b231aba64a721a606f58b9e0a5f/client/src/common/client.ts#L624-L650
263
- kind: LSP::Constant::CompletionItemKind::FIELD,
264
- insert_text_format: LSP::Constant::InsertTextFormat::SNIPPET,
265
- sort_text: complete_text,
266
- filter_text: complete_text
265
+ documentation: LSPFormatter.markup_content { LSPFormatter.format_rbs_completion_docs(type_name, alias_decl, [alias_decl.comment].compact) },
266
+ kind: LSP::Constant::CompletionItemKind::FIELD
267
267
  )
268
268
  when :interface
269
269
  interface_decl = sig_service.latest_env.interface_decls[type_name]&.decl or raise
270
270
 
271
- LanguageServer::Protocol::Interface::CompletionItem.new(
271
+ LSP::Interface::CompletionItem.new(
272
272
  label: complete_text,
273
- detail: type_name.to_s,
274
- text_edit: LanguageServer::Protocol::Interface::TextEdit.new(
273
+ label_details: LSP::Interface::CompletionItemLabelDetails.new(description: LSPFormatter.declaration_summary(interface_decl)),
274
+ text_edit: LSP::Interface::TextEdit.new(
275
275
  range: range,
276
276
  new_text: complete_text
277
277
  ),
278
- documentation: format_comment(interface_decl.comment),
279
- kind: LanguageServer::Protocol::Constant::CompletionItemKind::INTERFACE,
280
- insert_text_format: LanguageServer::Protocol::Constant::InsertTextFormat::SNIPPET,
281
- sort_text: complete_text,
282
- filter_text: complete_text
283
- )
284
- end
285
- end
286
-
287
- def format_comment(comment)
288
- if comment
289
- LSP::Interface::MarkupContent.new(
290
- kind: LSP::Constant::MarkupKind::MARKDOWN,
291
- value: comment.string.gsub(/<!--(?~-->)-->/, "")
292
- )
293
- end
294
- end
295
-
296
- def format_comments(comments)
297
- unless comments.empty?
298
- LSP::Interface::MarkupContent.new(
299
- kind: LSP::Constant::MarkupKind::MARKDOWN,
300
- value: comments.map(&:string).join("\n----\n").gsub(/<!--(?~-->)-->/, "")
278
+ documentation: LSPFormatter.markup_content { LSPFormatter.format_rbs_completion_docs(type_name, interface_decl, [interface_decl.comment].compact) },
279
+ kind: LSP::Constant::CompletionItemKind::INTERFACE
301
280
  )
281
+ else
282
+ raise
302
283
  end
303
284
  end
304
285
 
305
286
  def format_completion_item(item)
306
- range = LanguageServer::Protocol::Interface::Range.new(
307
- start: LanguageServer::Protocol::Interface::Position.new(
287
+ range = LSP::Interface::Range.new(
288
+ start: LSP::Interface::Position.new(
308
289
  line: item.range.start.line-1,
309
290
  character: item.range.start.column
310
291
  ),
311
- end: LanguageServer::Protocol::Interface::Position.new(
292
+ end: LSP::Interface::Position.new(
312
293
  line: item.range.end.line-1,
313
294
  character: item.range.end.column
314
295
  )
@@ -316,130 +297,103 @@ module Steep
316
297
 
317
298
  case item
318
299
  when Services::CompletionProvider::LocalVariableItem
319
- LanguageServer::Protocol::Interface::CompletionItem.new(
320
- label: item.identifier,
321
- kind: LanguageServer::Protocol::Constant::CompletionItemKind::VARIABLE,
322
- detail: item.type.to_s,
323
- text_edit: LanguageServer::Protocol::Interface::TextEdit.new(
324
- range: range,
325
- new_text: item.identifier
326
- )
300
+ LSP::Interface::CompletionItem.new(
301
+ label: item.identifier.to_s,
302
+ kind: LSP::Constant::CompletionItemKind::VARIABLE,
303
+ label_details: LSP::Interface::CompletionItemLabelDetails.new(description: item.type.to_s),
304
+ documentation: LSPFormatter.markup_content { LSPFormatter.format_completion_docs(item) },
305
+ insert_text: item.identifier.to_s,
306
+ sort_text: item.identifier.to_s
327
307
  )
328
308
  when Services::CompletionProvider::ConstantItem
329
309
  case
330
310
  when item.class? || item.module?
331
- kind = LanguageServer::Protocol::Constant::CompletionItemKind::CLASS
332
- detail = item.full_name.to_s
311
+ kind = LSP::Constant::CompletionItemKind::CLASS
333
312
  else
334
- kind = LanguageServer::Protocol::Constant::CompletionItemKind::CONSTANT
335
- detail = item.type.to_s
313
+ kind = LSP::Constant::CompletionItemKind::CONSTANT
336
314
  end
337
- LanguageServer::Protocol::Interface::CompletionItem.new(
338
- label: item.identifier,
315
+
316
+ detail = LSPFormatter.declaration_summary(item.decl)
317
+
318
+ LSP::Interface::CompletionItem.new(
319
+ label: item.identifier.to_s,
339
320
  kind: kind,
340
- detail: detail,
341
- documentation: format_comments(item.comments),
342
- text_edit: LanguageServer::Protocol::Interface::TextEdit.new(
321
+ label_details: LSP::Interface::CompletionItemLabelDetails.new(description: detail),
322
+ documentation: LSPFormatter.markup_content { LSPFormatter.format_completion_docs(item) },
323
+ text_edit: LSP::Interface::TextEdit.new(
343
324
  range: range,
344
- new_text: item.identifier
325
+ new_text: item.identifier.to_s
345
326
  )
346
327
  )
347
- when Services::CompletionProvider::MethodNameItem
348
- method_type_snippet = method_type_to_snippet(item.method_type)
349
- LanguageServer::Protocol::Interface::CompletionItem.new(
350
- label: item.identifier,
351
- kind: LanguageServer::Protocol::Constant::CompletionItemKind::METHOD,
352
- detail: item.method_type.to_s,
353
- text_edit: LanguageServer::Protocol::Interface::TextEdit.new(
354
- new_text: "#{item.identifier}#{method_type_snippet}",
355
- range: range
356
- ),
357
- documentation: format_comment(item.comment),
358
- insert_text_format: LanguageServer::Protocol::Constant::InsertTextFormat::SNIPPET,
359
- sort_text: item.inherited? ? 'z' : 'a' # Ensure language server puts non-inherited methods before inherited methods
328
+ when Services::CompletionProvider::SimpleMethodNameItem
329
+ LSP::Interface::CompletionItem.new(
330
+ label: item.identifier.to_s,
331
+ kind: LSP::Constant::CompletionItemKind::FUNCTION,
332
+ label_details: LSP::Interface::CompletionItemLabelDetails.new(description: item.method_name.relative.to_s),
333
+ insert_text: item.identifier.to_s,
334
+ documentation: LSPFormatter.markup_content { LSPFormatter.format_completion_docs(item) }
335
+ )
336
+ when Services::CompletionProvider::ComplexMethodNameItem
337
+ method_names = item.method_names.map(&:relative).uniq
338
+
339
+ LSP::Interface::CompletionItem.new(
340
+ label: item.identifier.to_s,
341
+ kind: LSP::Constant::CompletionItemKind::FUNCTION,
342
+ label_details: LSP::Interface::CompletionItemLabelDetails.new(description: method_names.join(", ")),
343
+ insert_text: item.identifier.to_s,
344
+ documentation: LSPFormatter.markup_content { LSPFormatter.format_completion_docs(item) }
345
+ )
346
+ when Services::CompletionProvider::GeneratedMethodNameItem
347
+ LSP::Interface::CompletionItem.new(
348
+ label: item.identifier.to_s,
349
+ kind: LSP::Constant::CompletionItemKind::FUNCTION,
350
+ label_details: LSP::Interface::CompletionItemLabelDetails.new(description: "(Generated)"),
351
+ insert_text: item.identifier.to_s,
352
+ documentation: LSPFormatter.markup_content { LSPFormatter.format_completion_docs(item) }
360
353
  )
361
354
  when Services::CompletionProvider::InstanceVariableItem
362
- LanguageServer::Protocol::Interface::CompletionItem.new(
363
- label: item.identifier,
364
- kind: LanguageServer::Protocol::Constant::CompletionItemKind::FIELD,
365
- detail: item.type.to_s,
366
- text_edit: LanguageServer::Protocol::Interface::TextEdit.new(
355
+ LSP::Interface::CompletionItem.new(
356
+ label: item.identifier.to_s,
357
+ kind: LSP::Constant::CompletionItemKind::FIELD,
358
+ label_details: LSP::Interface::CompletionItemLabelDetails.new(description: item.type.to_s),
359
+ documentation: LSPFormatter.markup_content { LSPFormatter.format_completion_docs(item) },
360
+ text_edit: LSP::Interface::TextEdit.new(
367
361
  range: range,
368
- new_text: item.identifier,
369
- ),
370
- insert_text_format: LanguageServer::Protocol::Constant::InsertTextFormat::SNIPPET
362
+ new_text: item.identifier.to_s
363
+ )
371
364
  )
372
365
  end
373
366
  end
374
367
 
375
- def method_type_to_snippet(method_type)
376
- params = if method_type.type.each_param.count == 0
377
- ""
378
- else
379
- "(#{params_to_snippet(method_type.type)})"
380
- end
381
-
382
-
383
- block = if method_type.block
384
- open, space, close = if method_type.block.type.return_type.is_a?(RBS::Types::Bases::Void)
385
- ["do", " ", "end"]
386
- else
387
- ["{", "", "}"]
388
- end
389
-
390
- if method_type.block.type.each_param.count == 0
391
- " #{open} $0 #{close}"
392
- else
393
- " #{open}#{space}|#{params_to_snippet(method_type.block.type)}| $0 #{close}"
368
+ def process_signature_help(job)
369
+ Steep.logger.tagged("##{__method__}") do
370
+ if target = project.target_for_source_path(job.path)
371
+ file = service.source_files[job.path] or return
372
+ subtyping = service.signature_services[target.name].current_subtyping or return
373
+ source = Source.parse(file.content, path: file.path, factory: subtyping.factory)
374
+
375
+ provider = Services::SignatureHelpProvider.new(source: source, subtyping: subtyping)
376
+
377
+ if (items, index = provider.run(line: job.line, column: job.column))
378
+ signatures = items.map do |item|
379
+ LSP::Interface::SignatureInformation.new(
380
+ label: "(#{item.method_type.type.param_to_s})",
381
+ documentation: item.comment&.yield_self do |comment|
382
+ LSP::Interface::MarkupContent.new(
383
+ kind: LSP::Constant::MarkupKind::MARKDOWN,
384
+ value: comment.string.gsub(/<!--(?~-->)-->/, "")
385
+ )
394
386
  end
395
- else
396
- ""
397
- end
398
-
399
- "#{params}#{block}"
400
- end
401
-
402
- def params_to_snippet(fun)
403
- params = []
404
-
405
- index = 1
406
-
407
- fun.required_positionals.each do |param|
408
- if name = param.name
409
- params << "${#{index}:#{param.type}}"
410
- else
411
- params << "${#{index}:#{param.type}}"
412
- end
413
-
414
- index += 1
415
- end
416
-
417
- if fun.rest_positionals
418
- params << "${#{index}:*#{fun.rest_positionals.type}}"
419
- index += 1
420
- end
421
-
422
- fun.trailing_positionals.each do |param|
423
- if name = param.name
424
- params << "${#{index}:#{param.type}}"
425
- else
426
- params << "${#{index}:#{param.type}}"
427
- end
428
-
429
- index += 1
430
- end
387
+ )
388
+ end
431
389
 
432
- fun.required_keywords.each do |keyword, param|
433
- if name = param.name
434
- params << "#{keyword}: ${#{index}:#{name}_}"
435
- else
436
- params << "#{keyword}: ${#{index}:#{param.type}_}"
390
+ LSP::Interface::SignatureHelp.new(
391
+ signatures: signatures,
392
+ active_signature: index
393
+ )
394
+ end
437
395
  end
438
-
439
- index += 1
440
396
  end
441
-
442
- params.join(", ")
443
397
  end
444
398
  end
445
399
  end