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,28 @@
1
+ module Ruby
2
+ module Signature
3
+ class Constant
4
+ attr_reader :name
5
+ attr_reader :type
6
+ attr_reader :declaration
7
+
8
+ def initialize(name:, type:, declaration:)
9
+ @name = name
10
+ @type = type
11
+ @declaration = declaration
12
+ end
13
+
14
+ def ==(other)
15
+ other.is_a?(Constant) &&
16
+ other.name == name &&
17
+ other.type == type &&
18
+ other.declaration == declaration
19
+ end
20
+
21
+ alias eql? ==
22
+
23
+ def hash
24
+ self.class.hash ^ name.hash ^ type.hash ^ declaration.hash
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,152 @@
1
+ module Ruby
2
+ module Signature
3
+ class ConstantTable
4
+ attr_reader :definition_builder
5
+ attr_reader :constant_scopes_cache
6
+
7
+ def env
8
+ definition_builder.env
9
+ end
10
+
11
+ def initialize(builder:)
12
+ @definition_builder = builder
13
+ @constant_scopes_cache = {}
14
+ end
15
+
16
+ def name_to_constant(name)
17
+ case
18
+ when env.name_to_constant.key?(name)
19
+ decl = env.name_to_constant[name]
20
+ type = env.absolute_type(decl.type, namespace: name.namespace) {|type| type.name.absolute! }
21
+ Constant.new(name: name, type: type, declaration: decl)
22
+ when env.class?(name)
23
+ decl = env.name_to_decl[name]
24
+ type = Types::ClassSingleton.new(name: name, location: nil)
25
+ Constant.new(name: name, type: type, declaration: decl)
26
+ end
27
+ end
28
+
29
+ def split_name(name)
30
+ name.namespace.path + [name.name]
31
+ end
32
+
33
+ def resolve_constant_reference(name, context:)
34
+ head, *tail = split_name(name)
35
+
36
+ head_constant = case
37
+ when name.absolute?
38
+ name_to_constant(TypeName.new(name: head, namespace: Namespace.root))
39
+ when !context || context.empty?
40
+ name_to_constant(TypeName.new(name: head, namespace: Namespace.root))
41
+ else
42
+ resolve_constant_reference_context(head, context: context) ||
43
+ resolve_constant_reference_inherit(head,
44
+ scopes: constant_scopes(context.to_type_name))
45
+ end
46
+
47
+ if head_constant
48
+ tail.inject(head_constant) do |constant, name|
49
+ resolve_constant_reference_inherit name,
50
+ scopes: constant_scopes(constant.name),
51
+ no_object: constant.name != BuiltinNames::Object.name
52
+ end
53
+ end
54
+ end
55
+
56
+ def resolve_constant_reference_context(name, context:)
57
+ if context.empty?
58
+ nil
59
+ else
60
+ name_to_constant(TypeName.new(name: name, namespace: context)) ||
61
+ resolve_constant_reference_context(name, context: context.parent)
62
+ end
63
+ end
64
+
65
+ def resolve_constant_reference_inherit(name, scopes:, no_object: false)
66
+ scopes.each do |context|
67
+ if context.path == [:Object]
68
+ unless no_object
69
+ constant = name_to_constant(TypeName.new(name: name, namespace: context)) ||
70
+ name_to_constant(TypeName.new(name: name, namespace: Namespace.root))
71
+ end
72
+ else
73
+ constant = name_to_constant(TypeName.new(name: name, namespace: context))
74
+ end
75
+
76
+ return constant if constant
77
+ end
78
+
79
+ nil
80
+ end
81
+
82
+ def constant_scopes(name)
83
+ constant_scopes_cache[name] ||= constant_scopes0(name, scopes: [])
84
+ end
85
+
86
+ def constant_scopes_module(name, scopes:)
87
+ decl = env.find_class(name)
88
+ namespace = name.to_namespace
89
+
90
+ decl.members.each do |member|
91
+ case member
92
+ when AST::Members::Include
93
+ constant_scopes_module absolute_type_name(member.name, namespace: namespace),
94
+ scopes: scopes
95
+ end
96
+ end
97
+
98
+ scopes.unshift namespace
99
+ end
100
+
101
+ def constant_scopes0(name, scopes: [])
102
+ decl = env.find_class(name)
103
+ namespace = name.to_namespace
104
+
105
+ case decl
106
+ when AST::Declarations::Module
107
+ constant_scopes0 BuiltinNames::Module.name, scopes: scopes
108
+ constant_scopes_module name, scopes: scopes
109
+
110
+ when AST::Declarations::Class
111
+ unless name == BuiltinNames::BasicObject.name
112
+ super_name = decl.super_class&.yield_self {|super_class|
113
+ absolute_type_name(super_class.name, namespace: namespace)
114
+ } || BuiltinNames::Object.name
115
+
116
+ constant_scopes0 super_name, scopes: scopes
117
+ end
118
+
119
+ decl.members.each do |member|
120
+ case member
121
+ when AST::Members::Include
122
+ constant_scopes_module absolute_type_name(member.name, namespace: namespace),
123
+ scopes: scopes
124
+ end
125
+ end
126
+
127
+ scopes.unshift namespace
128
+ else
129
+ raise "Unexpected declaration: #{name}"
130
+ end
131
+
132
+ env.each_extension(name).sort_by {|e| e.extension_name.to_s }.each do |extension|
133
+ extension.members.each do |member|
134
+ case member
135
+ when AST::Members::Include
136
+ constant_scopes_module absolute_type_name(member.name, namespace: namespace),
137
+ scopes: []
138
+ end
139
+ end
140
+ end
141
+
142
+ scopes
143
+ end
144
+
145
+ def absolute_type_name(name, namespace:)
146
+ env.absolute_type_name(name, namespace: namespace) do
147
+ raise
148
+ end
149
+ end
150
+ end
151
+ end
152
+ end
@@ -0,0 +1,172 @@
1
+ module Ruby
2
+ module Signature
3
+ class Definition
4
+ class Variable
5
+ attr_reader :parent_variable
6
+ attr_reader :type
7
+ attr_reader :declared_in
8
+
9
+ def initialize(parent_variable:, type:, declared_in:)
10
+ @parent_variable = parent_variable
11
+ @type = type
12
+ @declared_in = declared_in
13
+ end
14
+ end
15
+
16
+ class Method
17
+ attr_reader :super_method
18
+ attr_reader :method_types
19
+ attr_reader :defined_in
20
+ attr_reader :implemented_in
21
+ attr_reader :accessibility
22
+ attr_reader :attributes
23
+ attr_reader :annotations
24
+ attr_reader :comment
25
+
26
+ def initialize(super_method:, method_types:, defined_in:, implemented_in:, accessibility:, attributes:, annotations:, comment:)
27
+ @super_method = super_method
28
+ @method_types = method_types
29
+ @defined_in = defined_in
30
+ @implemented_in = implemented_in
31
+ @accessibility = accessibility
32
+ @attributes = attributes
33
+ @annotations = annotations
34
+ @comment = comment
35
+ end
36
+
37
+ def public?
38
+ @accessibility == :public
39
+ end
40
+
41
+ def private?
42
+ @accessibility == :private
43
+ end
44
+
45
+ def sub(s)
46
+ self.class.new(
47
+ super_method: super_method&.sub(s),
48
+ method_types: method_types.map {|ty| ty.sub(s) },
49
+ defined_in: defined_in,
50
+ implemented_in: implemented_in,
51
+ accessibility: @accessibility,
52
+ attributes: attributes,
53
+ annotations: annotations,
54
+ comment: comment
55
+ )
56
+ end
57
+
58
+ def map_type(&block)
59
+ self.class.new(
60
+ super_method: super_method&.map_type(&block),
61
+ method_types: method_types.map do |ty|
62
+ ty.map_type(&block)
63
+ end,
64
+ defined_in: defined_in,
65
+ implemented_in: implemented_in,
66
+ accessibility: @accessibility,
67
+ attributes: attributes,
68
+ annotations: annotations,
69
+ comment: comment
70
+ )
71
+ end
72
+ end
73
+
74
+ module Ancestor
75
+ Instance = Struct.new(:name, :args, keyword_init: true)
76
+ Singleton = Struct.new(:name, keyword_init: true)
77
+ ExtensionInstance = Struct.new(:name, :extension_name, :args, keyword_init: true)
78
+ ExtensionSingleton = Struct.new(:name, :extension_name, keyword_init: true)
79
+ end
80
+
81
+ attr_reader :declaration
82
+ attr_reader :self_type
83
+ attr_reader :methods
84
+ attr_reader :instance_variables
85
+ attr_reader :class_variables
86
+ attr_reader :ancestors
87
+
88
+ def initialize(declaration:, self_type:, ancestors:)
89
+ unless declaration.is_a?(AST::Declarations::Class) ||
90
+ declaration.is_a?(AST::Declarations::Module) ||
91
+ declaration.is_a?(AST::Declarations::Interface) ||
92
+ declaration.is_a?(AST::Declarations::Extension)
93
+ raise "Declaration should be a class, module, or interface: #{declaration.name}"
94
+ end
95
+
96
+ unless (self_type.is_a?(Types::ClassSingleton) || self_type.is_a?(Types::Interface) || self_type.is_a?(Types::ClassInstance)) && self_type.name == declaration.name.absolute!
97
+ raise "self_type should be the type of declaration: #{self_type}"
98
+ end
99
+
100
+ @self_type = self_type
101
+ @declaration = declaration
102
+ @methods = {}
103
+ @instance_variables = {}
104
+ @class_variables = {}
105
+ @ancestors = ancestors
106
+ end
107
+
108
+ def name
109
+ declaration.name
110
+ end
111
+
112
+ def class?
113
+ declaration.is_a?(AST::Declarations::Class)
114
+ end
115
+
116
+ def module?
117
+ declaration.is_a?(AST::Declarations::Module)
118
+ end
119
+
120
+ def class_type?
121
+ @self_type.is_a?(Types::ClassSingleton)
122
+ end
123
+
124
+ def instance_type?
125
+ @self_type.is_a?(Types::ClassInstance)
126
+ end
127
+
128
+ def interface_type?
129
+ @self_type.is_a?(Types::Interface)
130
+ end
131
+
132
+ def type_params
133
+ @self_type.args.map(&:name)
134
+ end
135
+
136
+ def type_params_decl
137
+ case declaration
138
+ when AST::Declarations::Extension
139
+ nil
140
+ else
141
+ declaration.type_params
142
+ end
143
+ end
144
+
145
+ def each_type(&block)
146
+ if block_given?
147
+ methods.each_value do |method|
148
+ if method.defined_in == self.declaration
149
+ method.method_types.each do |method_type|
150
+ method_type.each_type(&block)
151
+ end
152
+ end
153
+ end
154
+
155
+ instance_variables.each_value do |var|
156
+ if var.declared_in == self.declaration
157
+ yield var.type
158
+ end
159
+ end
160
+
161
+ class_variables.each_value do |var|
162
+ if var.declared_in == self.declaration
163
+ yield var.type
164
+ end
165
+ end
166
+ else
167
+ enum_for :each_type
168
+ end
169
+ end
170
+ end
171
+ end
172
+ end
@@ -0,0 +1,921 @@
1
+ module Ruby
2
+ module Signature
3
+ class DefinitionBuilder
4
+ attr_reader :env
5
+ attr_reader :instance_cache
6
+ attr_reader :singleton_cache
7
+
8
+ def initialize(env:)
9
+ @env = env
10
+ @instance_cache = {}
11
+ @singleton_cache = {}
12
+ end
13
+
14
+ def build_ancestors(self_ancestor, ancestors: [], building_ancestors: [], location: nil)
15
+ decl = env.find_class(self_ancestor.name)
16
+ namespace = self_ancestor.name.absolute!.to_namespace
17
+
18
+ RecursiveAncestorError.check!(self_ancestor,
19
+ ancestors: building_ancestors,
20
+ location: location || decl.location)
21
+ building_ancestors.push self_ancestor
22
+
23
+ case self_ancestor
24
+ when Definition::Ancestor::Instance
25
+ args = self_ancestor.args
26
+ param_names = decl.type_params.each.map(&:name)
27
+
28
+ InvalidTypeApplicationError.check!(
29
+ type_name: self_ancestor.name,
30
+ args: args,
31
+ params: decl.type_params,
32
+ location: location || decl.location
33
+ )
34
+
35
+ sub = Substitution.build(param_names, args)
36
+
37
+ case decl
38
+ when AST::Declarations::Class
39
+ unless self_ancestor.name == BuiltinNames::BasicObject.name
40
+ super_ancestor = decl.super_class&.yield_self do |super_class|
41
+ Definition::Ancestor::Instance.new(
42
+ name: absolute_type_name(super_class.name, namespace: namespace, location: location || decl.location),
43
+ args: super_class.args.map {|ty| absolute_type(ty.sub(sub), namespace: namespace) }
44
+ )
45
+ end || Definition::Ancestor::Instance.new(name: BuiltinNames::Object.name, args: [])
46
+
47
+ build_ancestors(super_ancestor, ancestors: ancestors, building_ancestors: building_ancestors)
48
+ end
49
+ end
50
+
51
+ decl.members.each do |member|
52
+ case member
53
+ when AST::Members::Include
54
+ if member.name.class?
55
+ ancestor = Definition::Ancestor::Instance.new(
56
+ name: absolute_type_name(member.name, namespace: namespace, location: member.location),
57
+ args: member.args.map {|ty| absolute_type(ty.sub(sub), namespace: namespace) }
58
+ )
59
+ build_ancestors ancestor, ancestors: ancestors, building_ancestors: building_ancestors, location: member.location
60
+ end
61
+ end
62
+ end
63
+
64
+ ancestors.unshift(self_ancestor)
65
+
66
+ env.each_extension(self_ancestor.name).sort_by {|e| e.extension_name.to_s }.each do |extension|
67
+ InvalidExtensionParameterError.check!(
68
+ type_name: self_ancestor.name,
69
+ extension_name: extension.extension_name,
70
+ extension_params: extension.type_params,
71
+ class_params: self_ancestor.args.map(&:name),
72
+ location: extension.location
73
+ )
74
+
75
+ sub = Substitution.build(extension.type_params, self_ancestor.args)
76
+
77
+ extension.members.each do |member|
78
+ case member
79
+ when AST::Members::Include
80
+ if member.name.class?
81
+ ancestor = Definition::Ancestor::Instance.new(
82
+ name: absolute_type_name(member.name, namespace: namespace, location: member.location),
83
+ args: member.args.map {|ty| absolute_type(ty.sub(sub), namespace: namespace) }
84
+ )
85
+ build_ancestors ancestor, ancestors: ancestors, building_ancestors: building_ancestors, location: member.location
86
+ end
87
+ end
88
+ end
89
+
90
+ extension_ancestor = Definition::Ancestor::ExtensionInstance.new(
91
+ name: extension.name.absolute!,
92
+ extension_name: extension.extension_name,
93
+ args: self_ancestor.args,
94
+ )
95
+ ancestors.unshift(extension_ancestor)
96
+
97
+ extension.members.each do |member|
98
+ case member
99
+ when AST::Members::Prepend
100
+ if member.name.class?
101
+ ancestor = Definition::Ancestor::Instance.new(
102
+ name: absolute_type_name(member.name, namespace: namespace, location: member.location),
103
+ args: member.args.map {|ty| absolute_type(ty.sub(sub), namespace: namespace) }
104
+ )
105
+ build_ancestors ancestor, ancestors: ancestors, building_ancestors: building_ancestors, location: member.location
106
+ end
107
+ end
108
+ end
109
+ end
110
+
111
+ decl.members.each do |member|
112
+ case member
113
+ when AST::Members::Prepend
114
+ ancestor = Definition::Ancestor::Instance.new(
115
+ name: absolute_type_name(member.name, namespace: namespace, location: member.location),
116
+ args: member.args.map {|ty| absolute_type(ty.sub(sub), namespace: namespace) }
117
+ )
118
+ build_ancestors ancestor, ancestors: ancestors, building_ancestors: building_ancestors, location: member.location
119
+ end
120
+ end
121
+ when Definition::Ancestor::Singleton
122
+ case decl
123
+ when AST::Declarations::Class
124
+ if self_ancestor.name == BuiltinNames::BasicObject.name
125
+ class_ancestor = Definition::Ancestor::Instance.new(
126
+ name: BuiltinNames::Class.name,
127
+ args: []
128
+ )
129
+ build_ancestors class_ancestor, ancestors: ancestors, building_ancestors: building_ancestors
130
+ else
131
+ super_ancestor = decl.super_class&.yield_self do |super_class|
132
+ Definition::Ancestor::Singleton.new(
133
+ name: absolute_type_name(super_class.name, namespace: namespace, location: location || decl.location)
134
+ )
135
+ end || Definition::Ancestor::Singleton.new(name: BuiltinNames::Object.name)
136
+
137
+ build_ancestors(super_ancestor, ancestors: ancestors, building_ancestors: building_ancestors)
138
+ end
139
+ when AST::Declarations::Module
140
+ module_ancestor = Definition::Ancestor::Instance.new(
141
+ name: BuiltinNames::Module.name,
142
+ args: []
143
+ )
144
+ build_ancestors module_ancestor, ancestors: ancestors, building_ancestors: building_ancestors
145
+ end
146
+
147
+ decl.members.each do |member|
148
+ case member
149
+ when AST::Members::Extend
150
+ if member.name.class?
151
+ ancestor = Definition::Ancestor::Instance.new(
152
+ name: absolute_type_name(member.name, namespace: namespace, location: member.location),
153
+ args: member.args.map {|ty| absolute_type(ty.sub(sub), namespace: namespace) }
154
+ )
155
+ build_ancestors ancestor, ancestors: ancestors, building_ancestors: building_ancestors, location: member.location
156
+ end
157
+ end
158
+ end
159
+
160
+ ancestors.unshift(self_ancestor)
161
+
162
+ env.each_extension(self_ancestor.name).sort_by {|e| e.extension_name.to_s }.each do |extension|
163
+ extension.members.each do |member|
164
+ case member
165
+ when AST::Members::Extend
166
+ if member.name.class?
167
+ ancestor = Definition::Ancestor::Instance.new(
168
+ name: absolute_type_name(member.name, namespace: namespace, location: member.location),
169
+ args: member.args.map {|ty| absolute_type(ty, namespace: namespace) }
170
+ )
171
+ build_ancestors ancestor, ancestors: ancestors, building_ancestors: building_ancestors, location: member.location
172
+ end
173
+ end
174
+ end
175
+
176
+ extension_ancestor = Definition::Ancestor::ExtensionSingleton.new(
177
+ name: extension.name.absolute!,
178
+ extension_name: extension.extension_name
179
+ )
180
+ ancestors.unshift(extension_ancestor)
181
+ end
182
+ end
183
+
184
+ building_ancestors.pop
185
+
186
+ ancestors
187
+ end
188
+
189
+ def each_member_with_accessibility(members, accessibility: :public)
190
+ members.each do |member|
191
+ case member
192
+ when AST::Members::Public
193
+ accessibility = :public
194
+ when AST::Members::Private
195
+ accessibility = :private
196
+ else
197
+ yield member, accessibility
198
+ end
199
+ end
200
+ end
201
+
202
+ def build_instance(type_name)
203
+ try_cache type_name, cache: instance_cache do
204
+ decl = env.find_class(type_name)
205
+ self_ancestor = Definition::Ancestor::Instance.new(name: type_name,
206
+ args: Types::Variable.build(decl.type_params.each.map(&:name)))
207
+ self_type = Types::ClassInstance.new(name: type_name, args: self_ancestor.args, location: nil)
208
+
209
+ case decl
210
+ when AST::Declarations::Class, AST::Declarations::Module
211
+ ancestors = build_ancestors(self_ancestor)
212
+ definition_pairs = ancestors.map do |ancestor|
213
+ case ancestor
214
+ when Definition::Ancestor::Instance
215
+ [ancestor, build_one_instance(ancestor.name)]
216
+ when Definition::Ancestor::Singleton
217
+ [ancestor, build_one_singleton(ancestor.name)]
218
+ when Definition::Ancestor::ExtensionInstance
219
+ [ancestor, build_one_instance(ancestor.name, extension_name: ancestor.extension_name)]
220
+ when Definition::Ancestor::ExtensionSingleton
221
+ [ancestor, build_one_extension_singleton(ancestor.name, extension_name: ancestor.extension_name)]
222
+ end
223
+ end
224
+
225
+ if decl.is_a?(AST::Declarations::Module)
226
+ if decl.self_type
227
+ self_interface = absolute_type(decl.self_type, namespace: type_name.to_namespace)
228
+ ancestor = Definition::Ancestor::Instance.new(name: self_interface.name,
229
+ args: self_interface.args)
230
+
231
+ definition_pairs.push [ancestor, build_one_instance(ancestor.name)]
232
+ end
233
+ end
234
+
235
+ merge_definitions(definition_pairs, decl: decl, self_type: self_type, ancestors: ancestors)
236
+ end
237
+ end
238
+ end
239
+
240
+ def build_singleton(type_name)
241
+ try_cache type_name, cache: singleton_cache do
242
+ decl = env.find_class(type_name)
243
+ self_ancestor = Definition::Ancestor::Singleton.new(name: type_name)
244
+ self_type = Types::ClassSingleton.new(name: type_name, location: nil)
245
+
246
+ case decl
247
+ when AST::Declarations::Class, AST::Declarations::Module
248
+ ancestors = build_ancestors(self_ancestor)
249
+ definition_pairs = ancestors.map do |ancestor|
250
+ case ancestor
251
+ when Definition::Ancestor::Instance
252
+ [ancestor, build_one_instance(ancestor.name)]
253
+ when Definition::Ancestor::Singleton
254
+ [ancestor, build_one_singleton(ancestor.name)]
255
+ when Definition::Ancestor::ExtensionInstance
256
+ [ancestor, build_one_instance(ancestor.name, extension_name: ancestor.extension_name)]
257
+ when Definition::Ancestor::ExtensionSingleton
258
+ [ancestor, build_one_singleton(ancestor.name, extension_name: ancestor.extension_name)]
259
+ end
260
+ end
261
+
262
+ if decl.is_a?(AST::Declarations::Class)
263
+ definition_pairs.find {|ancestor, _| ancestor == self_ancestor }.tap do |_, definition|
264
+ unless definition.methods[:new]&.implemented_in == decl
265
+ instance_definition = build_instance(type_name)
266
+ class_params = decl.type_params.each.map(&:name)
267
+ initialize_method = instance_definition.methods[:initialize]
268
+ method_types = initialize_method.method_types.map do |method_type|
269
+ case method_type
270
+ when MethodType
271
+ fvs = method_type.free_variables + class_params
272
+ unless fvs.empty?
273
+ param_name_set = Set.new(class_params)
274
+ bound_variables = method_type.type_params
275
+ renamed_types = bound_variables.map do |x|
276
+ if param_name_set.member?(x)
277
+ Types::Variable.fresh(x)
278
+ else
279
+ Types::Variable.new(name: x, location: nil)
280
+ end
281
+ end
282
+ sub = Substitution.build(bound_variables, renamed_types)
283
+ method_type_params = renamed_types.unshift(*class_params)
284
+ else
285
+ sub = Substitution.build([], [])
286
+ method_type_params = method_type.type_params
287
+ end
288
+
289
+ MethodType.new(
290
+ type_params: method_type_params,
291
+ type: method_type.type.sub(sub).with_return_type(instance_definition.self_type),
292
+ block: method_type.block&.yield_self {|ty| ty.sub(sub) },
293
+ location: method_type.location
294
+ )
295
+ end
296
+ end.compact
297
+
298
+ definition.methods[:new] = Definition::Method.new(
299
+ super_method: nil,
300
+ defined_in: nil,
301
+ implemented_in: env.find_class(Ruby::Signature::BuiltinNames::Class.name),
302
+ method_types: method_types,
303
+ accessibility: :public,
304
+ attributes: [:incompatible],
305
+ annotations: [],
306
+ comment: nil
307
+ )
308
+ end
309
+ end
310
+ end
311
+
312
+ merge_definitions(definition_pairs, decl: decl, self_type: self_type, ancestors: ancestors)
313
+ end
314
+ end
315
+ end
316
+
317
+ def build_one_instance(type_name, extension_name: nil)
318
+ decl = if extension_name
319
+ env.each_extension(type_name).find {|ext| ext.extension_name == extension_name } or
320
+ raise "Unknown extension: #{type_name} (#{extension_name})"
321
+ else
322
+ env.find_class(type_name)
323
+ end
324
+
325
+ case decl
326
+ when AST::Declarations::Interface
327
+ build_interface type_name, decl
328
+ else
329
+ namespace = type_name.to_namespace
330
+
331
+ case decl
332
+ when AST::Declarations::Class, AST::Declarations::Module
333
+ self_type = Types::ClassInstance.new(name: type_name,
334
+ args: Types::Variable.build(decl.type_params.each.map(&:name)),
335
+ location: nil)
336
+ ancestors = [Definition::Ancestor::Instance.new(name: type_name, args: self_type.args)]
337
+ when AST::Declarations::Extension
338
+ self_type = Types::ClassInstance.new(name: type_name, args: Types::Variable.build(decl.type_params), location: nil)
339
+ ancestors = [Definition::Ancestor::ExtensionInstance.new(name: type_name,
340
+ extension_name: extension_name,
341
+ args: self_type.args)]
342
+ end
343
+
344
+ Definition.new(declaration: decl, self_type: self_type, ancestors: ancestors).tap do |definition|
345
+ alias_members = []
346
+
347
+ each_member_with_accessibility(decl.members) do |member, accessibility|
348
+ case member
349
+ when AST::Members::MethodDefinition
350
+ if member.instance?
351
+ name = member.name
352
+ method_types = member.types.map do |method_type|
353
+ case method_type
354
+ when MethodType
355
+ method_type.map_type do |type|
356
+ absolute_type(type, namespace: namespace)
357
+ end
358
+ when :super
359
+ :super
360
+ end
361
+ end
362
+
363
+ DuplicatedMethodDefinitionError.check!(
364
+ decl: decl,
365
+ methods: definition.methods,
366
+ name: name,
367
+ location: member.location
368
+ )
369
+
370
+ attrs = if name == :initialize
371
+ (member.attributes + [:incompatible]).uniq
372
+ else
373
+ member.attributes
374
+ end
375
+
376
+ definition.methods[name] = Definition::Method.new(super_method: nil,
377
+ method_types: method_types,
378
+ defined_in: decl,
379
+ implemented_in: decl,
380
+ accessibility: accessibility,
381
+ attributes: attrs,
382
+ annotations: member.annotations,
383
+ comment: member.comment)
384
+ end
385
+ when AST::Members::AttrReader, AST::Members::AttrAccessor, AST::Members::AttrWriter
386
+ name = member.name
387
+ type = absolute_type(member.type, namespace: namespace)
388
+ ivar_name = case member.ivar_name
389
+ when false
390
+ nil
391
+ else
392
+ member.ivar_name || :"@#{member.name}"
393
+ end
394
+
395
+ if member.is_a?(AST::Members::AttrReader) || member.is_a?(AST::Members::AttrAccessor)
396
+ definition.methods[name] = Definition::Method.new(
397
+ super_method: nil,
398
+ method_types: [
399
+ MethodType.new(
400
+ type_params: [],
401
+ type: Types::Function.empty(type),
402
+ block: nil,
403
+ location: nil
404
+ )
405
+ ],
406
+ defined_in: decl,
407
+ implemented_in: decl,
408
+ accessibility: accessibility,
409
+ attributes: [],
410
+ annotations: member.annotations,
411
+ comment: member.comment
412
+ )
413
+ end
414
+
415
+ if member.is_a?(AST::Members::AttrWriter) || member.is_a?(AST::Members::AttrAccessor)
416
+ definition.methods[:"#{name}="] = Definition::Method.new(
417
+ super_method: nil,
418
+ method_types: [
419
+ MethodType.new(
420
+ type_params: [],
421
+ type: Types::Function.new(required_positionals: [Types::Function::Param.new(name: name, type: type)],
422
+ optional_positionals: [],
423
+ rest_positionals: nil,
424
+ trailing_positionals: [],
425
+ required_keywords: {},
426
+ optional_keywords: {},
427
+ rest_keywords: nil,
428
+ return_type: type),
429
+ block: nil,
430
+ location: nil
431
+ )
432
+ ],
433
+ defined_in: decl,
434
+ implemented_in: decl,
435
+ accessibility: accessibility,
436
+ attributes: [],
437
+ annotations: member.annotations,
438
+ comment: member.comment
439
+ )
440
+ end
441
+
442
+ if ivar_name
443
+ definition.instance_variables[ivar_name] = Definition::Variable.new(
444
+ parent_variable: nil,
445
+ type: type,
446
+ declared_in: decl
447
+ )
448
+ end
449
+
450
+ when AST::Members::Alias
451
+ if member.instance?
452
+ alias_members << member
453
+ end
454
+ when AST::Members::Include
455
+ if member.name.interface?
456
+ absolute_name = absolute_type_name(member.name, namespace: namespace, location: member.location)
457
+ interface_definition = build_one_instance(absolute_name)
458
+ absolute_args = member.args.map {|ty| absolute_type(ty, namespace: namespace) }
459
+
460
+ InvalidTypeApplicationError.check!(
461
+ type_name: absolute_name,
462
+ args: absolute_args,
463
+ params: interface_definition.type_params_decl,
464
+ location: member.location
465
+ )
466
+
467
+ sub = Substitution.build(interface_definition.type_params, absolute_args)
468
+ interface_definition.methods.each do |name, method|
469
+ method_types = method.method_types.map do |method_type|
470
+ method_type.sub(sub).map_type do |type|
471
+ absolute_type(type, namespace: namespace)
472
+ end
473
+ end
474
+
475
+ DuplicatedMethodDefinitionError.check!(
476
+ decl: decl,
477
+ methods: definition.methods,
478
+ name: name,
479
+ location: member.location
480
+ )
481
+
482
+ definition.methods[name] = Definition::Method.new(
483
+ super_method: nil,
484
+ method_types: method_types,
485
+ defined_in: method.defined_in,
486
+ implemented_in: decl,
487
+ accessibility: method.accessibility,
488
+ attributes: [],
489
+ annotations: method.annotations,
490
+ comment: member.comment
491
+ )
492
+ end
493
+ end
494
+ when AST::Members::InstanceVariable
495
+ definition.instance_variables[member.name] = Definition::Variable.new(
496
+ type: absolute_type(member.type, namespace: namespace),
497
+ parent_variable: nil,
498
+ declared_in: decl
499
+ )
500
+ when AST::Members::ClassVariable
501
+ definition.class_variables[member.name] = Definition::Variable.new(
502
+ type: absolute_type(member.type, namespace: namespace),
503
+ parent_variable: nil,
504
+ declared_in: decl
505
+ )
506
+ end
507
+ end
508
+
509
+ alias_members.each do |member|
510
+ UnknownMethodAliasError.check!(
511
+ methods: definition.methods,
512
+ original_name: member.old_name,
513
+ aliased_name: member.new_name,
514
+ location: member.location
515
+ )
516
+
517
+ DuplicatedMethodDefinitionError.check!(
518
+ decl: decl,
519
+ methods: definition.methods,
520
+ name: member.new_name,
521
+ location: member.location
522
+ )
523
+
524
+ # FIXME: may cause a problem if #old_name has super type
525
+ definition.methods[member.new_name] = definition.methods[member.old_name]
526
+ end
527
+
528
+ validate_parameter_variance(
529
+ decl: decl,
530
+ methods: definition.methods
531
+ )
532
+ end
533
+ end
534
+ end
535
+
536
+ def validate_params_with(type_params, result:)
537
+ type_params.each do |param|
538
+ unless param.skip_validation
539
+ unless result.compatible?(param.name, with_annotation: param.variance)
540
+ yield param
541
+ end
542
+ end
543
+ end
544
+ end
545
+
546
+ def validate_parameter_variance(decl:, methods:)
547
+ type_params = case decl
548
+ when AST::Declarations::Extension
549
+ env.find_class(decl.name.absolute!).type_params.rename_to(decl.type_params)
550
+ else
551
+ decl.type_params
552
+ end
553
+
554
+ namespace = decl.name.absolute!.to_namespace
555
+ calculator = VarianceCalculator.new(builder: self)
556
+ param_names = type_params.each.map(&:name)
557
+
558
+ errors = []
559
+
560
+ if decl.is_a?(AST::Declarations::Class)
561
+ if decl.super_class
562
+ absolute_super_name = absolute_type_name(decl.super_class.name, namespace: namespace, location: decl.location)
563
+ absolute_args = decl.super_class.args.map {|type| absolute_type(type, namespace: namespace) }
564
+ result = calculator.in_inherit(name: absolute_super_name, args: absolute_args, variables: param_names)
565
+
566
+ validate_params_with type_params, result: result do |param|
567
+ errors.push InvalidVarianceAnnotationError::InheritanceError.new(
568
+ param: param
569
+ )
570
+ end
571
+ end
572
+ end
573
+
574
+ decl.members.each do |member|
575
+ case member
576
+ when AST::Members::Include
577
+ if member.name.class?
578
+ absolute_module_name = absolute_type_name(member.name, namespace: namespace, location: decl.location)
579
+ absolute_args = member.args.map {|type| absolute_type(type, namespace: namespace) }
580
+ result = calculator.in_inherit(name: absolute_module_name, args: absolute_args, variables: param_names)
581
+
582
+ validate_params_with type_params, result: result do |param|
583
+ errors.push InvalidVarianceAnnotationError::MixinError.new(
584
+ include_member: member,
585
+ param: param
586
+ )
587
+ end
588
+ end
589
+ end
590
+ end
591
+
592
+ methods.each do |name, method|
593
+ method.method_types.each do |method_type|
594
+ case method_type
595
+ when MethodType
596
+ result = calculator.in_method_type(method_type: method_type, variables: param_names)
597
+
598
+ validate_params_with type_params, result: result do |param|
599
+ errors.push InvalidVarianceAnnotationError::MethodTypeError.new(
600
+ method_name: name,
601
+ method_type: method_type,
602
+ param: param
603
+ )
604
+ end
605
+ end
606
+ end
607
+ end
608
+
609
+ unless errors.empty?
610
+ raise InvalidVarianceAnnotationError.new(decl: decl, errors: errors)
611
+ end
612
+ end
613
+
614
+ def build_one_singleton(type_name, extension_name: nil)
615
+ decl = if extension_name
616
+ env.each_extension(type_name).find {|ext| ext.extension_name == extension_name } or
617
+ raise "Unknown extension: #{type_name} (#{extension_name})"
618
+ else
619
+ env.find_class(type_name)
620
+ end
621
+
622
+ namespace = type_name.to_namespace
623
+
624
+ case decl
625
+ when AST::Declarations::Module, AST::Declarations::Class
626
+ self_type = Types::ClassSingleton.new(name: type_name, location: nil)
627
+ ancestors = [Definition::Ancestor::Singleton.new(name: type_name)]
628
+ when AST::Declarations::Extension
629
+ self_type = Types::ClassSingleton.new(name: type_name, location: nil)
630
+ ancestors = [Definition::Ancestor::ExtensionSingleton.new(name: type_name, extension_name: extension_name)]
631
+ end
632
+
633
+ Definition.new(declaration: decl, self_type: self_type, ancestors: ancestors).tap do |definition|
634
+ alias_members = []
635
+
636
+ each_member_with_accessibility(decl.members) do |member, accessibility|
637
+ case member
638
+ when AST::Members::MethodDefinition
639
+ if member.singleton?
640
+ name = member.name
641
+ method_types = member.types.map do |method_type|
642
+ method_type.map_type do |type|
643
+ absolute_type(type, namespace: namespace)
644
+ end
645
+ end
646
+
647
+ DuplicatedMethodDefinitionError.check!(
648
+ decl: decl,
649
+ methods: definition.methods,
650
+ name: name,
651
+ location: member.location
652
+ )
653
+
654
+ definition.methods[name] = Definition::Method.new(super_method: nil,
655
+ method_types: method_types,
656
+ defined_in: decl,
657
+ implemented_in: decl,
658
+ accessibility: accessibility,
659
+ attributes: member.attributes,
660
+ annotations: member.annotations,
661
+ comment: member.comment)
662
+ end
663
+ when AST::Members::Alias
664
+ if member.singleton?
665
+ alias_members << member
666
+ end
667
+ when AST::Members::Extend
668
+ if member.name.interface?
669
+ absolute_name = absolute_type_name(member.name, namespace: namespace, location: member.location)
670
+ interface_definition = build_one_instance(absolute_name)
671
+ absolute_args = member.args.map {|ty| absolute_type(ty, namespace: namespace) }
672
+
673
+ InvalidTypeApplicationError.check!(
674
+ type_name: absolute_name,
675
+ args: absolute_args,
676
+ params: interface_definition.type_params_decl,
677
+ location: member.location
678
+ )
679
+
680
+ sub = Substitution.build(interface_definition.type_params, absolute_args)
681
+ interface_definition.methods.each do |name, method|
682
+ method_types = method.method_types.map do |method_type|
683
+ method_type.sub(sub).map_type do |type|
684
+ absolute_type(type, namespace: namespace)
685
+ end
686
+ end
687
+
688
+ DuplicatedMethodDefinitionError.check!(
689
+ decl: decl,
690
+ methods: definition.methods,
691
+ name: name,
692
+ location: member.location
693
+ )
694
+
695
+ definition.methods[name] = Definition::Method.new(
696
+ super_method: nil,
697
+ method_types: method_types,
698
+ defined_in: method.defined_in,
699
+ implemented_in: decl,
700
+ accessibility: method.accessibility,
701
+ attributes: method.attributes,
702
+ annotations: method.annotations,
703
+ comment: member.comment
704
+ )
705
+ end
706
+ end
707
+ when AST::Members::ClassInstanceVariable
708
+ definition.instance_variables[member.name] = Definition::Variable.new(
709
+ type: absolute_type(member.type, namespace: namespace),
710
+ parent_variable: nil,
711
+ declared_in: decl
712
+ )
713
+ when AST::Members::ClassVariable
714
+ definition.class_variables[member.name] = Definition::Variable.new(
715
+ type: absolute_type(member.type, namespace: namespace),
716
+ parent_variable: nil,
717
+ declared_in: decl
718
+ )
719
+ end
720
+ end
721
+
722
+ alias_members.each do |member|
723
+ UnknownMethodAliasError.check!(
724
+ methods: definition.methods,
725
+ original_name: member.old_name,
726
+ aliased_name: member.new_name,
727
+ location: member.location
728
+ )
729
+
730
+ DuplicatedMethodDefinitionError.check!(
731
+ decl: decl,
732
+ methods: definition.methods,
733
+ name: member.new_name,
734
+ location: member.location
735
+ )
736
+
737
+ # FIXME: may cause a problem if #old_name has super type
738
+ definition.methods[member.new_name] = definition.methods[member.old_name]
739
+ end
740
+ end
741
+ end
742
+
743
+ def merge_definitions(pairs, decl:, self_type:, ancestors:)
744
+ Definition.new(declaration: decl, self_type: self_type, ancestors: ancestors).tap do |definition|
745
+ pairs.reverse_each do |(ancestor, current_definition)|
746
+ sub = case ancestor
747
+ when Definition::Ancestor::Instance, Definition::Ancestor::ExtensionInstance
748
+ Substitution.build(current_definition.type_params, ancestor.args)
749
+ when Definition::Ancestor::Singleton, Definition::Ancestor::ExtensionSingleton
750
+ Substitution.build([], [])
751
+ end
752
+ namespace = current_definition.name.absolute!.to_namespace
753
+
754
+ current_definition.methods.each do |name, method|
755
+ merge_method definition.methods, name, method, sub, namespace
756
+ end
757
+
758
+ current_definition.instance_variables.each do |name, variable|
759
+ merge_variable definition.instance_variables, name, variable
760
+ end
761
+
762
+ current_definition.class_variables.each do |name, variable|
763
+ merge_variable definition.class_variables, name, variable
764
+ end
765
+ end
766
+ end
767
+ end
768
+
769
+ def merge_variable(variables, name, variable)
770
+ super_variable = variables[name]
771
+
772
+ variables[name] = Definition::Variable.new(
773
+ parent_variable: super_variable,
774
+ type: variable.type,
775
+ declared_in: variable.declared_in
776
+ )
777
+ end
778
+
779
+ def merge_method(methods, name, method, sub, namespace)
780
+ super_method = methods[name]
781
+
782
+ methods[name] = Definition::Method.new(
783
+ method_types: method.method_types.flat_map do |method_type|
784
+ case method_type
785
+ when MethodType
786
+ [absolute_type(method_type.sub(sub), namespace: namespace)]
787
+ when :super
788
+ super_method.method_types
789
+ end
790
+ end,
791
+ super_method: super_method,
792
+ defined_in: method.defined_in,
793
+ implemented_in: method.implemented_in,
794
+ accessibility: method.accessibility,
795
+ attributes: method.attributes,
796
+ annotations: method.annotations,
797
+ comment: method.comment
798
+ )
799
+ end
800
+
801
+ def try_cache(type_name, cache:)
802
+ cached = cache[type_name]
803
+
804
+ case cached
805
+ when Definition
806
+ cached
807
+ when false
808
+ raise
809
+ when nil
810
+ cache[type_name] = false
811
+ begin
812
+ cache[type_name] = yield
813
+ rescue => ex
814
+ cache[type_name] = nil
815
+ raise ex
816
+ end
817
+ end
818
+ end
819
+
820
+ def build_interface(type_name, declaration)
821
+ self_type = Types::Interface.new(
822
+ name: type_name,
823
+ args: declaration.type_params.each.map {|p| Types::Variable.new(name: p.name, location: nil) },
824
+ location: nil
825
+ )
826
+
827
+ namespace = type_name.to_namespace
828
+
829
+ Definition.new(declaration: declaration, self_type: self_type, ancestors: []).tap do |definition|
830
+ alias_members = []
831
+
832
+ declaration.members.each do |member|
833
+ case member
834
+ when AST::Members::Include
835
+ mixin_name = env.absolute_interface_name(member.name, namespace: namespace) || member.name.absolute!
836
+ mixin = build_one_instance(mixin_name)
837
+
838
+ args = member.args.map {|type| absolute_type(type, namespace: namespace) }
839
+ type_params = mixin.declaration.type_params
840
+
841
+ InvalidTypeApplicationError.check!(
842
+ type_name: type_name,
843
+ args: args,
844
+ params: type_params,
845
+ location: member.location
846
+ )
847
+
848
+ sub = Substitution.build(type_params.each.map(&:name), args)
849
+ mixin.methods.each do |name, method|
850
+ definition.methods[name] = method.sub(sub)
851
+ end
852
+ end
853
+ end
854
+
855
+ declaration.members.each do |member|
856
+ case member
857
+ when AST::Members::MethodDefinition
858
+ DuplicatedMethodDefinitionError.check!(
859
+ decl: declaration,
860
+ methods: definition.methods,
861
+ name: member.name,
862
+ location: member.location
863
+ )
864
+
865
+ method = Definition::Method.new(
866
+ super_method: nil,
867
+ method_types: member.types.map do |method_type|
868
+ method_type.map_type {|ty| absolute_type(ty, namespace: namespace) }
869
+ end,
870
+ defined_in: declaration,
871
+ implemented_in: nil,
872
+ accessibility: :public,
873
+ attributes: member.attributes,
874
+ annotations: member.annotations,
875
+ comment: member.comment
876
+ )
877
+ definition.methods[member.name] = method
878
+ when AST::Members::Alias
879
+ alias_members << member
880
+ end
881
+ end
882
+
883
+ alias_members.each do |member|
884
+ UnknownMethodAliasError.check!(
885
+ methods: definition.methods,
886
+ original_name: member.old_name,
887
+ aliased_name: member.new_name,
888
+ location: member.location
889
+ )
890
+
891
+ DuplicatedMethodDefinitionError.check!(
892
+ decl: declaration,
893
+ methods: definition.methods,
894
+ name: member.new_name,
895
+ location: member.location
896
+ )
897
+
898
+ # FIXME: may cause a problem if #old_name has super type
899
+ definition.methods[member.new_name] = definition.methods[member.old_name]
900
+ end
901
+ end
902
+ end
903
+
904
+ def absolute_type(type, namespace:)
905
+ env.absolute_type(type, namespace: namespace) do |type|
906
+ NoTypeFoundError.check!(type.name.absolute!, env: env, location: type.location)
907
+ end
908
+ end
909
+
910
+ def absolute_type_name(type_name, namespace:, location:)
911
+ env.absolute_type_name(type_name, namespace: namespace) do |type_name|
912
+ NoTypeFoundError.check!(type_name.absolute!, env: env, location: location)
913
+ end
914
+ end
915
+
916
+ def expand_alias(type_name)
917
+ absolute_type(env.find_alias(type_name).type, namespace: type_name.namespace)
918
+ end
919
+ end
920
+ end
921
+ end