steep-relaxed 1.9.3.3

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.
Files changed (165) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +13 -0
  3. data/.gitmodules +0 -0
  4. data/CHANGELOG.md +1032 -0
  5. data/LICENSE +21 -0
  6. data/README.md +260 -0
  7. data/Rakefile +227 -0
  8. data/STDGEM_DEPENDENCIES.txt +59 -0
  9. data/Steepfile +68 -0
  10. data/bin/console +14 -0
  11. data/bin/generate-diagnostics-docs.rb +112 -0
  12. data/bin/mem_graph.rb +67 -0
  13. data/bin/mem_prof.rb +102 -0
  14. data/bin/output_rebaseline.rb +34 -0
  15. data/bin/output_test.rb +60 -0
  16. data/bin/rbs +20 -0
  17. data/bin/rbs-inline +19 -0
  18. data/bin/setup +9 -0
  19. data/bin/stackprof_test.rb +19 -0
  20. data/bin/steep +19 -0
  21. data/bin/steep-check.rb +251 -0
  22. data/bin/steep-prof +16 -0
  23. data/doc/narrowing.md +195 -0
  24. data/doc/shape.md +194 -0
  25. data/exe/steep +18 -0
  26. data/guides/README.md +5 -0
  27. data/guides/src/gem-rbs-collection/gem-rbs-collection.md +126 -0
  28. data/guides/src/getting-started/getting-started.md +163 -0
  29. data/guides/src/nil-optional/nil-optional.md +195 -0
  30. data/lib/steep/annotation_parser.rb +199 -0
  31. data/lib/steep/ast/annotation/collection.rb +172 -0
  32. data/lib/steep/ast/annotation.rb +137 -0
  33. data/lib/steep/ast/builtin.rb +104 -0
  34. data/lib/steep/ast/ignore.rb +148 -0
  35. data/lib/steep/ast/node/type_application.rb +88 -0
  36. data/lib/steep/ast/node/type_assertion.rb +81 -0
  37. data/lib/steep/ast/types/any.rb +35 -0
  38. data/lib/steep/ast/types/boolean.rb +45 -0
  39. data/lib/steep/ast/types/bot.rb +35 -0
  40. data/lib/steep/ast/types/class.rb +43 -0
  41. data/lib/steep/ast/types/factory.rb +557 -0
  42. data/lib/steep/ast/types/helper.rb +40 -0
  43. data/lib/steep/ast/types/instance.rb +42 -0
  44. data/lib/steep/ast/types/intersection.rb +93 -0
  45. data/lib/steep/ast/types/literal.rb +59 -0
  46. data/lib/steep/ast/types/logic.rb +84 -0
  47. data/lib/steep/ast/types/name.rb +128 -0
  48. data/lib/steep/ast/types/nil.rb +41 -0
  49. data/lib/steep/ast/types/proc.rb +117 -0
  50. data/lib/steep/ast/types/record.rb +79 -0
  51. data/lib/steep/ast/types/self.rb +43 -0
  52. data/lib/steep/ast/types/shared_instance.rb +11 -0
  53. data/lib/steep/ast/types/top.rb +35 -0
  54. data/lib/steep/ast/types/tuple.rb +60 -0
  55. data/lib/steep/ast/types/union.rb +97 -0
  56. data/lib/steep/ast/types/var.rb +65 -0
  57. data/lib/steep/ast/types/void.rb +35 -0
  58. data/lib/steep/cli.rb +401 -0
  59. data/lib/steep/diagnostic/deprecated/else_on_exhaustive_case.rb +20 -0
  60. data/lib/steep/diagnostic/deprecated/unknown_constant_assigned.rb +28 -0
  61. data/lib/steep/diagnostic/helper.rb +18 -0
  62. data/lib/steep/diagnostic/lsp_formatter.rb +78 -0
  63. data/lib/steep/diagnostic/result_printer2.rb +48 -0
  64. data/lib/steep/diagnostic/ruby.rb +1221 -0
  65. data/lib/steep/diagnostic/signature.rb +570 -0
  66. data/lib/steep/drivers/annotations.rb +52 -0
  67. data/lib/steep/drivers/check.rb +339 -0
  68. data/lib/steep/drivers/checkfile.rb +210 -0
  69. data/lib/steep/drivers/diagnostic_printer.rb +105 -0
  70. data/lib/steep/drivers/init.rb +66 -0
  71. data/lib/steep/drivers/langserver.rb +56 -0
  72. data/lib/steep/drivers/print_project.rb +113 -0
  73. data/lib/steep/drivers/stats.rb +203 -0
  74. data/lib/steep/drivers/utils/driver_helper.rb +143 -0
  75. data/lib/steep/drivers/utils/jobs_option.rb +26 -0
  76. data/lib/steep/drivers/vendor.rb +27 -0
  77. data/lib/steep/drivers/watch.rb +194 -0
  78. data/lib/steep/drivers/worker.rb +58 -0
  79. data/lib/steep/equatable.rb +23 -0
  80. data/lib/steep/expectations.rb +228 -0
  81. data/lib/steep/index/rbs_index.rb +350 -0
  82. data/lib/steep/index/signature_symbol_provider.rb +185 -0
  83. data/lib/steep/index/source_index.rb +167 -0
  84. data/lib/steep/interface/block.rb +103 -0
  85. data/lib/steep/interface/builder.rb +843 -0
  86. data/lib/steep/interface/function.rb +1090 -0
  87. data/lib/steep/interface/method_type.rb +330 -0
  88. data/lib/steep/interface/shape.rb +239 -0
  89. data/lib/steep/interface/substitution.rb +159 -0
  90. data/lib/steep/interface/type_param.rb +115 -0
  91. data/lib/steep/located_value.rb +20 -0
  92. data/lib/steep/method_name.rb +42 -0
  93. data/lib/steep/module_helper.rb +24 -0
  94. data/lib/steep/node_helper.rb +273 -0
  95. data/lib/steep/path_helper.rb +30 -0
  96. data/lib/steep/project/dsl.rb +268 -0
  97. data/lib/steep/project/group.rb +31 -0
  98. data/lib/steep/project/options.rb +63 -0
  99. data/lib/steep/project/pattern.rb +59 -0
  100. data/lib/steep/project/target.rb +92 -0
  101. data/lib/steep/project.rb +78 -0
  102. data/lib/steep/rake_task.rb +132 -0
  103. data/lib/steep/range_extension.rb +29 -0
  104. data/lib/steep/server/base_worker.rb +97 -0
  105. data/lib/steep/server/change_buffer.rb +73 -0
  106. data/lib/steep/server/custom_methods.rb +77 -0
  107. data/lib/steep/server/delay_queue.rb +45 -0
  108. data/lib/steep/server/interaction_worker.rb +492 -0
  109. data/lib/steep/server/lsp_formatter.rb +455 -0
  110. data/lib/steep/server/master.rb +922 -0
  111. data/lib/steep/server/target_group_files.rb +205 -0
  112. data/lib/steep/server/type_check_controller.rb +366 -0
  113. data/lib/steep/server/type_check_worker.rb +303 -0
  114. data/lib/steep/server/work_done_progress.rb +64 -0
  115. data/lib/steep/server/worker_process.rb +176 -0
  116. data/lib/steep/services/completion_provider.rb +802 -0
  117. data/lib/steep/services/content_change.rb +61 -0
  118. data/lib/steep/services/file_loader.rb +74 -0
  119. data/lib/steep/services/goto_service.rb +441 -0
  120. data/lib/steep/services/hover_provider/rbs.rb +88 -0
  121. data/lib/steep/services/hover_provider/ruby.rb +221 -0
  122. data/lib/steep/services/hover_provider/singleton_methods.rb +20 -0
  123. data/lib/steep/services/path_assignment.rb +46 -0
  124. data/lib/steep/services/signature_help_provider.rb +202 -0
  125. data/lib/steep/services/signature_service.rb +428 -0
  126. data/lib/steep/services/stats_calculator.rb +68 -0
  127. data/lib/steep/services/type_check_service.rb +394 -0
  128. data/lib/steep/services/type_name_completion.rb +236 -0
  129. data/lib/steep/signature/validator.rb +651 -0
  130. data/lib/steep/source/ignore_ranges.rb +69 -0
  131. data/lib/steep/source.rb +691 -0
  132. data/lib/steep/subtyping/cache.rb +30 -0
  133. data/lib/steep/subtyping/check.rb +1113 -0
  134. data/lib/steep/subtyping/constraints.rb +341 -0
  135. data/lib/steep/subtyping/relation.rb +101 -0
  136. data/lib/steep/subtyping/result.rb +324 -0
  137. data/lib/steep/subtyping/variable_variance.rb +89 -0
  138. data/lib/steep/test.rb +9 -0
  139. data/lib/steep/thread_waiter.rb +43 -0
  140. data/lib/steep/type_construction.rb +5183 -0
  141. data/lib/steep/type_inference/block_params.rb +416 -0
  142. data/lib/steep/type_inference/case_when.rb +303 -0
  143. data/lib/steep/type_inference/constant_env.rb +56 -0
  144. data/lib/steep/type_inference/context.rb +195 -0
  145. data/lib/steep/type_inference/logic_type_interpreter.rb +613 -0
  146. data/lib/steep/type_inference/method_call.rb +193 -0
  147. data/lib/steep/type_inference/method_params.rb +531 -0
  148. data/lib/steep/type_inference/multiple_assignment.rb +194 -0
  149. data/lib/steep/type_inference/send_args.rb +712 -0
  150. data/lib/steep/type_inference/type_env.rb +341 -0
  151. data/lib/steep/type_inference/type_env_builder.rb +138 -0
  152. data/lib/steep/typing.rb +321 -0
  153. data/lib/steep/version.rb +3 -0
  154. data/lib/steep.rb +369 -0
  155. data/manual/annotations.md +181 -0
  156. data/manual/ignore.md +20 -0
  157. data/manual/ruby-diagnostics.md +1879 -0
  158. data/sample/Steepfile +22 -0
  159. data/sample/lib/conference.rb +49 -0
  160. data/sample/lib/length.rb +35 -0
  161. data/sample/sig/conference.rbs +42 -0
  162. data/sample/sig/generics.rbs +15 -0
  163. data/sample/sig/length.rbs +34 -0
  164. data/steep-relaxed.gemspec +56 -0
  165. metadata +340 -0
@@ -0,0 +1,455 @@
1
+ module Steep
2
+ module Server
3
+ module LSPFormatter
4
+ include Services
5
+
6
+ LSP = LanguageServer::Protocol
7
+
8
+ module_function
9
+
10
+ def markup_content(string = nil, &block)
11
+ if block
12
+ string = yield()
13
+ end
14
+
15
+ if string
16
+ LSP::Interface::MarkupContent.new(kind: LSP::Constant::MarkupKind::MARKDOWN, value: string)
17
+ end
18
+ end
19
+
20
+ def format_hover_content(content)
21
+ case content
22
+ when HoverProvider::Ruby::VariableContent
23
+ local_variable(content.name, content.type)
24
+
25
+ when HoverProvider::Ruby::MethodCallContent
26
+ io = StringIO.new
27
+ call = content.method_call
28
+
29
+ case call
30
+ when TypeInference::MethodCall::Typed
31
+ io.puts <<~MD
32
+ ```rbs
33
+ #{call.actual_method_type.type.return_type}
34
+ ```
35
+
36
+ ----
37
+ MD
38
+
39
+ method_decls = call.method_decls.sort_by {|decl| decl.method_name.to_s }
40
+ method_types = method_decls.map(&:method_type)
41
+
42
+ if call.is_a?(TypeInference::MethodCall::Special)
43
+ method_types = [
44
+ call.actual_method_type.with(
45
+ type: call.actual_method_type.type.with(return_type: call.return_type)
46
+ )
47
+ ]
48
+
49
+ header = <<~MD
50
+ **💡 Custom typing rule applies**
51
+
52
+ ----
53
+ MD
54
+ end
55
+ when TypeInference::MethodCall::Error
56
+ method_decls = call.method_decls.sort_by {|decl| decl.method_name.to_s }
57
+ method_types = method_decls.map {|decl| decl.method_type }
58
+
59
+ header = <<~MD
60
+ **🚨 No compatible method type found**
61
+
62
+ ----
63
+ MD
64
+ end
65
+
66
+ method_names = method_decls.map {|decl| decl.method_name.relative }
67
+ docs = method_decls.map {|decl| [decl.method_name, decl.method_def.comment] }.to_h
68
+
69
+ if header
70
+ io.puts header
71
+ end
72
+
73
+ io.puts(
74
+ format_method_item_doc(method_types, method_names, docs)
75
+ )
76
+
77
+ io.string
78
+
79
+ when HoverProvider::Ruby::DefinitionContent
80
+ io = StringIO.new
81
+
82
+ method_name =
83
+ if content.method_name.is_a?(SingletonMethodName)
84
+ "self.#{content.method_name.method_name}"
85
+ else
86
+ content.method_name.method_name
87
+ end
88
+
89
+ prefix_size = "def ".size + method_name.size
90
+ method_types = content.definition.method_types
91
+
92
+ io.puts <<~MD
93
+ ```rbs
94
+ def #{method_name}: #{method_types.join("\n" + " "*prefix_size + "| ") }
95
+ ```
96
+
97
+ ----
98
+ MD
99
+
100
+ if content.definition.method_types.size > 1
101
+ io.puts "**Internal method type**"
102
+ io.puts <<~MD
103
+ ```rbs
104
+ #{content.method_type}
105
+ ```
106
+
107
+ ----
108
+ MD
109
+ end
110
+
111
+ io.puts format_comments(
112
+ content.definition.comments.map {|comment|
113
+ [content.method_name.relative.to_s, comment] #: [String, RBS::AST::Comment?]
114
+ }
115
+ )
116
+
117
+ io.string
118
+ when HoverProvider::Ruby::ConstantContent
119
+ io = StringIO.new
120
+
121
+ decl_summary =
122
+ case
123
+ when decl = content.class_decl
124
+ declaration_summary(decl.primary.decl)
125
+ when decl = content.constant_decl
126
+ declaration_summary(decl.decl)
127
+ when decl = content.class_alias
128
+ declaration_summary(decl.decl)
129
+ end
130
+
131
+ io.puts <<~MD
132
+ ```rbs
133
+ #{decl_summary}
134
+ ```
135
+ MD
136
+
137
+ comments = content.comments.map {|comment|
138
+ [content.full_name.relative!.to_s, comment] #: [String, RBS::AST::Comment?]
139
+ }
140
+
141
+ unless comments.all?(&:nil?)
142
+ io.puts "----"
143
+ io.puts format_comments(comments)
144
+ end
145
+
146
+ io.string
147
+ when HoverProvider::Ruby::TypeContent
148
+ <<~MD
149
+ ```rbs
150
+ #{content.type}
151
+ ```
152
+ MD
153
+
154
+ when HoverProvider::Ruby::TypeAssertionContent
155
+ <<~MD
156
+ ```rbs
157
+ #{content.asserted_type}
158
+ ```
159
+
160
+ ↑ Converted from `#{content.original_type.to_s}`
161
+ MD
162
+
163
+ when HoverProvider::RBS::TypeAliasContent, HoverProvider::RBS::InterfaceContent
164
+ io = StringIO.new()
165
+
166
+ io.puts <<~MD
167
+ ```rbs
168
+ #{declaration_summary(content.decl)}
169
+ ```
170
+ MD
171
+
172
+ if comment = content.decl.comment
173
+ io.puts
174
+ io.puts "----"
175
+
176
+ io.puts format_comment(comment, header: content.decl.name.relative!.to_s)
177
+ end
178
+
179
+ io.string
180
+
181
+ when HoverProvider::RBS::ClassContent
182
+ io = StringIO.new
183
+
184
+ io << <<~MD
185
+ ```rbs
186
+ #{declaration_summary(content.decl)}
187
+ ```
188
+ MD
189
+
190
+ if content.decl.comment
191
+ io.puts "----"
192
+
193
+ class_name =
194
+ case content.decl
195
+ when RBS::AST::Declarations::ModuleAlias, RBS::AST::Declarations::ClassAlias
196
+ content.decl.new_name
197
+ when RBS::AST::Declarations::Class, RBS::AST::Declarations::Module
198
+ content.decl.name
199
+ else
200
+ raise
201
+ end
202
+
203
+ io << format_comments([[class_name.relative!.to_s, content.decl.comment]])
204
+ end
205
+
206
+ io.string
207
+ else
208
+ raise content.class.to_s
209
+ end
210
+ end
211
+
212
+ def format_completion_docs(item)
213
+ case item
214
+ when Services::CompletionProvider::LocalVariableItem
215
+ local_variable(item.identifier, item.type)
216
+ when Services::CompletionProvider::ConstantItem
217
+ io = StringIO.new
218
+
219
+ io.puts <<~MD
220
+ ```rbs
221
+ #{declaration_summary(item.decl)}
222
+ ```
223
+ MD
224
+
225
+ unless item.comments.all?(&:nil?)
226
+ io.puts "----"
227
+ io.puts format_comments(
228
+ item.comments.map {|comment|
229
+ [item.full_name.relative!.to_s, comment] #: [String, RBS::AST::Comment?]
230
+ }
231
+ )
232
+ end
233
+
234
+ io.string
235
+ when Services::CompletionProvider::InstanceVariableItem
236
+ instance_variable(item.identifier, item.type)
237
+ when Services::CompletionProvider::SimpleMethodNameItem
238
+ format_method_item_doc(item.method_types, [], { item.method_name => item.method_member.comment })
239
+ when Services::CompletionProvider::ComplexMethodNameItem
240
+ method_names = item.method_names.map(&:relative).uniq
241
+ comments = item.method_definitions.transform_values {|member| member.comment }
242
+ format_method_item_doc(item.method_types, method_names, comments)
243
+ when Services::CompletionProvider::GeneratedMethodNameItem
244
+ format_method_item_doc(item.method_types, [], {}, "🤖 Generated method for receiver type")
245
+ when Services::CompletionProvider::TypeNameItem
246
+ io = StringIO.new
247
+
248
+ io.puts <<~MD
249
+ ```rbs
250
+ #{declaration_summary(item.decl)}
251
+ ```
252
+ MD
253
+
254
+ unless item.comments.empty?
255
+ io.puts "----"
256
+ io.puts format_comments(
257
+ item.comments.map {|comment|
258
+ [item.absolute_type_name.relative!.to_s, comment] #: [String, RBS::AST::Comment?]
259
+ }
260
+ )
261
+ end
262
+
263
+ io.string
264
+ when Services::CompletionProvider::KeywordArgumentItem
265
+ <<~MD
266
+ **Keyword argument**: `#{item.identifier}`
267
+ MD
268
+ else
269
+ raise
270
+ end
271
+ end
272
+
273
+ def format_rbs_completion_docs(type_name, decl, comments)
274
+ io = StringIO.new
275
+
276
+ io.puts <<~MD
277
+ ```rbs
278
+ #{declaration_summary(decl)}
279
+ ```
280
+ MD
281
+
282
+ unless comments.empty?
283
+ io.puts
284
+ io.puts "----"
285
+
286
+ io.puts format_comments(
287
+ comments.map {|comment|
288
+ [type_name.relative!.to_s, comment] #: [String, RBS::AST::Comment?]
289
+ }
290
+ )
291
+ end
292
+
293
+ io.string
294
+ end
295
+
296
+ def format_comments(comments)
297
+ io = StringIO.new
298
+
299
+ with_docs = [] #: Array[[String, RBS::AST::Comment]]
300
+ without_docs = [] #: Array[String]
301
+
302
+ comments.each do |title, comment|
303
+ if comment
304
+ with_docs << [title, comment]
305
+ else
306
+ without_docs << title
307
+ end
308
+ end
309
+
310
+ unless with_docs.empty?
311
+ with_docs.each do |title, comment|
312
+ io.puts format_comment(comment, header: title)
313
+ io.puts
314
+ end
315
+
316
+ unless without_docs.empty?
317
+ io.puts
318
+ io.puts "----"
319
+ if without_docs.size == 1
320
+ io.puts "🔍 One more definition without docs"
321
+ else
322
+ io.puts "🔍 #{without_docs.size} more definitions without docs"
323
+ end
324
+ end
325
+ end
326
+
327
+ io.string
328
+ end
329
+
330
+ def format_comment(comment, header: nil, &block)
331
+ return unless comment
332
+
333
+ io = StringIO.new
334
+ if header
335
+ io.puts "### 📚 #{header.gsub("_", "\\_")}"
336
+ io.puts
337
+ end
338
+ io.puts comment.string.rstrip.gsub(/^[ \t]*<!--(?~-->)-->\n/, "").gsub(/\A([ \t]*\n)+/, "")
339
+
340
+ if block
341
+ yield io.string
342
+ else
343
+ io.string
344
+ end
345
+ end
346
+
347
+ def local_variable(name, type)
348
+ <<~MD
349
+ **Local variable** `#{name}: #{type}`
350
+ MD
351
+ end
352
+
353
+ def instance_variable(name, type)
354
+ <<~MD
355
+ **Instance variable** `#{name}: #{type}`
356
+ MD
357
+ end
358
+
359
+ def name_and_params(name, params)
360
+ if params.empty?
361
+ "#{name}"
362
+ else
363
+ ps = params.each.map do |param|
364
+ s = +""
365
+ if param.unchecked?
366
+ s << "unchecked "
367
+ end
368
+ case param.variance
369
+ when :invariant
370
+ # nop
371
+ when :covariant
372
+ s << "out "
373
+ when :contravariant
374
+ s << "in "
375
+ end
376
+ s << param.name.to_s
377
+
378
+ if param.upper_bound_type
379
+ s << " < #{param.upper_bound_type.to_s}"
380
+ end
381
+
382
+ s
383
+ end
384
+
385
+ "#{name}[#{ps.join(", ")}]"
386
+ end
387
+ end
388
+
389
+ def name_and_args(name, args)
390
+ if args.empty?
391
+ "#{name}"
392
+ else
393
+ "#{name}[#{args.map(&:to_s).join(", ")}]"
394
+ end
395
+ end
396
+
397
+ def declaration_summary(decl)
398
+ # Note that all names in the declarations is absolute
399
+ case decl
400
+ when RBS::AST::Declarations::Class
401
+ super_class = if super_class = decl.super_class
402
+ " < #{name_and_args(super_class.name, super_class.args)}"
403
+ end
404
+ "class #{name_and_params(decl.name.relative!, decl.type_params)}#{super_class}"
405
+ when RBS::AST::Declarations::Module
406
+ self_type = unless decl.self_types.empty?
407
+ " : #{decl.self_types.map {|s| name_and_args(s.name, s.args) }.join(", ")}"
408
+ end
409
+ "module #{name_and_params(decl.name.relative!, decl.type_params)}#{self_type}"
410
+ when RBS::AST::Declarations::TypeAlias
411
+ "type #{name_and_params(decl.name.relative!, decl.type_params)} = #{decl.type}"
412
+ when RBS::AST::Declarations::Interface
413
+ "interface #{name_and_params(decl.name.relative!, decl.type_params)}"
414
+ when RBS::AST::Declarations::ClassAlias
415
+ "class #{decl.new_name.relative!} = #{decl.old_name}"
416
+ when RBS::AST::Declarations::ModuleAlias
417
+ "module #{decl.new_name.relative!} = #{decl.old_name}"
418
+ when RBS::AST::Declarations::Global
419
+ "#{decl.name}: #{decl.type}"
420
+ when RBS::AST::Declarations::Constant
421
+ "#{decl.name.relative!}: #{decl.type}"
422
+ end
423
+ end
424
+
425
+ def format_method_item_doc(method_types, method_names, comments, footer = "")
426
+ io = StringIO.new
427
+
428
+ io.puts "**Method type**:"
429
+ io.puts "```rbs"
430
+ if method_types.size == 1
431
+ io.puts method_types[0].to_s
432
+ else
433
+ io.puts " #{method_types.join("\n| ")}"
434
+ end
435
+ io.puts "```"
436
+
437
+ if method_names.size > 1
438
+ io.puts "**Possible methods**: #{method_names.map {|type| "`#{type.to_s}`" }.join(", ")}"
439
+ io.puts
440
+ end
441
+
442
+ unless comments.each_value.all?(&:nil?)
443
+ io.puts "----"
444
+ io.puts format_comments(comments.transform_keys {|name| name.relative.to_s }.entries)
445
+ end
446
+
447
+ unless footer.empty?
448
+ io.puts footer.rstrip
449
+ end
450
+
451
+ io.string
452
+ end
453
+ end
454
+ end
455
+ end