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,189 @@
1
+ module Ruby
2
+ module Signature
3
+ class InvalidTypeApplicationError < StandardError
4
+ attr_reader :type_name
5
+ attr_reader :args
6
+ attr_reader :params
7
+ attr_reader :location
8
+
9
+ def initialize(type_name:, args:, params:, location:)
10
+ @type_name = type_name
11
+ @args = args
12
+ @params = params
13
+ @location = location
14
+ super "#{Location.to_string location}: #{type_name} expects parameters [#{params.each.map(&:name).join(", ")}], but given args [#{args.join(", ")}]"
15
+ end
16
+
17
+ def self.check!(type_name:, args:, params:, location:)
18
+ unless args.size == params.size
19
+ raise new(type_name: type_name, args: args, params: params, location: location)
20
+ end
21
+ end
22
+ end
23
+
24
+ class InvalidExtensionParameterError < StandardError
25
+ attr_reader :type_name
26
+ attr_reader :extension_name
27
+ attr_reader :location
28
+ attr_reader :extension_params
29
+ attr_reader :class_params
30
+
31
+ def initialize(type_name:, extension_name:, extension_params:, class_params:, location:)
32
+ @type_name = type_name
33
+ @extension_name = extension_name
34
+ @extension_params = extension_params
35
+ @class_params = class_params
36
+ @location = location
37
+
38
+ super "#{Location.to_string location}: Expected #{class_params.size} parameters to #{type_name} (#{extension_name}) but has #{extension_params.size} parameters"
39
+ end
40
+
41
+ def self.check!(type_name:, extension_name:, extension_params:, class_params:, location:)
42
+ unless extension_params.size == class_params.size
43
+ raise new(type_name: type_name,
44
+ extension_name: extension_name,
45
+ extension_params: extension_params,
46
+ class_params: class_params,
47
+ location: location)
48
+ end
49
+ end
50
+ end
51
+
52
+ class RecursiveAncestorError < StandardError
53
+ attr_reader :ancestors
54
+ attr_reader :location
55
+
56
+ def initialize(ancestors:, location:)
57
+ last = case last = ancestors.last
58
+ when Definition::Ancestor::Singleton
59
+ "singleton(#{last.name})"
60
+ when Definition::Ancestor::Instance
61
+ if last.args.empty?
62
+ last.name.to_s
63
+ else
64
+ "#{last.name}[#{last.args.join(", ")}]"
65
+ end
66
+ end
67
+
68
+ super "#{Location.to_string location}: Detected recursive ancestors: #{last}"
69
+ end
70
+
71
+ def self.check!(self_ancestor, ancestors:, location:)
72
+ case self_ancestor
73
+ when Definition::Ancestor::Instance
74
+ if ancestors.any? {|a| a.is_a?(Definition::Ancestor::Instance) && a.name == self_ancestor.name }
75
+ raise new(ancestors: ancestors + [self_ancestor], location: location)
76
+ end
77
+ when Definition::Ancestor::Singleton
78
+ if ancestors.include?(self_ancestor)
79
+ raise new(ancestors: ancestors + [self_ancestor], location: location)
80
+ end
81
+ end
82
+ end
83
+ end
84
+
85
+ class NoTypeFoundError < StandardError
86
+ attr_reader :type_name
87
+ attr_reader :location
88
+
89
+ def initialize(type_name:, location:)
90
+ @type_name = type_name
91
+ @location = location
92
+
93
+ super "#{Location.to_string location}: Could not find #{type_name}"
94
+ end
95
+
96
+ def self.check!(type_name, env:, location:)
97
+ env.find_type_decl(type_name) or
98
+ raise new(type_name: type_name, location: location)
99
+
100
+ type_name
101
+ end
102
+ end
103
+
104
+ class DuplicatedMethodDefinitionError < StandardError
105
+ attr_reader :decl
106
+ attr_reader :location
107
+
108
+ def initialize(decl:, name:, location:)
109
+ decl_str = case decl
110
+ when AST::Declarations::Interface, AST::Declarations::Class, AST::Declarations::Module
111
+ decl.name.to_s
112
+ when AST::Declarations::Extension
113
+ "#{decl.name} (#{decl.extension_name})"
114
+ end
115
+
116
+ super "#{Location.to_string location}: #{decl_str} has duplicated method definition: #{name}"
117
+ end
118
+
119
+ def self.check!(decl:, methods:, name:, location:)
120
+ if methods.key?(name)
121
+ raise new(decl: decl, name: name, location: location)
122
+ end
123
+ end
124
+ end
125
+
126
+ class UnknownMethodAliasError < StandardError
127
+ attr_reader :original_name
128
+ attr_reader :aliased_name
129
+ attr_reader :location
130
+
131
+ def initialize(original_name:, aliased_name:, location:)
132
+ @original_name = original_name
133
+ @aliased_name = aliased_name
134
+ @location = location
135
+
136
+ super "#{Location.to_string location}: Unknown method alias name: #{original_name} => #{aliased_name}"
137
+ end
138
+
139
+ def self.check!(methods:, original_name:, aliased_name:, location:)
140
+ unless methods.key?(original_name)
141
+ raise new(original_name: original_name, aliased_name: aliased_name, location: location)
142
+ end
143
+ end
144
+ end
145
+
146
+ class DuplicatedDeclarationError < StandardError
147
+ attr_reader :name
148
+ attr_reader :decls
149
+
150
+ def initialize(name, *decls)
151
+ @name = name
152
+ @decls = decls
153
+
154
+ super "#{Location.to_string decls.last.location}: Duplicated declaration: #{name}"
155
+ end
156
+ end
157
+
158
+ class InvalidVarianceAnnotationError < StandardError
159
+ MethodTypeError = Struct.new(:method_name, :method_type, :param, keyword_init: true)
160
+ InheritanceError = Struct.new(:super_class, :param, keyword_init: true)
161
+ MixinError = Struct.new(:include_member, :param, keyword_init: true)
162
+
163
+ attr_reader :decl
164
+ attr_reader :errors
165
+
166
+ def initialize(decl:, errors:)
167
+ @decl = decl
168
+ @errors = errors
169
+
170
+ message = [
171
+ "#{Location.to_string decl.location}: Invalid variance annotation: #{decl.name}"
172
+ ]
173
+
174
+ errors.each do |error|
175
+ case error
176
+ when MethodTypeError
177
+ message << " MethodTypeError (#{error.param.name}): on `#{error.method_name}` #{error.method_type.to_s} (#{error.method_type.location&.start_line})"
178
+ when InheritanceError
179
+ message << " InheritanceError: #{error.super_class}"
180
+ when MixinError
181
+ message << " MixinError: #{error.include_member.name} (#{error.include_member.location&.start_line})"
182
+ end
183
+ end
184
+
185
+ super message.join("\n")
186
+ end
187
+ end
188
+ end
189
+ end
@@ -0,0 +1,104 @@
1
+ module Ruby
2
+ module Signature
3
+ class Location
4
+ attr_reader :buffer
5
+ attr_reader :start_pos
6
+ attr_reader :end_pos
7
+
8
+ def initialize(buffer:, start_pos:, end_pos:)
9
+ @buffer = buffer
10
+ @start_pos = start_pos
11
+ @end_pos = end_pos
12
+ end
13
+
14
+ def inspect
15
+ "#<#{self.class}:#{self.__id__} @buffer=#{buffer.name}, @pos=#{start_pos}...#{end_pos}, source='#{source.lines.first}', start_line=#{start_line}, start_column=#{start_column}>"
16
+ end
17
+
18
+ def name
19
+ buffer.name
20
+ end
21
+
22
+ def start_line
23
+ start_loc[0]
24
+ end
25
+
26
+ def start_column
27
+ start_loc[1]
28
+ end
29
+
30
+ def end_line
31
+ end_loc[0]
32
+ end
33
+
34
+ def end_column
35
+ end_loc[1]
36
+ end
37
+
38
+ def start_loc
39
+ @start_loc ||= buffer.pos_to_loc(start_pos)
40
+ end
41
+
42
+ def end_loc
43
+ @end_loc ||= buffer.pos_to_loc(end_pos)
44
+ end
45
+
46
+ def source
47
+ @source ||= buffer.content[start_pos...end_pos]
48
+ end
49
+
50
+ def to_s
51
+ "#{name || "-"}:#{start_line}:#{start_column}...#{end_line}:#{end_column}"
52
+ end
53
+
54
+ def self.to_string(location, default: "*:*:*...*:*")
55
+ location&.to_s || default
56
+ end
57
+
58
+ def ==(other)
59
+ other.is_a?(Location) &&
60
+ other.buffer == buffer &&
61
+ other.start_pos == start_pos &&
62
+ other.end_pos == end_pos
63
+ end
64
+
65
+ def +(other)
66
+ if other
67
+ raise "Invalid concat: buffer=#{buffer.name}, other.buffer=#{other.buffer.name}" unless other.buffer == buffer
68
+
69
+ self.class.new(buffer: buffer,
70
+ start_pos: start_pos,
71
+ end_pos: other.end_pos)
72
+ else
73
+ self
74
+ end
75
+ end
76
+
77
+ def self.concat(*locations)
78
+ locations.inject {|l1, l2| l1 + l2 }
79
+ end
80
+
81
+ def pred?(loc)
82
+ loc.is_a?(Location) &&
83
+ loc.name == name &&
84
+ loc.start_pos == end_pos
85
+ end
86
+
87
+ def to_json(*args)
88
+ {
89
+ start: {
90
+ line: start_line,
91
+ column: start_column
92
+ },
93
+ end: {
94
+ line: end_line,
95
+ column: end_column
96
+ },
97
+ buffer: {
98
+ name: name&.to_s
99
+ }
100
+ }.to_json(*args)
101
+ end
102
+ end
103
+ end
104
+ end
@@ -0,0 +1,125 @@
1
+ module Ruby
2
+ module Signature
3
+ class MethodType
4
+ class Block
5
+ attr_reader :type
6
+ attr_reader :required
7
+
8
+ def initialize(type:, required:)
9
+ @type = type
10
+ @required = required
11
+ end
12
+
13
+ def ==(other)
14
+ other.is_a?(Block) &&
15
+ other.type == type &&
16
+ other.required == required
17
+ end
18
+
19
+ def to_json(*a)
20
+ {
21
+ type: type,
22
+ required: required
23
+ }.to_json(*a)
24
+ end
25
+
26
+ def sub(s)
27
+ self.class.new(
28
+ type: type.sub(s),
29
+ required: required
30
+ )
31
+ end
32
+ end
33
+
34
+ attr_reader :type_params
35
+ attr_reader :type
36
+ attr_reader :block
37
+ attr_reader :location
38
+
39
+ def initialize(type_params:, type:, block:, location:)
40
+ @type_params = type_params
41
+ @type = type
42
+ @block = block
43
+ @location = location
44
+ end
45
+
46
+ def ==(other)
47
+ other.is_a?(MethodType) &&
48
+ other.type_params == type_params &&
49
+ other.type == type &&
50
+ other.block == block
51
+ end
52
+
53
+ def to_json(*a)
54
+ {
55
+ type_params: type_params,
56
+ type: type,
57
+ block: block,
58
+ location: location
59
+ }.to_json(*a)
60
+ end
61
+
62
+ def sub(s)
63
+ s.without(*type_params).yield_self do |sub|
64
+ map_type do |ty|
65
+ ty.sub(sub)
66
+ end
67
+ end
68
+ end
69
+
70
+ def update(type_params: self.type_params, type: self.type, block: self.block, location: self.location)
71
+ self.class.new(
72
+ type_params: type_params,
73
+ type: type,
74
+ block: block,
75
+ location: location
76
+ )
77
+ end
78
+
79
+ def free_variables(set = Set.new)
80
+ type.free_variables(set)
81
+ block&.type&.free_variables(set)
82
+ set.subtract(type_params)
83
+ end
84
+
85
+ def map_type(&block)
86
+ self.class.new(
87
+ type_params: type_params,
88
+ type: type.map_type(&block),
89
+ block: self.block&.yield_self do |b|
90
+ Block.new(type: b.type.map_type(&block), required: b.required)
91
+ end,
92
+ location: location
93
+ )
94
+ end
95
+
96
+ def each_type(&block)
97
+ if block_given?
98
+ type.each_type(&block)
99
+ self.block&.yield_self do |b|
100
+ b.type.each_type(&block)
101
+ end
102
+ else
103
+ enum_for :each_type
104
+ end
105
+ end
106
+
107
+ def to_s
108
+ s = case
109
+ when block && block.required
110
+ "(#{type.param_to_s}) { (#{block.type.param_to_s}) -> #{block.type.return_to_s} } -> #{type.return_to_s}"
111
+ when block
112
+ "(#{type.param_to_s}) ?{ (#{block.type.param_to_s}) -> #{block.type.return_to_s} } -> #{type.return_to_s}"
113
+ else
114
+ "(#{type.param_to_s}) -> #{type.return_to_s}"
115
+ end
116
+
117
+ if type_params.empty?
118
+ s
119
+ else
120
+ "[#{type_params.join(", ")}] #{s}"
121
+ end
122
+ end
123
+ end
124
+ end
125
+ end
@@ -0,0 +1,93 @@
1
+ module Ruby
2
+ module Signature
3
+ class Namespace
4
+ attr_reader :path
5
+
6
+ def initialize(path:, absolute:)
7
+ @path = path
8
+ @absolute = absolute
9
+ end
10
+
11
+ def self.empty
12
+ new(path: [], absolute: false)
13
+ end
14
+
15
+ def self.root
16
+ new(path: [], absolute: true)
17
+ end
18
+
19
+ def +(other)
20
+ if other.absolute?
21
+ other
22
+ else
23
+ self.class.new(path: path + other.path, absolute: absolute?)
24
+ end
25
+ end
26
+
27
+ def append(component)
28
+ self.class.new(path: path + [component], absolute: absolute?)
29
+ end
30
+
31
+ def parent
32
+ raise "Parent with empty namespace" if empty?
33
+ self.class.new(path: path.take(path.size - 1), absolute: absolute?)
34
+ end
35
+
36
+ def absolute?
37
+ @absolute
38
+ end
39
+
40
+ def relative?
41
+ !absolute?
42
+ end
43
+
44
+ def absolute!
45
+ self.class.new(path: path, absolute: true)
46
+ end
47
+
48
+ def relative!
49
+ self.class.new(path: path, absolute: false)
50
+ end
51
+
52
+ def empty?
53
+ path.empty?
54
+ end
55
+
56
+ def ==(other)
57
+ other.is_a?(Namespace) && other.path == path && other.absolute? == absolute?
58
+ end
59
+
60
+ alias eql? ==
61
+
62
+ def hash
63
+ self.class.hash ^ path.hash ^ absolute?.hash
64
+ end
65
+
66
+ def split
67
+ [parent, path.last]
68
+ end
69
+
70
+ def to_s
71
+ if empty?
72
+ absolute? ? "::" : ""
73
+ else
74
+ s = path.join("::")
75
+ absolute? ? "::#{s}::" : "#{s}::"
76
+ end
77
+ end
78
+
79
+ def to_type_name
80
+ parent, name = split
81
+ TypeName.new(name: name, namespace: parent)
82
+ end
83
+
84
+ def self.parse(string)
85
+ if string.start_with?("::")
86
+ new(path: string.split("::").drop(1).map(&:to_sym), absolute: true)
87
+ else
88
+ new(path: string.split("::").map(&:to_sym), absolute: false)
89
+ end
90
+ end
91
+ end
92
+ end
93
+ end