rbs 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (132) hide show
  1. checksums.yaml +7 -0
  2. data/.github/workflows/ruby.yml +28 -0
  3. data/.gitignore +12 -0
  4. data/.rubocop.yml +15 -0
  5. data/BSDL +22 -0
  6. data/CHANGELOG.md +9 -0
  7. data/COPYING +56 -0
  8. data/Gemfile +6 -0
  9. data/README.md +93 -0
  10. data/Rakefile +142 -0
  11. data/bin/annotate-with-rdoc +157 -0
  12. data/bin/console +14 -0
  13. data/bin/query-rdoc +103 -0
  14. data/bin/setup +10 -0
  15. data/bin/sort +89 -0
  16. data/bin/test_runner.rb +16 -0
  17. data/docs/CONTRIBUTING.md +97 -0
  18. data/docs/sigs.md +148 -0
  19. data/docs/stdlib.md +152 -0
  20. data/docs/syntax.md +528 -0
  21. data/exe/rbs +7 -0
  22. data/lib/rbs.rb +64 -0
  23. data/lib/rbs/ast/annotation.rb +27 -0
  24. data/lib/rbs/ast/comment.rb +27 -0
  25. data/lib/rbs/ast/declarations.rb +395 -0
  26. data/lib/rbs/ast/members.rb +362 -0
  27. data/lib/rbs/buffer.rb +50 -0
  28. data/lib/rbs/builtin_names.rb +55 -0
  29. data/lib/rbs/cli.rb +558 -0
  30. data/lib/rbs/constant.rb +26 -0
  31. data/lib/rbs/constant_table.rb +150 -0
  32. data/lib/rbs/definition.rb +170 -0
  33. data/lib/rbs/definition_builder.rb +919 -0
  34. data/lib/rbs/environment.rb +281 -0
  35. data/lib/rbs/environment_loader.rb +136 -0
  36. data/lib/rbs/environment_walker.rb +124 -0
  37. data/lib/rbs/errors.rb +187 -0
  38. data/lib/rbs/location.rb +102 -0
  39. data/lib/rbs/method_type.rb +123 -0
  40. data/lib/rbs/namespace.rb +91 -0
  41. data/lib/rbs/parser.y +1344 -0
  42. data/lib/rbs/prototype/rb.rb +553 -0
  43. data/lib/rbs/prototype/rbi.rb +587 -0
  44. data/lib/rbs/prototype/runtime.rb +381 -0
  45. data/lib/rbs/substitution.rb +46 -0
  46. data/lib/rbs/test.rb +26 -0
  47. data/lib/rbs/test/errors.rb +61 -0
  48. data/lib/rbs/test/hook.rb +294 -0
  49. data/lib/rbs/test/setup.rb +58 -0
  50. data/lib/rbs/test/spy.rb +325 -0
  51. data/lib/rbs/test/test_helper.rb +183 -0
  52. data/lib/rbs/test/type_check.rb +254 -0
  53. data/lib/rbs/type_name.rb +70 -0
  54. data/lib/rbs/types.rb +936 -0
  55. data/lib/rbs/variance_calculator.rb +138 -0
  56. data/lib/rbs/vendorer.rb +47 -0
  57. data/lib/rbs/version.rb +3 -0
  58. data/lib/rbs/writer.rb +269 -0
  59. data/lib/ruby/signature.rb +7 -0
  60. data/rbs.gemspec +46 -0
  61. data/stdlib/abbrev/abbrev.rbs +60 -0
  62. data/stdlib/base64/base64.rbs +71 -0
  63. data/stdlib/benchmark/benchmark.rbs +372 -0
  64. data/stdlib/builtin/array.rbs +1997 -0
  65. data/stdlib/builtin/basic_object.rbs +280 -0
  66. data/stdlib/builtin/binding.rbs +177 -0
  67. data/stdlib/builtin/builtin.rbs +45 -0
  68. data/stdlib/builtin/class.rbs +145 -0
  69. data/stdlib/builtin/comparable.rbs +116 -0
  70. data/stdlib/builtin/complex.rbs +400 -0
  71. data/stdlib/builtin/constants.rbs +37 -0
  72. data/stdlib/builtin/data.rbs +5 -0
  73. data/stdlib/builtin/deprecated.rbs +2 -0
  74. data/stdlib/builtin/dir.rbs +413 -0
  75. data/stdlib/builtin/encoding.rbs +607 -0
  76. data/stdlib/builtin/enumerable.rbs +404 -0
  77. data/stdlib/builtin/enumerator.rbs +260 -0
  78. data/stdlib/builtin/errno.rbs +781 -0
  79. data/stdlib/builtin/errors.rbs +582 -0
  80. data/stdlib/builtin/exception.rbs +194 -0
  81. data/stdlib/builtin/false_class.rbs +40 -0
  82. data/stdlib/builtin/fiber.rbs +68 -0
  83. data/stdlib/builtin/fiber_error.rbs +12 -0
  84. data/stdlib/builtin/file.rbs +1076 -0
  85. data/stdlib/builtin/file_test.rbs +59 -0
  86. data/stdlib/builtin/float.rbs +696 -0
  87. data/stdlib/builtin/gc.rbs +243 -0
  88. data/stdlib/builtin/hash.rbs +1029 -0
  89. data/stdlib/builtin/integer.rbs +707 -0
  90. data/stdlib/builtin/io.rbs +683 -0
  91. data/stdlib/builtin/kernel.rbs +576 -0
  92. data/stdlib/builtin/marshal.rbs +161 -0
  93. data/stdlib/builtin/match_data.rbs +271 -0
  94. data/stdlib/builtin/math.rbs +369 -0
  95. data/stdlib/builtin/method.rbs +185 -0
  96. data/stdlib/builtin/module.rbs +1104 -0
  97. data/stdlib/builtin/nil_class.rbs +82 -0
  98. data/stdlib/builtin/numeric.rbs +409 -0
  99. data/stdlib/builtin/object.rbs +824 -0
  100. data/stdlib/builtin/proc.rbs +429 -0
  101. data/stdlib/builtin/process.rbs +1227 -0
  102. data/stdlib/builtin/random.rbs +267 -0
  103. data/stdlib/builtin/range.rbs +226 -0
  104. data/stdlib/builtin/rational.rbs +424 -0
  105. data/stdlib/builtin/rb_config.rbs +57 -0
  106. data/stdlib/builtin/regexp.rbs +1083 -0
  107. data/stdlib/builtin/ruby_vm.rbs +14 -0
  108. data/stdlib/builtin/signal.rbs +55 -0
  109. data/stdlib/builtin/string.rbs +1901 -0
  110. data/stdlib/builtin/string_io.rbs +284 -0
  111. data/stdlib/builtin/struct.rbs +40 -0
  112. data/stdlib/builtin/symbol.rbs +228 -0
  113. data/stdlib/builtin/thread.rbs +1108 -0
  114. data/stdlib/builtin/thread_group.rbs +23 -0
  115. data/stdlib/builtin/time.rbs +1047 -0
  116. data/stdlib/builtin/trace_point.rbs +290 -0
  117. data/stdlib/builtin/true_class.rbs +46 -0
  118. data/stdlib/builtin/unbound_method.rbs +153 -0
  119. data/stdlib/builtin/warning.rbs +17 -0
  120. data/stdlib/coverage/coverage.rbs +62 -0
  121. data/stdlib/csv/csv.rbs +773 -0
  122. data/stdlib/erb/erb.rbs +392 -0
  123. data/stdlib/find/find.rbs +40 -0
  124. data/stdlib/ipaddr/ipaddr.rbs +247 -0
  125. data/stdlib/json/json.rbs +335 -0
  126. data/stdlib/pathname/pathname.rbs +1093 -0
  127. data/stdlib/prime/integer-extension.rbs +23 -0
  128. data/stdlib/prime/prime.rbs +188 -0
  129. data/stdlib/securerandom/securerandom.rbs +9 -0
  130. data/stdlib/set/set.rbs +301 -0
  131. data/stdlib/tmpdir/tmpdir.rbs +53 -0
  132. metadata +292 -0
@@ -0,0 +1,587 @@
1
+ module RBS
2
+ module Prototype
3
+ class RBI
4
+ attr_reader :decls
5
+ attr_reader :modules
6
+ attr_reader :last_sig
7
+
8
+ def initialize
9
+ @decls = []
10
+
11
+ @modules = []
12
+ end
13
+
14
+ def parse(string)
15
+ comments = Ripper.lex(string).yield_self do |tokens|
16
+ tokens.each.with_object({}) do |token, hash|
17
+ if token[1] == :on_comment
18
+ line = token[0][0]
19
+ body = token[2][2..]
20
+
21
+ body = "\n" if body.empty?
22
+
23
+ comment = AST::Comment.new(string: body, location: nil)
24
+ if (prev_comment = hash[line - 1])
25
+ hash[line - 1] = nil
26
+ hash[line] = AST::Comment.new(string: prev_comment.string + comment.string,
27
+ location: nil)
28
+ else
29
+ hash[line] = comment
30
+ end
31
+ end
32
+ end
33
+ end
34
+ process RubyVM::AbstractSyntaxTree.parse(string), comments: comments
35
+ end
36
+
37
+ def nested_name(name)
38
+ (current_namespace + const_to_name(name).to_namespace).to_type_name.relative!
39
+ end
40
+
41
+ def current_namespace
42
+ modules.inject(Namespace.empty) do |parent, mod|
43
+ parent + mod.name.to_namespace
44
+ end
45
+ end
46
+
47
+ def push_class(name, super_class, comment:)
48
+ modules.push AST::Declarations::Class.new(
49
+ name: nested_name(name),
50
+ super_class: super_class && AST::Declarations::Class::Super.new(name: const_to_name(super_class), args: []),
51
+ type_params: AST::Declarations::ModuleTypeParams.empty,
52
+ members: [],
53
+ annotations: [],
54
+ location: nil,
55
+ comment: comment
56
+ )
57
+
58
+ decls << modules.last
59
+
60
+ yield
61
+ ensure
62
+ modules.pop
63
+ end
64
+
65
+ def push_module(name, comment:)
66
+ modules.push AST::Declarations::Module.new(
67
+ name: nested_name(name),
68
+ type_params: AST::Declarations::ModuleTypeParams.empty,
69
+ members: [],
70
+ annotations: [],
71
+ location: nil,
72
+ self_type: nil,
73
+ comment: comment
74
+ )
75
+
76
+ decls << modules.last
77
+
78
+ yield
79
+ ensure
80
+ modules.pop
81
+ end
82
+
83
+ def current_module
84
+ modules.last
85
+ end
86
+
87
+ def push_sig(node)
88
+ @last_sig ||= []
89
+ @last_sig << node
90
+ end
91
+
92
+ def pop_sig
93
+ @last_sig.tap do
94
+ @last_sig = nil
95
+ end
96
+ end
97
+
98
+ def join_comments(nodes, comments)
99
+ cs = nodes.map {|node| comments[node.first_lineno - 1] }.compact
100
+ AST::Comment.new(string: cs.map(&:string).join("\n"), location: nil)
101
+ end
102
+
103
+ def process(node, outer: [], comments:)
104
+ case node.type
105
+ when :CLASS
106
+ comment = comments[node.first_lineno - 1]
107
+ push_class node.children[0], node.children[1], comment: comment do
108
+ process node.children[2], outer: outer + [node], comments: comments
109
+ end
110
+ when :MODULE
111
+ comment = comments[node.first_lineno - 1]
112
+ push_module node.children[0], comment: comment do
113
+ process node.children[1], outer: outer + [node], comments: comments
114
+ end
115
+ when :FCALL
116
+ case node.children[0]
117
+ when :include
118
+ each_arg node.children[1] do |arg|
119
+ if arg.type == :CONST || arg.type == :COLON2 || arg.type == :COLON3
120
+ name = const_to_name(arg)
121
+ include_member = AST::Members::Include.new(
122
+ name: name,
123
+ args: [],
124
+ annotations: [],
125
+ location: nil,
126
+ comment: nil
127
+ )
128
+ current_module.members << include_member
129
+ end
130
+ end
131
+ when :extend
132
+ each_arg node.children[1] do |arg|
133
+ if arg.type == :CONST || arg.type == :COLON2
134
+ name = const_to_name(arg)
135
+ unless name.to_s == "T::Generic" || name.to_s == "T::Sig"
136
+ member = AST::Members::Extend.new(
137
+ name: name,
138
+ args: [],
139
+ annotations: [],
140
+ location: nil,
141
+ comment: nil
142
+ )
143
+ current_module.members << member
144
+ end
145
+ end
146
+ end
147
+ when :sig
148
+ push_sig outer.last.children.last.children.last
149
+ when :alias_method
150
+ new, old = each_arg(node.children[1]).map {|x| x.children[0] }
151
+ current_module.members << AST::Members::Alias.new(
152
+ new_name: new,
153
+ old_name: old,
154
+ location: nil,
155
+ annotations: [],
156
+ kind: :instance,
157
+ comment: nil
158
+ )
159
+ end
160
+ when :DEFS
161
+ sigs = pop_sig
162
+
163
+ if sigs
164
+ comment = join_comments(sigs, comments)
165
+
166
+ args = node.children[2]
167
+ types = sigs.map {|sig| method_type(args, sig, variables: current_module.type_params) }
168
+
169
+ current_module.members << AST::Members::MethodDefinition.new(
170
+ name: node.children[1],
171
+ location: nil,
172
+ annotations: [],
173
+ types: types,
174
+ kind: :singleton,
175
+ comment: comment,
176
+ attributes: []
177
+ )
178
+ end
179
+
180
+ when :DEFN
181
+ sigs = pop_sig
182
+
183
+ if sigs
184
+ comment = join_comments(sigs, comments)
185
+
186
+ args = node.children[1]
187
+ types = sigs.map {|sig| method_type(args, sig, variables: current_module.type_params) }
188
+
189
+ current_module.members << AST::Members::MethodDefinition.new(
190
+ name: node.children[0],
191
+ location: nil,
192
+ annotations: [],
193
+ types: types,
194
+ kind: :instance,
195
+ comment: comment,
196
+ attributes: []
197
+ )
198
+ end
199
+
200
+ when :CDECL
201
+ if (send = node.children.last) && send.type == :FCALL && send.children[0] == :type_member
202
+ unless each_arg(send.children[1]).any? {|node|
203
+ node.type == :HASH &&
204
+ each_arg(node.children[0]).each_slice(2).any? {|a, _| a.type == :LIT && a.children[0] == :fixed }
205
+ }
206
+ if (a0 = each_arg(send.children[1]).to_a[0])&.type == :LIT
207
+ variance = case a0.children[0]
208
+ when :out
209
+ :covariant
210
+ when :in
211
+ :contravariant
212
+ end
213
+ end
214
+
215
+ current_module.type_params.add(
216
+ AST::Declarations::ModuleTypeParams::TypeParam.new(name: node.children[0],
217
+ variance: variance || :invariant,
218
+ skip_validation: false))
219
+ end
220
+ else
221
+ name = node.children[0].yield_self do |n|
222
+ if n.is_a?(Symbol)
223
+ TypeName.new(namespace: current_namespace, name: n)
224
+ else
225
+ const_to_name(n)
226
+ end
227
+ end
228
+ value_node = node.children.last
229
+ type = if value_node.type == :CALL && value_node.children[1] == :let
230
+ type_node = each_arg(value_node.children[2]).to_a[1]
231
+ type_of type_node, variables: current_module&.type_params || []
232
+ else
233
+ Types::Bases::Any.new(location: nil)
234
+ end
235
+ decls << AST::Declarations::Constant.new(
236
+ name: name,
237
+ type: type,
238
+ location: nil,
239
+ comment: nil
240
+ )
241
+ end
242
+ when :ALIAS
243
+ current_module.members << AST::Members::Alias.new(
244
+ new_name: node.children[0].children[0],
245
+ old_name: node.children[1].children[0],
246
+ location: nil,
247
+ annotations: [],
248
+ kind: :instance,
249
+ comment: nil
250
+ )
251
+ else
252
+ each_child node do |child|
253
+ process child, outer: outer + [node], comments: comments
254
+ end
255
+ end
256
+ end
257
+
258
+ def method_type(args_node, type_node, variables:)
259
+ if type_node
260
+ if type_node.type == :CALL
261
+ method_type = method_type(args_node, type_node.children[0], variables: variables)
262
+ else
263
+ method_type = MethodType.new(
264
+ type: Types::Function.empty(Types::Bases::Any.new(location: nil)),
265
+ block: nil,
266
+ location: nil,
267
+ type_params: []
268
+ )
269
+ end
270
+
271
+ name, args = case type_node.type
272
+ when :CALL
273
+ [
274
+ type_node.children[1],
275
+ type_node.children[2]
276
+ ]
277
+ when :FCALL, :VCALL
278
+ [
279
+ type_node.children[0],
280
+ type_node.children[1]
281
+ ]
282
+ end
283
+
284
+ case name
285
+ when :returns
286
+ return_type = each_arg(args).to_a[0]
287
+ method_type.update(type: method_type.type.with_return_type(type_of(return_type, variables: variables)))
288
+ when :params
289
+ if args_node
290
+ parse_params(args_node, args, method_type, variables: variables)
291
+ else
292
+ vars = (node_to_hash(each_arg(args).to_a[0]) || {}).transform_values {|value| type_of(value, variables: variables) }
293
+
294
+ required_positionals = vars.map do |name, type|
295
+ Types::Function::Param.new(name: name, type: type)
296
+ end
297
+
298
+ method_type.update(type: method_type.type.update(required_positionals: required_positionals))
299
+ end
300
+ when :type_parameters
301
+ type_params = []
302
+
303
+ each_arg args do |node|
304
+ if node.type == :LIT
305
+ type_params << node.children[0]
306
+ end
307
+ end
308
+
309
+ method_type.update(type_params: type_params)
310
+ when :void
311
+ method_type.update(type: method_type.type.with_return_type(Types::Bases::Void.new(location: nil)))
312
+ when :proc
313
+ method_type
314
+ else
315
+ method_type
316
+ end
317
+ end
318
+ end
319
+
320
+ def parse_params(args_node, args, method_type, variables:)
321
+ vars = (node_to_hash(each_arg(args).to_a[0]) || {}).transform_values {|value| type_of(value, variables: variables) }
322
+
323
+ required_positionals = []
324
+ optional_positionals = []
325
+ rest_positionals = nil
326
+ trailing_positionals = []
327
+ required_keywords = {}
328
+ optional_keywords = {}
329
+ rest_keywords = nil
330
+
331
+ var_names = args_node.children[0]
332
+ pre_num, _pre_init, opt, _first_post, post_num, _post_init, rest, kw, kwrest, block = args_node.children[1].children
333
+
334
+ pre_num.times.each do |i|
335
+ name = var_names[i]
336
+ type = vars[name] || Types::Bases::Any.new(location: nil)
337
+ required_positionals << Types::Function::Param.new(type: type, name: name)
338
+ end
339
+
340
+ index = pre_num
341
+ while opt
342
+ name = var_names[index]
343
+ if (type = vars[name])
344
+ optional_positionals << Types::Function::Param.new(type: type, name: name)
345
+ end
346
+ index += 1
347
+ opt = opt.children[1]
348
+ end
349
+
350
+ if rest
351
+ name = var_names[index]
352
+ if (type = vars[name])
353
+ rest_positionals = Types::Function::Param.new(type: type, name: name)
354
+ end
355
+ index += 1
356
+ end
357
+
358
+ post_num.times do |i|
359
+ name = var_names[i+index]
360
+ if (type = vars[name])
361
+ trailing_positionals << Types::Function::Param.new(type: type, name: name)
362
+ end
363
+ index += 1
364
+ end
365
+
366
+ while kw
367
+ name, value = kw.children[0].children
368
+ if (type = vars[name])
369
+ if value
370
+ optional_keywords[name] = Types::Function::Param.new(type: type, name: name)
371
+ else
372
+ required_keywords[name] = Types::Function::Param.new(type: type, name: name)
373
+ end
374
+ end
375
+
376
+ kw = kw.children[1]
377
+ end
378
+
379
+ if kwrest
380
+ name = kwrest.children[0]
381
+ if (type = vars[name])
382
+ rest_keywords = Types::Function::Param.new(type: type, name: name)
383
+ end
384
+ end
385
+
386
+ method_block = nil
387
+ if block
388
+ if (type = vars[block])
389
+ if type.is_a?(Types::Proc)
390
+ method_block = MethodType::Block.new(required: true, type: type.type)
391
+ elsif type.is_a?(Types::Bases::Any)
392
+ method_block = MethodType::Block.new(
393
+ required: true,
394
+ type: Types::Function.empty(Types::Bases::Any.new(location: nil))
395
+ )
396
+ # Handle an optional block like `T.nilable(T.proc.void)`.
397
+ elsif type.is_a?(Types::Optional) && type.type.is_a?(Types::Proc)
398
+ method_block = MethodType::Block.new(required: false, type: type.type.type)
399
+ else
400
+ STDERR.puts "Unexpected block type: #{type}"
401
+ PP.pp args_node, STDERR
402
+ method_block = MethodType::Block.new(
403
+ required: true,
404
+ type: Types::Function.empty(Types::Bases::Any.new(location: nil))
405
+ )
406
+ end
407
+ end
408
+ end
409
+
410
+ method_type.update(
411
+ type: method_type.type.update(
412
+ required_positionals: required_positionals,
413
+ optional_positionals: optional_positionals,
414
+ rest_positionals: rest_positionals,
415
+ trailing_positionals: trailing_positionals,
416
+ required_keywords: required_keywords,
417
+ optional_keywords: optional_keywords,
418
+ rest_keywords: rest_keywords
419
+ ),
420
+ block: method_block
421
+ )
422
+ end
423
+
424
+ def type_of(type_node, variables:)
425
+ type = type_of0(type_node, variables: variables)
426
+
427
+ case
428
+ when type.is_a?(Types::ClassInstance) && type.name.name == BuiltinNames::BasicObject.name.name
429
+ Types::Bases::Any.new(location: nil)
430
+ when type.is_a?(Types::ClassInstance) && type.name.to_s == "T::Boolean"
431
+ Types::Bases::Bool.new(location: nil)
432
+ else
433
+ type
434
+ end
435
+ end
436
+
437
+ def type_of0(type_node, variables:)
438
+ case
439
+ when type_node.type == :CONST
440
+ if variables.each.include?(type_node.children[0])
441
+ Types::Variable.new(name: type_node.children[0], location: nil)
442
+ else
443
+ Types::ClassInstance.new(name: const_to_name(type_node), args: [], location: nil)
444
+ end
445
+ when type_node.type == :COLON2
446
+ Types::ClassInstance.new(name: const_to_name(type_node), args: [], location: nil)
447
+ when call_node?(type_node, name: :[], receiver: -> (_) { true })
448
+ type = type_of(type_node.children[0], variables: variables)
449
+ each_arg(type_node.children[2]) do |arg|
450
+ type.args << type_of(arg, variables: variables)
451
+ end
452
+
453
+ type
454
+ when call_node?(type_node, name: :type_parameter)
455
+ name = each_arg(type_node.children[2]).to_a[0].children[0]
456
+ Types::Variable.new(name: name, location: nil)
457
+ when call_node?(type_node, name: :any)
458
+ types = each_arg(type_node.children[2]).to_a.map {|node| type_of(node, variables: variables) }
459
+ Types::Union.new(types: types, location: nil)
460
+ when call_node?(type_node, name: :all)
461
+ types = each_arg(type_node.children[2]).to_a.map {|node| type_of(node, variables: variables) }
462
+ Types::Intersection.new(types: types, location: nil)
463
+ when call_node?(type_node, name: :untyped)
464
+ Types::Bases::Any.new(location: nil)
465
+ when call_node?(type_node, name: :nilable)
466
+ type = type_of each_arg(type_node.children[2]).to_a[0], variables: variables
467
+ Types::Optional.new(type: type, location: nil)
468
+ when call_node?(type_node, name: :self_type)
469
+ Types::Bases::Self.new(location: nil)
470
+ when call_node?(type_node, name: :attached_class)
471
+ Types::Bases::Instance.new(location: nil)
472
+ when call_node?(type_node, name: :noreturn)
473
+ Types::Bases::Bottom.new(location: nil)
474
+ when call_node?(type_node, name: :class_of)
475
+ type = type_of each_arg(type_node.children[2]).to_a[0], variables: variables
476
+ case type
477
+ when Types::ClassInstance
478
+ Types::ClassSingleton.new(name: type.name, location: nil)
479
+ else
480
+ STDERR.puts "Unexpected type for `class_of`: #{type}"
481
+ Types::Bases::Any.new(location: nil)
482
+ end
483
+ when type_node.type == :ARRAY, type_node.type == :LIST
484
+ types = each_arg(type_node).map {|node| type_of(node, variables: variables) }
485
+ Types::Tuple.new(types: types, location: nil)
486
+ else
487
+ if proc_type?(type_node)
488
+ Types::Proc.new(type: method_type(nil, type_node, variables: variables).type, location: nil)
489
+ else
490
+ STDERR.puts "Unexpected type_node:"
491
+ PP.pp type_node, STDERR
492
+ Types::Bases::Any.new(location: nil)
493
+ end
494
+ end
495
+ end
496
+
497
+ def proc_type?(type_node)
498
+ if call_node?(type_node, name: :proc)
499
+ true
500
+ else
501
+ type_node.type == :CALL && proc_type?(type_node.children[0])
502
+ end
503
+
504
+ end
505
+
506
+ def call_node?(node, name:, receiver: -> (node) { node.type == :CONST && node.children[0] == :T }, args: -> (node) { true })
507
+ node.type == :CALL && receiver[node.children[0]] && name == node.children[1] && args[node.children[2]]
508
+ end
509
+
510
+ def const_to_name(node)
511
+ case node.type
512
+ when :CONST
513
+ TypeName.new(name: node.children[0], namespace: Namespace.empty)
514
+ when :COLON2
515
+ if node.children[0]
516
+ if node.children[0].type == :COLON3
517
+ namespace = Namespace.root
518
+ else
519
+ namespace = const_to_name(node.children[0]).to_namespace
520
+ end
521
+ else
522
+ namespace = Namespace.empty
523
+ end
524
+
525
+ type_name = TypeName.new(name: node.children[1], namespace: namespace)
526
+
527
+ case type_name.to_s
528
+ when "T::Array"
529
+ BuiltinNames::Array.name
530
+ when "T::Hash"
531
+ BuiltinNames::Hash.name
532
+ when "T::Range"
533
+ BuiltinNames::Range.name
534
+ when "T::Enumerator"
535
+ BuiltinNames::Enumerator.name
536
+ when "T::Enumerable"
537
+ BuiltinNames::Enumerable.name
538
+ when "T::Set"
539
+ BuiltinNames::Set.name
540
+ else
541
+ type_name
542
+ end
543
+ when :COLON3
544
+ TypeName.new(name: node.children[0], namespace: Namespace.root)
545
+ else
546
+ raise "Unexpected node type: #{node.type}"
547
+ end
548
+ end
549
+
550
+ def each_arg(array, &block)
551
+ if block_given?
552
+ if array&.type == :ARRAY || array&.type == :LIST
553
+ array.children.each do |arg|
554
+ if arg
555
+ yield arg
556
+ end
557
+ end
558
+ end
559
+ else
560
+ enum_for :each_arg, array
561
+ end
562
+ end
563
+
564
+ def each_child(node)
565
+ node.children.each do |child|
566
+ if child.is_a?(RubyVM::AbstractSyntaxTree::Node)
567
+ yield child
568
+ end
569
+ end
570
+ end
571
+
572
+ def node_to_hash(node)
573
+ if node&.type == :HASH
574
+ hash = {}
575
+
576
+ each_arg(node.children[0]).each_slice(2) do |var, type|
577
+ if var.type == :LIT && type
578
+ hash[var.children[0]] = type
579
+ end
580
+ end
581
+
582
+ hash
583
+ end
584
+ end
585
+ end
586
+ end
587
+ end