steep-activesupport-4 1.9.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (164) 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/Steepfile +68 -0
  9. data/bin/console +14 -0
  10. data/bin/generate-diagnostics-docs.rb +112 -0
  11. data/bin/mem_graph.rb +67 -0
  12. data/bin/mem_prof.rb +102 -0
  13. data/bin/output_rebaseline.rb +34 -0
  14. data/bin/output_test.rb +60 -0
  15. data/bin/rbs +20 -0
  16. data/bin/rbs-inline +19 -0
  17. data/bin/setup +9 -0
  18. data/bin/stackprof_test.rb +19 -0
  19. data/bin/steep +19 -0
  20. data/bin/steep-check.rb +251 -0
  21. data/bin/steep-prof +16 -0
  22. data/doc/narrowing.md +195 -0
  23. data/doc/shape.md +194 -0
  24. data/exe/steep +18 -0
  25. data/guides/README.md +5 -0
  26. data/guides/src/gem-rbs-collection/gem-rbs-collection.md +126 -0
  27. data/guides/src/getting-started/getting-started.md +163 -0
  28. data/guides/src/nil-optional/nil-optional.md +195 -0
  29. data/lib/steep/annotation_parser.rb +199 -0
  30. data/lib/steep/ast/annotation/collection.rb +172 -0
  31. data/lib/steep/ast/annotation.rb +137 -0
  32. data/lib/steep/ast/builtin.rb +104 -0
  33. data/lib/steep/ast/ignore.rb +148 -0
  34. data/lib/steep/ast/node/type_application.rb +88 -0
  35. data/lib/steep/ast/node/type_assertion.rb +81 -0
  36. data/lib/steep/ast/types/any.rb +35 -0
  37. data/lib/steep/ast/types/boolean.rb +45 -0
  38. data/lib/steep/ast/types/bot.rb +35 -0
  39. data/lib/steep/ast/types/class.rb +43 -0
  40. data/lib/steep/ast/types/factory.rb +557 -0
  41. data/lib/steep/ast/types/helper.rb +40 -0
  42. data/lib/steep/ast/types/instance.rb +42 -0
  43. data/lib/steep/ast/types/intersection.rb +93 -0
  44. data/lib/steep/ast/types/literal.rb +59 -0
  45. data/lib/steep/ast/types/logic.rb +84 -0
  46. data/lib/steep/ast/types/name.rb +128 -0
  47. data/lib/steep/ast/types/nil.rb +41 -0
  48. data/lib/steep/ast/types/proc.rb +117 -0
  49. data/lib/steep/ast/types/record.rb +79 -0
  50. data/lib/steep/ast/types/self.rb +43 -0
  51. data/lib/steep/ast/types/shared_instance.rb +11 -0
  52. data/lib/steep/ast/types/top.rb +35 -0
  53. data/lib/steep/ast/types/tuple.rb +60 -0
  54. data/lib/steep/ast/types/union.rb +97 -0
  55. data/lib/steep/ast/types/var.rb +65 -0
  56. data/lib/steep/ast/types/void.rb +35 -0
  57. data/lib/steep/cli.rb +401 -0
  58. data/lib/steep/diagnostic/deprecated/else_on_exhaustive_case.rb +20 -0
  59. data/lib/steep/diagnostic/deprecated/unknown_constant_assigned.rb +28 -0
  60. data/lib/steep/diagnostic/helper.rb +18 -0
  61. data/lib/steep/diagnostic/lsp_formatter.rb +78 -0
  62. data/lib/steep/diagnostic/result_printer2.rb +48 -0
  63. data/lib/steep/diagnostic/ruby.rb +1221 -0
  64. data/lib/steep/diagnostic/signature.rb +570 -0
  65. data/lib/steep/drivers/annotations.rb +52 -0
  66. data/lib/steep/drivers/check.rb +339 -0
  67. data/lib/steep/drivers/checkfile.rb +210 -0
  68. data/lib/steep/drivers/diagnostic_printer.rb +105 -0
  69. data/lib/steep/drivers/init.rb +66 -0
  70. data/lib/steep/drivers/langserver.rb +56 -0
  71. data/lib/steep/drivers/print_project.rb +113 -0
  72. data/lib/steep/drivers/stats.rb +203 -0
  73. data/lib/steep/drivers/utils/driver_helper.rb +143 -0
  74. data/lib/steep/drivers/utils/jobs_option.rb +26 -0
  75. data/lib/steep/drivers/vendor.rb +27 -0
  76. data/lib/steep/drivers/watch.rb +194 -0
  77. data/lib/steep/drivers/worker.rb +58 -0
  78. data/lib/steep/equatable.rb +23 -0
  79. data/lib/steep/expectations.rb +228 -0
  80. data/lib/steep/index/rbs_index.rb +350 -0
  81. data/lib/steep/index/signature_symbol_provider.rb +185 -0
  82. data/lib/steep/index/source_index.rb +167 -0
  83. data/lib/steep/interface/block.rb +103 -0
  84. data/lib/steep/interface/builder.rb +843 -0
  85. data/lib/steep/interface/function.rb +1090 -0
  86. data/lib/steep/interface/method_type.rb +330 -0
  87. data/lib/steep/interface/shape.rb +239 -0
  88. data/lib/steep/interface/substitution.rb +159 -0
  89. data/lib/steep/interface/type_param.rb +115 -0
  90. data/lib/steep/located_value.rb +20 -0
  91. data/lib/steep/method_name.rb +42 -0
  92. data/lib/steep/module_helper.rb +24 -0
  93. data/lib/steep/node_helper.rb +273 -0
  94. data/lib/steep/path_helper.rb +30 -0
  95. data/lib/steep/project/dsl.rb +268 -0
  96. data/lib/steep/project/group.rb +31 -0
  97. data/lib/steep/project/options.rb +63 -0
  98. data/lib/steep/project/pattern.rb +59 -0
  99. data/lib/steep/project/target.rb +92 -0
  100. data/lib/steep/project.rb +78 -0
  101. data/lib/steep/rake_task.rb +132 -0
  102. data/lib/steep/range_extension.rb +29 -0
  103. data/lib/steep/server/base_worker.rb +97 -0
  104. data/lib/steep/server/change_buffer.rb +73 -0
  105. data/lib/steep/server/custom_methods.rb +77 -0
  106. data/lib/steep/server/delay_queue.rb +45 -0
  107. data/lib/steep/server/interaction_worker.rb +492 -0
  108. data/lib/steep/server/lsp_formatter.rb +455 -0
  109. data/lib/steep/server/master.rb +912 -0
  110. data/lib/steep/server/target_group_files.rb +205 -0
  111. data/lib/steep/server/type_check_controller.rb +366 -0
  112. data/lib/steep/server/type_check_worker.rb +303 -0
  113. data/lib/steep/server/work_done_progress.rb +64 -0
  114. data/lib/steep/server/worker_process.rb +176 -0
  115. data/lib/steep/services/completion_provider.rb +802 -0
  116. data/lib/steep/services/content_change.rb +61 -0
  117. data/lib/steep/services/file_loader.rb +74 -0
  118. data/lib/steep/services/goto_service.rb +441 -0
  119. data/lib/steep/services/hover_provider/rbs.rb +88 -0
  120. data/lib/steep/services/hover_provider/ruby.rb +221 -0
  121. data/lib/steep/services/hover_provider/singleton_methods.rb +20 -0
  122. data/lib/steep/services/path_assignment.rb +46 -0
  123. data/lib/steep/services/signature_help_provider.rb +202 -0
  124. data/lib/steep/services/signature_service.rb +428 -0
  125. data/lib/steep/services/stats_calculator.rb +68 -0
  126. data/lib/steep/services/type_check_service.rb +394 -0
  127. data/lib/steep/services/type_name_completion.rb +236 -0
  128. data/lib/steep/signature/validator.rb +651 -0
  129. data/lib/steep/source/ignore_ranges.rb +69 -0
  130. data/lib/steep/source.rb +691 -0
  131. data/lib/steep/subtyping/cache.rb +30 -0
  132. data/lib/steep/subtyping/check.rb +1113 -0
  133. data/lib/steep/subtyping/constraints.rb +341 -0
  134. data/lib/steep/subtyping/relation.rb +101 -0
  135. data/lib/steep/subtyping/result.rb +324 -0
  136. data/lib/steep/subtyping/variable_variance.rb +89 -0
  137. data/lib/steep/test.rb +9 -0
  138. data/lib/steep/thread_waiter.rb +43 -0
  139. data/lib/steep/type_construction.rb +5183 -0
  140. data/lib/steep/type_inference/block_params.rb +416 -0
  141. data/lib/steep/type_inference/case_when.rb +303 -0
  142. data/lib/steep/type_inference/constant_env.rb +56 -0
  143. data/lib/steep/type_inference/context.rb +195 -0
  144. data/lib/steep/type_inference/logic_type_interpreter.rb +613 -0
  145. data/lib/steep/type_inference/method_call.rb +193 -0
  146. data/lib/steep/type_inference/method_params.rb +531 -0
  147. data/lib/steep/type_inference/multiple_assignment.rb +194 -0
  148. data/lib/steep/type_inference/send_args.rb +712 -0
  149. data/lib/steep/type_inference/type_env.rb +341 -0
  150. data/lib/steep/type_inference/type_env_builder.rb +138 -0
  151. data/lib/steep/typing.rb +321 -0
  152. data/lib/steep/version.rb +3 -0
  153. data/lib/steep.rb +369 -0
  154. data/manual/annotations.md +181 -0
  155. data/manual/ignore.md +20 -0
  156. data/manual/ruby-diagnostics.md +1879 -0
  157. data/sample/Steepfile +22 -0
  158. data/sample/lib/conference.rb +49 -0
  159. data/sample/lib/length.rb +35 -0
  160. data/sample/sig/conference.rbs +42 -0
  161. data/sample/sig/generics.rbs +15 -0
  162. data/sample/sig/length.rbs +34 -0
  163. data/steep-activesupport-4.gemspec +55 -0
  164. metadata +437 -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