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,1221 @@
1
+ module Steep
2
+ module Diagnostic
3
+ module Ruby
4
+ class Base
5
+ include Helper
6
+
7
+ attr_reader :node
8
+ attr_reader :location
9
+
10
+ def initialize(node:, location: node&.location&.expression)
11
+ @node = node
12
+ @location = location
13
+ end
14
+
15
+ def header_line
16
+ error_name
17
+ end
18
+
19
+ def detail_lines
20
+ nil
21
+ end
22
+
23
+ def diagnostic_code
24
+ "Ruby::#{error_name}"
25
+ end
26
+ end
27
+
28
+ module ResultPrinter
29
+ def relation_message(relation)
30
+ case
31
+ when relation.type?
32
+ relation.to_s
33
+ when relation.method?
34
+ if relation.super_type.is_a?(Interface::MethodType) && relation.sub_type.is_a?(Interface::MethodType)
35
+ relation.to_s
36
+ end
37
+ when relation.interface?
38
+ nil
39
+ when relation.block?
40
+ "(Blocks are incompatible)"
41
+ when relation.function?
42
+ nil
43
+ when relation.params?
44
+ "(Params are incompatible)"
45
+ end
46
+ end
47
+
48
+ def detail_lines
49
+ lines = StringIO.new.tap do |io|
50
+ failure_path = result.failure_path || []
51
+ failure_path.reverse_each.map do |result|
52
+ relation_message(result.relation)
53
+ end.compact.each.with_index(1) do |message, index|
54
+ io.puts "#{" " * (index)}#{message}"
55
+ end
56
+ end.string.chomp
57
+
58
+ unless lines.empty?
59
+ lines
60
+ end
61
+ end
62
+ end
63
+
64
+ class IncompatibleAssignment < Base
65
+ attr_reader :lhs_type
66
+ attr_reader :rhs_type
67
+ attr_reader :result
68
+
69
+ include ResultPrinter
70
+
71
+ def initialize(node:, lhs_type:, rhs_type:, result:)
72
+ super(node: node)
73
+ @lhs_type = lhs_type
74
+ @rhs_type = rhs_type
75
+ @result = result
76
+ end
77
+
78
+ def header_line
79
+ node = node() or raise
80
+
81
+ element = case node.type
82
+ when :ivasgn, :lvasgn, :gvasgn, :cvasgn
83
+ "a variable"
84
+ when :casgn
85
+ "a constant"
86
+ else
87
+ "an expression"
88
+ end
89
+ "Cannot assign a value of type `#{rhs_type}` to #{element} of type `#{lhs_type}`"
90
+ end
91
+ end
92
+
93
+ class UnexpectedPositionalArgument < Base
94
+ attr_reader :node
95
+ attr_reader :params
96
+
97
+ def initialize(node:, params:)
98
+ super(node: node)
99
+ @params = params
100
+ end
101
+
102
+ def header_line
103
+ "Unexpected positional argument"
104
+ end
105
+ end
106
+
107
+ class InsufficientPositionalArguments < Base
108
+ attr_reader :node
109
+ attr_reader :params
110
+
111
+ def initialize(node:, params:)
112
+ send = case node.type
113
+ when :send, :csend
114
+ node
115
+ when :block, :numblock
116
+ node.children[0]
117
+ end
118
+
119
+ loc = if send
120
+ send.loc.selector.with(end_pos: send.loc.expression.end_pos) # steep:ignore NoMethod
121
+ else
122
+ node.loc.expression
123
+ end
124
+
125
+ super(node: node, location: loc)
126
+ @params = params
127
+ end
128
+
129
+ def header_line
130
+ "More positional arguments are required"
131
+ end
132
+ end
133
+
134
+ class UnexpectedKeywordArgument < Base
135
+ attr_reader :node
136
+ attr_reader :params
137
+
138
+ def initialize(node:, params:)
139
+ loc = case node.type
140
+ when :pair
141
+ node.children[0].location.expression
142
+ when :kwsplat
143
+ node.location.expression
144
+ else
145
+ raise
146
+ end
147
+ super(node: node, location: loc)
148
+ @params = params
149
+ end
150
+
151
+ def header_line
152
+ "Unexpected keyword argument"
153
+ end
154
+ end
155
+
156
+ class InsufficientKeywordArguments < Base
157
+ attr_reader :node
158
+ attr_reader :method_name
159
+ attr_reader :method_type
160
+ attr_reader :missing_keywords
161
+
162
+ def initialize(node:, params:, missing_keywords:)
163
+ send = case node.type
164
+ when :send, :csend
165
+ node
166
+ when :block, :numblock
167
+ node.children[0]
168
+ end
169
+
170
+ loc = if send
171
+ send.loc.selector.with(end_pos: send.loc.expression.end_pos) # steep:ignore NoMethod
172
+ else
173
+ node.loc.expression
174
+ end
175
+
176
+ super(node: node, location: loc)
177
+
178
+ @params = params
179
+ @missing_keywords = missing_keywords
180
+ end
181
+
182
+ def header_line
183
+ "More keyword arguments are required: #{missing_keywords.join(", ")}"
184
+ end
185
+ end
186
+
187
+ class UnresolvedOverloading < Base
188
+ attr_reader :node
189
+ attr_reader :receiver_type
190
+ attr_reader :method_name
191
+ attr_reader :method_types
192
+
193
+ def initialize(node:, receiver_type:, method_name:, method_types:)
194
+ super node: node
195
+ @receiver_type = receiver_type
196
+ @method_name = method_name
197
+ @method_types = method_types
198
+ end
199
+
200
+ def header_line
201
+ "Cannot find compatible overloading of method `#{method_name}` of type `#{receiver_type}`"
202
+ end
203
+
204
+ def detail_lines
205
+ StringIO.new.tap do |io|
206
+ io.puts "Method types:"
207
+ first_type, *rest_types = method_types
208
+ defn = " def #{method_name}"
209
+ io.puts "#{defn}: #{first_type}"
210
+ rest_types.each do |method_type|
211
+ io.puts "#{" " * defn.size}| #{method_type}"
212
+ end
213
+ end.string.chomp
214
+ end
215
+ end
216
+
217
+ class ArgumentTypeMismatch < Base
218
+ attr_reader :node
219
+ attr_reader :expected
220
+ attr_reader :actual
221
+ attr_reader :result
222
+
223
+ include ResultPrinter
224
+
225
+ def initialize(node:, expected:, actual:, result:)
226
+ super(node: node)
227
+ @expected = expected
228
+ @actual = actual
229
+ @result = result
230
+ end
231
+
232
+ def header_line
233
+ "Cannot pass a value of type `#{actual}` as an argument of type `#{expected}`"
234
+ end
235
+ end
236
+
237
+ class NoMethod < Base
238
+ attr_reader :type
239
+ attr_reader :method
240
+
241
+ def initialize(node:, type:, method:)
242
+ loc = case node.type
243
+ when :send
244
+ loc = _ = nil
245
+ loc ||= node.loc.operator if node.loc.respond_to?(:operator) # steep:ignore NoMethod
246
+ loc ||= node.loc.selector if node.loc.respond_to?(:selector) # steep:ignore NoMethod
247
+ loc
248
+ when :block
249
+ node.children[0].loc.selector
250
+ end
251
+ super(node: node, location: loc || node.loc.expression)
252
+ @type = type
253
+ @method = method
254
+ end
255
+
256
+ def header_line
257
+ "Type `#{type}` does not have method `#{method}`"
258
+ end
259
+ end
260
+
261
+ class ReturnTypeMismatch < Base
262
+ attr_reader :expected
263
+ attr_reader :actual
264
+ attr_reader :result
265
+
266
+ include ResultPrinter
267
+
268
+ def initialize(node:, expected:, actual:, result:)
269
+ super(node: node)
270
+ @expected = expected
271
+ @actual = actual
272
+ @result = result
273
+ end
274
+
275
+ def header_line
276
+ "The method cannot return a value of type `#{actual}` because declared as type `#{expected}`"
277
+ end
278
+ end
279
+
280
+ class SetterReturnTypeMismatch < Base
281
+ attr_reader :expected, :actual, :result, :method_name
282
+
283
+ include ResultPrinter
284
+
285
+ def initialize(node:, method_name:, expected:, actual:, result:)
286
+ super(node: node)
287
+ @method_name = method_name
288
+ @expected = expected
289
+ @actual = actual
290
+ @result = result
291
+ end
292
+
293
+ def header_line
294
+ "The setter method `#{method_name}` cannot return a value of type `#{actual}` because declared as type `#{expected}`"
295
+ end
296
+ end
297
+
298
+ class UnexpectedBlockGiven < Base
299
+ attr_reader :method_type
300
+
301
+ def initialize(node:, method_type:)
302
+ loc = node.loc.begin.join(node.loc.end)
303
+ super(node: node, location: loc)
304
+ @method_type = method_type
305
+ end
306
+
307
+ def header_line
308
+ "The method cannot be called with a block"
309
+ end
310
+ end
311
+
312
+ class RequiredBlockMissing < Base
313
+ attr_reader :method_type
314
+
315
+ def initialize(node:, method_type:)
316
+ super(node: node, location: (node.type == :super || node.type == :zsuper) ? node.loc.keyword : node.loc.selector)
317
+ @method_type = method_type
318
+ end
319
+
320
+ def header_line
321
+ "The method cannot be called without a block"
322
+ end
323
+ end
324
+
325
+ class BlockTypeMismatch < Base
326
+ attr_reader :expected
327
+ attr_reader :actual
328
+ attr_reader :result
329
+
330
+ include ResultPrinter
331
+
332
+ def initialize(node:, expected:, actual:, result:)
333
+ super(node: node)
334
+ @expected = expected
335
+ @actual = actual
336
+ @result = result
337
+ end
338
+
339
+ def header_line
340
+ "Cannot pass a value of type `#{actual}` as a block-pass-argument of type `#{expected}`"
341
+ end
342
+ end
343
+
344
+ class BlockBodyTypeMismatch < Base
345
+ attr_reader :expected
346
+ attr_reader :actual
347
+ attr_reader :result
348
+
349
+ include ResultPrinter
350
+
351
+ def initialize(node:, expected:, actual:, result:)
352
+ super(node: node, location: node.loc.begin.join(node.loc.end))
353
+ @expected = expected
354
+ @actual = actual
355
+ @result = result
356
+ end
357
+
358
+ def header_line
359
+ "Cannot allow block body have type `#{actual}` because declared as type `#{expected}`"
360
+ end
361
+ end
362
+
363
+ class BreakTypeMismatch < Base
364
+ attr_reader :expected
365
+ attr_reader :actual
366
+ attr_reader :result
367
+
368
+ include ResultPrinter
369
+
370
+ def initialize(node:, expected:, actual:, result:)
371
+ super(node: node)
372
+ @expected = expected
373
+ @actual = actual
374
+ @result = result
375
+ end
376
+
377
+ def header_line
378
+ "Cannot break with a value of type `#{actual}` because type `#{expected}` is assumed"
379
+ end
380
+ end
381
+
382
+ class ImplicitBreakValueMismatch < Base
383
+ attr_reader :jump_type
384
+ attr_reader :result
385
+
386
+ include ResultPrinter
387
+
388
+ def initialize(node:, jump_type:, result:)
389
+ super(node: node)
390
+ @jump_type = jump_type
391
+ @result = result
392
+ end
393
+
394
+ def header_line
395
+ "Breaking without a value may result an error because a value of type `#{jump_type}` is expected"
396
+ end
397
+ end
398
+
399
+ class UnexpectedJump < Base
400
+ def header_line
401
+ "Cannot jump from here"
402
+ end
403
+ end
404
+
405
+ class UnexpectedJumpValue < Base
406
+ def header_line
407
+ node = node() or raise
408
+ "The value given to #{node.type} will be ignored"
409
+ end
410
+ end
411
+
412
+ class ClassModuleMismatch < Base
413
+ attr_reader :name
414
+
415
+ def initialize(node:, name:)
416
+ case node.type
417
+ when :module, :class
418
+ location = node.loc.name # steep:ignore NoMethod
419
+ else
420
+ raise "Unexpected node: #{node.type}"
421
+ end
422
+ super(node: node, location: location) # steep:ignore NoMethod
423
+
424
+ @name = name
425
+ end
426
+
427
+ def header_line
428
+ case node&.type
429
+ when :module
430
+ "#{name} is declared as a class in RBS"
431
+ when :class
432
+ "#{name} is declared as a module in RBS"
433
+ else
434
+ raise
435
+ end
436
+ end
437
+ end
438
+
439
+ class MethodArityMismatch < Base
440
+ attr_reader :method_type
441
+
442
+ def initialize(node:, method_type:)
443
+ args = case node.type
444
+ when :def
445
+ node.children[1]
446
+ when :defs
447
+ node.children[2]
448
+ end #: Parser::AST::Node?
449
+ super(node: node, location: args&.loc&.expression || node.loc.name)
450
+ @method_type = method_type
451
+ end
452
+
453
+ def header_line
454
+ "Method parameters are incompatible with declaration `#{method_type}`"
455
+ end
456
+ end
457
+
458
+ class MethodParameterMismatch < Base
459
+ attr_reader :method_param
460
+ attr_reader :method_type
461
+
462
+ def initialize(method_param:, method_type:)
463
+ super(node: method_param.node)
464
+ @method_param = method_param
465
+ @method_type = method_type
466
+ end
467
+
468
+ def header_line
469
+ "The method parameter is incompatible with the declaration `#{method_type}`"
470
+ end
471
+ end
472
+
473
+ class DifferentMethodParameterKind < Base
474
+ attr_reader :method_param
475
+ attr_reader :method_type
476
+
477
+ def initialize(method_param:, method_type:)
478
+ super(node: method_param.node)
479
+ @method_param = method_param
480
+ @method_type = method_type
481
+ end
482
+
483
+ def header_line
484
+ "The method parameter has different kind from the declaration `#{method_type}`"
485
+ end
486
+ end
487
+
488
+ class MethodReturnTypeAnnotationMismatch < Base
489
+ attr_reader :method_type
490
+ attr_reader :annotation_type
491
+ attr_reader :result
492
+
493
+ include ResultPrinter
494
+
495
+ def initialize(node:, method_type:, annotation_type:, result:)
496
+ super(node: node)
497
+ @method_type = method_type
498
+ @annotation_type = annotation_type
499
+ @result = result
500
+ end
501
+
502
+ def header_line
503
+ "Annotation `@type return` specifies type `#{annotation_type}` where declared as type `#{method_type}`"
504
+ end
505
+ end
506
+
507
+ class MethodBodyTypeMismatch < Base
508
+ attr_reader :expected
509
+ attr_reader :actual
510
+ attr_reader :result
511
+
512
+ include ResultPrinter
513
+
514
+ def initialize(node:, expected:, actual:, result:)
515
+ super(node: node, location: node.loc.name)
516
+ @expected = expected
517
+ @actual = actual
518
+ @result = result
519
+ end
520
+
521
+ def header_line
522
+ "Cannot allow method body have type `#{actual}` because declared as type `#{expected}`"
523
+ end
524
+ end
525
+
526
+ class SetterBodyTypeMismatch < Base
527
+ attr_reader :expected, :actual, :result, :method_name
528
+
529
+ include ResultPrinter
530
+
531
+ def initialize(node:, expected:, actual:, result:, method_name:)
532
+ super(node: node, location: node.loc.name)
533
+ @expected = expected
534
+ @actual = actual
535
+ @result = result
536
+ @method_name = method_name
537
+ end
538
+
539
+ def header_line
540
+ "Setter method `#{method_name}` cannot have type `#{actual}` because declared as type `#{expected}`"
541
+ end
542
+ end
543
+
544
+ class UnexpectedYield < Base
545
+ def header_line
546
+ "No block given for `yield`"
547
+ end
548
+ end
549
+
550
+ class UnexpectedSuper < Base
551
+ attr_reader :method
552
+
553
+ def initialize(node:, method:)
554
+ super(node: node)
555
+ @method = method
556
+ end
557
+
558
+ def header_line
559
+ if method
560
+ "No superclass method `#{method}` defined"
561
+ else
562
+ "`super` is not allowed from outside of method"
563
+ end
564
+ end
565
+ end
566
+
567
+ class MethodDefinitionMissing < Base
568
+ attr_reader :module_name
569
+ attr_reader :kind
570
+ attr_reader :missing_method
571
+
572
+ def initialize(node:, module_name:, kind:, missing_method:)
573
+ super(node: node, location: node.children[0].loc.expression)
574
+ @module_name = module_name
575
+ @kind = kind
576
+ @missing_method = missing_method
577
+ end
578
+
579
+ def header_line
580
+ method_name = case kind
581
+ when :module
582
+ ".#{missing_method}"
583
+ when :instance
584
+ "##{missing_method}"
585
+ end
586
+ "Cannot find implementation of method `#{module_name}#{method_name}`"
587
+ end
588
+ end
589
+
590
+ class UnexpectedDynamicMethod < Base
591
+ attr_reader :module_name
592
+ attr_reader :method_name
593
+
594
+ def initialize(node:, module_name:, method_name:)
595
+ super(node: node, location: node.children[0].loc.expression)
596
+ @module_name = module_name
597
+ @method_name = method_name
598
+ end
599
+
600
+ def header_line
601
+ "@dynamic annotation contains unknown method name `#{method_name}`"
602
+ end
603
+ end
604
+
605
+ class UnknownConstant < Base
606
+ attr_reader :name
607
+ attr_reader :kind
608
+
609
+ def initialize(node:, name:)
610
+ super(node: node, location: node.loc.name)
611
+ @name = name
612
+ @kind = :constant
613
+ end
614
+
615
+ def class!
616
+ @kind = :class
617
+ self
618
+ end
619
+
620
+ def module!
621
+ @kind = :module
622
+ self
623
+ end
624
+
625
+ def header_line
626
+ "Cannot find the declaration of #{kind}: `#{name}`"
627
+ end
628
+ end
629
+
630
+ autoload :UnknownConstantAssigned, "steep/diagnostic/deprecated/unknown_constant_assigned"
631
+ autoload :ElseOnExhaustiveCase, "steep/diagnostic/deprecated/else_on_exhaustive_case"
632
+
633
+ class UnknownInstanceVariable < Base
634
+ attr_reader :name
635
+
636
+ def initialize(node:, name:)
637
+ super(node: node, location: node.loc.name) # steep:ignore NoMethod
638
+ @name = name
639
+ end
640
+
641
+ def header_line
642
+ "Cannot find the declaration of instance variable: `#{name}`"
643
+ end
644
+ end
645
+
646
+ class UnknownGlobalVariable < Base
647
+ attr_reader :name
648
+
649
+ def initialize(node:, name:)
650
+ super(node: node, location: node.loc.name)
651
+ @name = name
652
+ end
653
+
654
+ def header_line
655
+ "Cannot find the declaration of global variable: `#{name}`"
656
+ end
657
+ end
658
+
659
+ class FallbackAny < Base
660
+ def initialize(node:)
661
+ super(node: node)
662
+ end
663
+
664
+ def header_line
665
+ "Cannot detect the type of the expression"
666
+ end
667
+ end
668
+
669
+ class UnsatisfiableConstraint < Base
670
+ attr_reader :method_type
671
+ attr_reader :var
672
+ attr_reader :sub_type
673
+ attr_reader :super_type
674
+ attr_reader :result
675
+
676
+ def initialize(node:, method_type:, var:, sub_type:, super_type:, result:)
677
+ super(node: node)
678
+ @method_type = method_type
679
+ @var = var
680
+ @sub_type = sub_type
681
+ @super_type = super_type
682
+ @result = result
683
+ end
684
+
685
+ include ResultPrinter
686
+
687
+ def header_line
688
+ "Unsatisfiable constraint `#{sub_type} <: #{var} <: #{super_type}` is generated through #{method_type}"
689
+ end
690
+ end
691
+
692
+ class IncompatibleAnnotation < Base
693
+ attr_reader :var_name
694
+ attr_reader :result
695
+ attr_reader :relation
696
+
697
+ def initialize(node:, var_name:, result:, relation:)
698
+ super(node: node, location: node.location.expression)
699
+ @var_name = var_name
700
+ @result = result
701
+ @relation = relation
702
+ end
703
+
704
+ include ResultPrinter
705
+
706
+ def header_line
707
+ "Type annotation about `#{var_name}` is incompatible since #{relation} doesn't hold"
708
+ end
709
+ end
710
+
711
+ class UnreachableBranch < Base
712
+ def header_line
713
+ "The branch is unreachable"
714
+ end
715
+ end
716
+
717
+ class UnreachableValueBranch < Base
718
+ attr_reader :type
719
+
720
+ def initialize(node:, type:, location: node.location.expression)
721
+ super(node: node, location: location)
722
+ @type = type
723
+ end
724
+
725
+ def header_line
726
+ "The branch may evaluate to a value of `#{type}` but unreachable"
727
+ end
728
+ end
729
+
730
+ class ProcTypeExpected < Base
731
+ attr_reader :type
732
+
733
+ def initialize(node:, type:)
734
+ super(node: node)
735
+ @type = type
736
+ end
737
+
738
+ def header_line
739
+ "Proc type is expected but `#{type.to_s}` is specified"
740
+ end
741
+ end
742
+
743
+ class MultipleAssignmentConversionError < Base
744
+ attr_reader :original_type, :returned_type
745
+
746
+ def initialize(node:, original_type:, returned_type:)
747
+ super(node: node)
748
+
749
+ @node = node
750
+ @original_type = original_type
751
+ @returned_type = returned_type
752
+ end
753
+
754
+ def header_line
755
+ "Cannot convert `#{original_type}` to Array or tuple (`#to_ary` returns `#{returned_type}`)"
756
+ end
757
+ end
758
+
759
+ class UnsupportedSyntax < Base
760
+ attr_reader :message
761
+
762
+ def initialize(node:, message: nil)
763
+ super(node: node)
764
+ @message = message
765
+ end
766
+
767
+ def header_line
768
+ if message
769
+ message
770
+ else
771
+ node = node() or raise
772
+ "Syntax `#{node.type}` is not supported in Steep"
773
+ end
774
+ end
775
+ end
776
+
777
+ class UnexpectedError < Base
778
+ attr_reader :error
779
+
780
+ def initialize(node:, error:)
781
+ super(node: node)
782
+ @error = error
783
+ end
784
+
785
+ def header_line
786
+ "UnexpectedError: #{error.message}(#{error.class})"
787
+ end
788
+
789
+ def detail_lines
790
+ if trace = error.backtrace
791
+ io = StringIO.new
792
+
793
+ total = trace.size
794
+ if total > 30
795
+ trace = trace.take(15)
796
+ end
797
+
798
+ trace.each.with_index do |line, index|
799
+ io.puts "#{index+1}. #{line}"
800
+ end
801
+
802
+ if trace.size != total
803
+ io.puts " (#{total - trace.size} more backtrace)"
804
+ end
805
+
806
+ io.string
807
+ end
808
+ end
809
+ end
810
+
811
+ class SyntaxError < Base
812
+ attr_reader :message
813
+
814
+ def initialize(message: ,location:)
815
+ super(node: nil, location: location)
816
+ @message = message
817
+ end
818
+
819
+ def header_line
820
+ "SyntaxError: #{message}"
821
+ end
822
+ end
823
+
824
+ class AnnotationSyntaxError < Base
825
+ attr_reader :message
826
+
827
+ def initialize(message: ,location:)
828
+ super(node: nil, location: location)
829
+ @message = message
830
+ end
831
+
832
+ def header_line
833
+ "Type annotation has a syntax error: #{message}"
834
+ end
835
+ end
836
+
837
+ class FalseAssertion < Base
838
+ attr_reader :node, :assertion_type, :node_type
839
+
840
+ def initialize(node:, assertion_type:, node_type:)
841
+ super(node: node)
842
+ @assertion_type = assertion_type
843
+ @node_type = node_type
844
+ end
845
+
846
+ def header_line
847
+ "Assertion cannot hold: no relationship between inferred type (`#{node_type.to_s}`) and asserted type (`#{assertion_type.to_s}`)"
848
+ end
849
+ end
850
+
851
+ class UnexpectedTypeArgument < Base
852
+ attr_reader :type_arg, :method_type
853
+
854
+ def initialize(type_arg:, method_type:, location:)
855
+ super(node: nil, location: location)
856
+ @type_arg = type_arg
857
+ @method_type = method_type
858
+ end
859
+
860
+ def header_line
861
+ "Unexpected type arg is given to method type `#{method_type.to_s}`"
862
+ end
863
+ end
864
+
865
+ class InsufficientTypeArgument < Base
866
+ attr_reader :type_args, :method_type
867
+
868
+ def initialize(node:, type_args:, method_type:)
869
+ super(node: node)
870
+ @type_args = type_args
871
+ @method_type = method_type
872
+ end
873
+
874
+ def header_line
875
+ "Requires #{method_type.type_params.size} types, but #{type_args.size} given: `#{method_type.to_s}`"
876
+ end
877
+ end
878
+
879
+ class TypeArgumentMismatchError < Base
880
+ attr_reader :type_argument, :type_parameter, :result
881
+
882
+ def initialize(type_arg:, type_param:, result:, location:)
883
+ super(node: nil, location: location)
884
+ @type_argument = type_arg
885
+ @type_parameter = type_param
886
+ @result = result
887
+ end
888
+
889
+ include ResultPrinter
890
+
891
+ def header_line
892
+ "Cannot pass a type `#{type_argument}` as a type parameter `#{type_parameter.to_s}`"
893
+ end
894
+ end
895
+
896
+ class IncompatibleArgumentForwarding < Base
897
+ attr_reader :method_name, :params_pair, :block_pair, :result
898
+
899
+ def initialize(method_name:, node:, params_pair: nil, block_pair: nil, result:)
900
+ super(node: node)
901
+ @method_name = method_name
902
+ @result = result
903
+ @params_pair = params_pair
904
+ @block_pair = block_pair
905
+ end
906
+
907
+ include ResultPrinter2
908
+
909
+ def header_line
910
+ case
911
+ when params_pair
912
+ "Cannot forward arguments to `#{method_name}`:"
913
+ when block_pair
914
+ "Cannot forward block to `#{method_name}`:"
915
+ else
916
+ raise
917
+ end
918
+ end
919
+ end
920
+
921
+ class ProcHintIgnored < Base
922
+ attr_reader :hint_type, :block_node
923
+
924
+ def initialize(hint_type:, node:)
925
+ @hint_type = hint_type
926
+ super(node: node)
927
+ end
928
+
929
+ def header_line
930
+ "The type hint given to the block is ignored: `#{hint_type}`"
931
+ end
932
+ end
933
+
934
+ class RBSError < Base
935
+ attr_reader :error
936
+
937
+ def initialize(error:, node:, location:)
938
+ @error = error
939
+ super(node: node, location: location)
940
+ end
941
+
942
+ def header_line
943
+ error.header_line
944
+ end
945
+ end
946
+
947
+ class InvalidIgnoreComment < Base
948
+ attr_reader :comment
949
+
950
+ def initialize(comment:)
951
+ @comment = comment
952
+ super(node: nil, location: comment.location.expression)
953
+ end
954
+
955
+ def header_line
956
+ "Invalid ignore comment"
957
+ end
958
+ end
959
+
960
+ class UnannotatedEmptyCollection < Base
961
+ def header_line
962
+ node or raise
963
+ "Empty #{node.type} doesn't have type annotation"
964
+ end
965
+ end
966
+
967
+ class UnknownRecordKey < Base
968
+ attr_reader :key
969
+
970
+ def initialize(key:, node:)
971
+ super(node: node)
972
+ @key = key
973
+ end
974
+
975
+ def header_line
976
+ "Unknown key `#{key.inspect}` is given to a record type"
977
+ end
978
+ end
979
+
980
+ class UndeclaredMethodDefinition < Base
981
+ attr_reader :method_name, :type_name
982
+
983
+ def initialize(method_name:, type_name:, node:)
984
+ @method_name = method_name
985
+ @type_name = type_name
986
+ super(node: node, location: (_ = node.loc).name)
987
+ end
988
+
989
+ def header_line
990
+ name =
991
+ case node.type
992
+ when :def
993
+ "#{type_name}##{method_name}"
994
+ when :defs
995
+ "#{type_name}.#{method_name}"
996
+ else
997
+ raise
998
+ end
999
+ "Method `#{name}` is not declared in RBS"
1000
+ end
1001
+ end
1002
+
1003
+ class MethodDefinitionInUndeclaredModule < Base
1004
+ attr_reader :method_name
1005
+
1006
+ def initialize(method_name:, node:)
1007
+ @method_name = method_name
1008
+ super(node: node, location: (_ = node.loc).name)
1009
+ end
1010
+
1011
+ def header_line
1012
+ "Method `#{method_name}` is defined in undeclared module"
1013
+ end
1014
+ end
1015
+
1016
+ ALL = ObjectSpace.each_object(Class).with_object([]) do |klass, array|
1017
+ if klass < Base
1018
+ array << klass
1019
+ end
1020
+ end
1021
+
1022
+ def self.all_error
1023
+ @all_error ||= ALL.each.with_object({}) do |klass, hash| #$ Hash[singleton(Base), LSPFormatter::severity]
1024
+ hash[klass] = LSPFormatter::ERROR
1025
+ end.freeze
1026
+ end
1027
+
1028
+ def self.default
1029
+ @default ||= _ = all_error.merge(
1030
+ {
1031
+ AnnotationSyntaxError => :error,
1032
+ ArgumentTypeMismatch => :error,
1033
+ BlockBodyTypeMismatch => :warning,
1034
+ BlockTypeMismatch => :warning,
1035
+ BreakTypeMismatch => :hint,
1036
+ DifferentMethodParameterKind => :hint,
1037
+ FallbackAny => :hint,
1038
+ FalseAssertion => :hint,
1039
+ ImplicitBreakValueMismatch => :hint,
1040
+ IncompatibleAnnotation => :hint,
1041
+ IncompatibleArgumentForwarding => :warning,
1042
+ IncompatibleAssignment => :hint,
1043
+ InsufficientKeywordArguments => :error,
1044
+ InsufficientPositionalArguments => :error,
1045
+ InsufficientTypeArgument => :hint,
1046
+ InvalidIgnoreComment => :warning,
1047
+ MethodArityMismatch => :error,
1048
+ MethodBodyTypeMismatch => :error,
1049
+ MethodDefinitionInUndeclaredModule => :information,
1050
+ MethodDefinitionMissing => nil,
1051
+ MethodParameterMismatch => :error,
1052
+ MethodReturnTypeAnnotationMismatch => :hint,
1053
+ MultipleAssignmentConversionError => :hint,
1054
+ NoMethod => :error,
1055
+ ProcHintIgnored => :hint,
1056
+ ProcTypeExpected => :hint,
1057
+ RBSError => :information,
1058
+ RequiredBlockMissing => :error,
1059
+ ReturnTypeMismatch => :error,
1060
+ SetterBodyTypeMismatch => :information,
1061
+ SetterReturnTypeMismatch => :information,
1062
+ ClassModuleMismatch => :error,
1063
+ SyntaxError => :information,
1064
+ TypeArgumentMismatchError => :hint,
1065
+ UnannotatedEmptyCollection => :warning,
1066
+ UndeclaredMethodDefinition => :warning,
1067
+ UnexpectedBlockGiven => :warning,
1068
+ UnexpectedDynamicMethod => :hint,
1069
+ UnexpectedError => :hint,
1070
+ UnexpectedJump => :hint,
1071
+ UnexpectedJumpValue => :hint,
1072
+ UnexpectedKeywordArgument => :error,
1073
+ UnexpectedPositionalArgument => :error,
1074
+ UnexpectedSuper => :information,
1075
+ UnexpectedTypeArgument => :hint,
1076
+ UnexpectedYield => :warning,
1077
+ UnknownConstant => :warning,
1078
+ UnknownGlobalVariable => :warning,
1079
+ UnknownRecordKey => :information,
1080
+ UnknownInstanceVariable => :information,
1081
+ UnreachableBranch => :hint,
1082
+ UnreachableValueBranch => :hint,
1083
+ UnresolvedOverloading => :error,
1084
+ UnsatisfiableConstraint => :hint,
1085
+ UnsupportedSyntax => :hint,
1086
+ }
1087
+ ).freeze
1088
+ end
1089
+
1090
+ def self.strict
1091
+ @strict ||= _ = all_error.merge(
1092
+ {
1093
+ AnnotationSyntaxError => :error,
1094
+ ArgumentTypeMismatch => :error,
1095
+ BlockBodyTypeMismatch => :error,
1096
+ BlockTypeMismatch => :error,
1097
+ BreakTypeMismatch => :error,
1098
+ DifferentMethodParameterKind => :error,
1099
+ FallbackAny => :warning,
1100
+ FalseAssertion => :error,
1101
+ ImplicitBreakValueMismatch => :information,
1102
+ IncompatibleAnnotation => :error,
1103
+ IncompatibleArgumentForwarding => :error,
1104
+ IncompatibleAssignment => :error,
1105
+ InsufficientKeywordArguments => :error,
1106
+ InsufficientPositionalArguments => :error,
1107
+ InsufficientTypeArgument => :error,
1108
+ InvalidIgnoreComment => :warning,
1109
+ MethodArityMismatch => :error,
1110
+ MethodBodyTypeMismatch => :error,
1111
+ MethodDefinitionInUndeclaredModule => :warning,
1112
+ MethodDefinitionMissing => :hint,
1113
+ MethodParameterMismatch => :error,
1114
+ MethodReturnTypeAnnotationMismatch => :error,
1115
+ MultipleAssignmentConversionError => :error,
1116
+ NoMethod => :error,
1117
+ ProcHintIgnored => :information,
1118
+ ProcTypeExpected => :error,
1119
+ RBSError => :error,
1120
+ RequiredBlockMissing => :error,
1121
+ ReturnTypeMismatch => :error,
1122
+ SetterBodyTypeMismatch => :error,
1123
+ SetterReturnTypeMismatch => :error,
1124
+ ClassModuleMismatch => :error,
1125
+ SyntaxError => :information,
1126
+ TypeArgumentMismatchError => :error,
1127
+ UnannotatedEmptyCollection => :error,
1128
+ UndeclaredMethodDefinition => :warning,
1129
+ UnexpectedBlockGiven => :error,
1130
+ UnexpectedDynamicMethod => :information,
1131
+ UnexpectedError => :information,
1132
+ UnexpectedJump => :error,
1133
+ UnexpectedJumpValue => :error,
1134
+ UnexpectedKeywordArgument => :error,
1135
+ UnexpectedPositionalArgument => :error,
1136
+ UnexpectedSuper => :error,
1137
+ UnexpectedTypeArgument => :error,
1138
+ UnexpectedYield => :error,
1139
+ UnknownConstant => :error,
1140
+ UnknownGlobalVariable => :error,
1141
+ UnknownRecordKey => :warning,
1142
+ UnknownInstanceVariable => :error,
1143
+ UnreachableBranch => :information,
1144
+ UnreachableValueBranch => :warning,
1145
+ UnresolvedOverloading => :error,
1146
+ UnsatisfiableConstraint => :error,
1147
+ UnsupportedSyntax => :information,
1148
+ }
1149
+ ).freeze
1150
+ end
1151
+
1152
+ def self.lenient
1153
+ @lenient ||= _ = all_error.merge(
1154
+ {
1155
+ AnnotationSyntaxError => :error,
1156
+ ArgumentTypeMismatch => :information,
1157
+ BlockBodyTypeMismatch => :information,
1158
+ BlockTypeMismatch => :information,
1159
+ BreakTypeMismatch => :hint,
1160
+ DifferentMethodParameterKind => nil,
1161
+ FallbackAny => nil,
1162
+ FalseAssertion => nil,
1163
+ ImplicitBreakValueMismatch => nil,
1164
+ IncompatibleAnnotation => nil,
1165
+ IncompatibleArgumentForwarding => :information,
1166
+ IncompatibleAssignment => :hint,
1167
+ InsufficientKeywordArguments => :information,
1168
+ InsufficientPositionalArguments => :information,
1169
+ InsufficientTypeArgument => nil,
1170
+ InvalidIgnoreComment => :warning,
1171
+ MethodArityMismatch => :information,
1172
+ MethodBodyTypeMismatch => :warning,
1173
+ MethodDefinitionInUndeclaredModule => :hint,
1174
+ MethodDefinitionMissing => nil,
1175
+ MethodParameterMismatch => :warning,
1176
+ MethodReturnTypeAnnotationMismatch => nil,
1177
+ MultipleAssignmentConversionError => nil,
1178
+ NoMethod => :information,
1179
+ ProcHintIgnored => nil,
1180
+ ProcTypeExpected => nil,
1181
+ RBSError => :information,
1182
+ RequiredBlockMissing => :hint,
1183
+ ReturnTypeMismatch => :warning,
1184
+ SetterBodyTypeMismatch => nil,
1185
+ SetterReturnTypeMismatch => nil,
1186
+ ClassModuleMismatch => nil,
1187
+ SyntaxError => :information,
1188
+ TypeArgumentMismatchError => nil,
1189
+ UnannotatedEmptyCollection => :hint,
1190
+ UndeclaredMethodDefinition => :information,
1191
+ UnexpectedBlockGiven => :hint,
1192
+ UnexpectedDynamicMethod => nil,
1193
+ UnexpectedError => :hint,
1194
+ UnexpectedJump => nil,
1195
+ UnexpectedJumpValue => nil,
1196
+ UnexpectedKeywordArgument => :information,
1197
+ UnexpectedPositionalArgument => :information,
1198
+ UnexpectedSuper => nil,
1199
+ UnexpectedTypeArgument => nil,
1200
+ UnexpectedYield => :information,
1201
+ UnknownConstant => :hint,
1202
+ UnknownGlobalVariable => :hint,
1203
+ UnknownRecordKey => :hint,
1204
+ UnknownInstanceVariable => :hint,
1205
+ UnreachableBranch => :hint,
1206
+ UnreachableValueBranch => :hint,
1207
+ UnresolvedOverloading => :information,
1208
+ UnsatisfiableConstraint => :hint,
1209
+ UnsupportedSyntax => :hint,
1210
+ }
1211
+ ).freeze
1212
+ end
1213
+
1214
+ def self.silent
1215
+ @silent ||= ALL.each.with_object({}) do |klass, hash| #$ template
1216
+ hash[klass] = nil
1217
+ end.freeze
1218
+ end
1219
+ end
1220
+ end
1221
+ end