rbs 0.2.0

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 (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