steep 0.11.1 → 0.12.0

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