steep 0.11.1 → 0.12.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 (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