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
data/lib/steep/errors.rb CHANGED
@@ -19,18 +19,9 @@ module Steep
19
19
 
20
20
  module ResultPrinter
21
21
  def print_result_to(io, level: 2)
22
- indent = " " * level
23
- result.trace.each do |s, t|
24
- case s
25
- when Interface::Method
26
- io.puts "#{indent}#{s.name}(#{s.type_name}) <: #{t.name}(#{t.type_name})"
27
- when Interface::MethodType
28
- io.puts "#{indent}#{s} <: #{t} (#{s.location.name}:#{s.location.start_line})"
29
- else
30
- io.puts "#{indent}#{s} <: #{t}"
31
- end
32
- end
33
- io.puts "#{indent} #{result.error.message}"
22
+ printer = Drivers::TracePrinter.new(io)
23
+ printer.print result.trace, level: level
24
+ io.puts "==> #{result.error.message}"
34
25
  end
35
26
 
36
27
  def print_to(io)
@@ -74,6 +65,24 @@ module Steep
74
65
  end
75
66
  end
76
67
 
68
+ class UnresolvedOverloading < Base
69
+ attr_reader :node
70
+ attr_reader :receiver_type
71
+ attr_reader :method_name
72
+ attr_reader :method_types
73
+
74
+ def initialize(node:, receiver_type:, method_name:, method_types:)
75
+ super node: node
76
+ @receiver_type = receiver_type
77
+ @method_name = method_name
78
+ @method_types = method_types
79
+ end
80
+
81
+ def to_s
82
+ "#{location_to_str}: UnresolvedOverloading: receiver=#{receiver_type}, method_name=#{method_name}, method_types=#{method_types.join(" | ")}"
83
+ end
84
+ end
85
+
77
86
  class ArgumentTypeMismatch < Base
78
87
  attr_reader :node
79
88
  attr_reader :expected
@@ -164,7 +173,7 @@ module Steep
164
173
  end
165
174
 
166
175
  def to_s
167
- "#{location_to_str}: UnexpectedBlockGiven: method_type=#{method_type.location&.source}"
176
+ "#{location_to_str}: UnexpectedBlockGiven: method_type=#{method_type}"
168
177
  end
169
178
  end
170
179
 
@@ -0,0 +1,91 @@
1
+ module Steep
2
+ module Interface
3
+ class Interface
4
+ class Combination
5
+ attr_reader :operator
6
+ attr_reader :types
7
+
8
+ def initialize(operator:, types:)
9
+ @types = types
10
+ @operator = operator
11
+ @incompatible = false
12
+ end
13
+
14
+ def overload?
15
+ operator == :overload
16
+ end
17
+
18
+ def union?
19
+ operator == :union
20
+ end
21
+
22
+ def intersection?
23
+ operator == :intersection
24
+ end
25
+
26
+ def self.overload(types, incompatible:)
27
+ new(operator: :overload, types: types).incompatible!(incompatible)
28
+ end
29
+
30
+ def incompatible?
31
+ @incompatible
32
+ end
33
+
34
+ def incompatible!(value)
35
+ @incompatible = value
36
+ self
37
+ end
38
+
39
+ def self.union(types)
40
+ case types.size
41
+ when 0
42
+ raise "Combination.union called with zero types"
43
+ when 1
44
+ types.first
45
+ else
46
+ new(operator: :union, types: types)
47
+ end
48
+ end
49
+
50
+ def self.intersection(types)
51
+ case types.size
52
+ when 0
53
+ raise "Combination.intersection called with zero types"
54
+ when 1
55
+ types.first
56
+ else
57
+ new(operator: :intersection, types: types)
58
+ end
59
+ end
60
+
61
+ def to_s
62
+ case operator
63
+ when :overload
64
+ "{ #{types.map(&:to_s).join(" | ")} }"
65
+ when :union
66
+ "[#{types.map(&:to_s).join(" | ")}]"
67
+ when :intersection
68
+ "[#{types.map(&:to_s).join(" & ")}]"
69
+ end
70
+ end
71
+ end
72
+
73
+ attr_reader :type
74
+ attr_reader :methods
75
+
76
+ def initialize(type:, private:)
77
+ @type = type
78
+ @private = private
79
+ @methods = {}
80
+ end
81
+
82
+ def private?
83
+ @private
84
+ end
85
+
86
+ def public?
87
+ !private?
88
+ end
89
+ end
90
+ end
91
+ end
@@ -24,10 +24,6 @@ module Steep
24
24
  other.attributes == attributes
25
25
  end
26
26
 
27
- def incompatible?
28
- attributes.include?(:incompatible)
29
- end
30
-
31
27
  def private?
32
28
  attributes.include?(:private)
33
29
  end
@@ -29,6 +29,40 @@ module Steep
29
29
  )
30
30
  end
31
31
 
32
+ RequiredPositional = Struct.new(:type)
33
+ OptionalPositional = Struct.new(:type)
34
+ RestPositional = Struct.new(:type)
35
+
36
+ def first_param
37
+ case
38
+ when !required.empty?
39
+ RequiredPositional.new(required[0])
40
+ when !optional.empty?
41
+ OptionalPositional.new(optional[0])
42
+ when rest
43
+ RestPositional.new(rest)
44
+ else
45
+ nil
46
+ end
47
+ end
48
+
49
+ def with_first_param(param)
50
+ case param
51
+ when RequiredPositional
52
+ update(required: [param.type] + required)
53
+ when OptionalPositional
54
+ update(optional: [param.type] + required)
55
+ when RestPositional
56
+ update(rest: param.type)
57
+ else
58
+ self
59
+ end
60
+ end
61
+
62
+ def has_positional?
63
+ first_param
64
+ end
65
+
32
66
  def self.empty
33
67
  self.new(
34
68
  required: [],
@@ -226,7 +260,271 @@ module Steep
226
260
  end
227
261
 
228
262
  def empty?
229
- required.empty? && optional.empty? && !rest && !has_keywords?
263
+ !has_positional? && !has_keywords?
264
+ end
265
+
266
+ def |(other)
267
+ a = first_param
268
+ b = other.first_param
269
+
270
+ case
271
+ when a.is_a?(RequiredPositional) && b.is_a?(RequiredPositional)
272
+ AST::Types::Union.build(types: [a.type, b.type]).yield_self do |type|
273
+ (self.drop_first | other.drop_first).with_first_param(RequiredPositional.new(type))
274
+ end
275
+ when a.is_a?(RequiredPositional) && b.is_a?(OptionalPositional)
276
+ AST::Types::Union.build(types: [a.type, b.type]).yield_self do |type|
277
+ (self.drop_first | other.drop_first).with_first_param(OptionalPositional.new(type))
278
+ end
279
+ when a.is_a?(RequiredPositional) && b.is_a?(RestPositional)
280
+ AST::Types::Union.build(types: [a.type, b.type]).yield_self do |type|
281
+ (self.drop_first | other).with_first_param(OptionalPositional.new(type))
282
+ end
283
+ when a.is_a?(RequiredPositional) && b.nil?
284
+ (self.drop_first | other).with_first_param(OptionalPositional.new(a.type))
285
+ when a.is_a?(OptionalPositional) && b.is_a?(RequiredPositional)
286
+ AST::Types::Union.build(types: [a.type, b.type]).yield_self do |type|
287
+ (self.drop_first | other.drop_first).with_first_param(OptionalPositional.new(type))
288
+ end
289
+ when a.is_a?(OptionalPositional) && b.is_a?(OptionalPositional)
290
+ AST::Types::Union.build(types: [a.type, b.type]).yield_self do |type|
291
+ (self.drop_first | other.drop_first).with_first_param(OptionalPositional.new(type))
292
+ end
293
+ when a.is_a?(OptionalPositional) && b.is_a?(RestPositional)
294
+ AST::Types::Union.build(types: [a.type, b.type]).yield_self do |type|
295
+ (self.drop_first | other).with_first_param(OptionalPositional.new(type))
296
+ end
297
+ when a.is_a?(OptionalPositional) && b.nil?
298
+ (self.drop_first | other).with_first_param(OptionalPositional.new(a.type))
299
+ when a.is_a?(RestPositional) && b.is_a?(RequiredPositional)
300
+ AST::Types::Union.build(types: [a.type, b.type]).yield_self do |type|
301
+ (self | other.drop_first).with_first_param(OptionalPositional.new(type))
302
+ end
303
+ when a.is_a?(RestPositional) && b.is_a?(OptionalPositional)
304
+ AST::Types::Union.build(types: [a.type, b.type]).yield_self do |type|
305
+ (self | other.drop_first).with_first_param(OptionalPositional.new(type))
306
+ end
307
+ when a.is_a?(RestPositional) && b.is_a?(RestPositional)
308
+ AST::Types::Union.build(types: [a.type, b.type]).yield_self do |type|
309
+ (self.drop_first | other.drop_first).with_first_param(RestPositional.new(type))
310
+ end
311
+ when a.is_a?(RestPositional) && b.nil?
312
+ (self.drop_first | other).with_first_param(RestPositional.new(a.type))
313
+ when a.nil? && b.is_a?(RequiredPositional)
314
+ (self | other.drop_first).with_first_param(OptionalPositional.new(b.type))
315
+ when a.nil? && b.is_a?(OptionalPositional)
316
+ (self | other.drop_first).with_first_param(OptionalPositional.new(b.type))
317
+ when a.nil? && b.is_a?(RestPositional)
318
+ (self | other.drop_first).with_first_param(RestPositional.new(b.type))
319
+ when a.nil? && b.nil?
320
+ required_keywords = {}
321
+
322
+ (Set.new(self.required_keywords.keys) & Set.new(other.required_keywords.keys)).each do |keyword|
323
+ required_keywords[keyword] = AST::Types::Union.build(
324
+ types: [
325
+ self.required_keywords[keyword],
326
+ other.required_keywords[keyword]
327
+ ]
328
+ )
329
+ end
330
+
331
+ optional_keywords = {}
332
+ self.required_keywords.each do |keyword, t|
333
+ unless required_keywords.key?(keyword)
334
+ case
335
+ when other.optional_keywords.key?(keyword)
336
+ optional_keywords[keyword] = AST::Types::Union.build(types: [t, other.optional_keywords[keyword]])
337
+ when other.rest_keywords
338
+ optional_keywords[keyword] = AST::Types::Union.build(types: [t, other.rest_keywords])
339
+ else
340
+ optional_keywords[keyword] = t
341
+ end
342
+ end
343
+ end
344
+ other.required_keywords.each do |keyword, t|
345
+ unless required_keywords.key?(keyword)
346
+ case
347
+ when self.optional_keywords.key?(keyword)
348
+ optional_keywords[keyword] = AST::Types::Union.build(types: [t, self.optional_keywords[keyword]])
349
+ when self.rest_keywords
350
+ optional_keywords[keyword] = AST::Types::Union.build(types: [t, self.rest_keywords])
351
+ else
352
+ optional_keywords[keyword] = t
353
+ end
354
+ end
355
+ end
356
+ self.optional_keywords.each do |keyword, t|
357
+ unless optional_keywords.key?(keyword)
358
+ case
359
+ when other.optional_keywords.key?(keyword)
360
+ optional_keywords[keyword] = AST::Types::Union.build(types: [t, other.optional_keywords[keyword]])
361
+ when other.rest_keywords
362
+ optional_keywords[keyword] = AST::Types::Union.build(types: [t, other.rest_keywords])
363
+ else
364
+ optional_keywords[keyword] = t
365
+ end
366
+ end
367
+ end
368
+ other.optional_keywords.each do |keyword, t|
369
+ unless optional_keywords.key?(keyword)
370
+ case
371
+ when self.optional_keywords.key?(keyword)
372
+ optional_keywords[keyword] = AST::Types::Union.build(types: [t, self.optional_keywords[keyword]])
373
+ when self.rest_keywords
374
+ optional_keywords[keyword] = AST::Types::Union.build(types: [t, self.rest_keywords])
375
+ else
376
+ optional_keywords[keyword] = t
377
+ end
378
+ end
379
+ end
380
+
381
+ rest = case
382
+ when self.rest_keywords && other.rest_keywords
383
+ AST::Types::Union.build(types: [self.rest_keywords, other.rest_keywords])
384
+ else
385
+ self.rest_keywords || other.rest_keywords
386
+ end
387
+
388
+ Params.new(
389
+ required: [],
390
+ optional: [],
391
+ rest: nil,
392
+ required_keywords: required_keywords,
393
+ optional_keywords: optional_keywords,
394
+ rest_keywords: rest)
395
+ end
396
+ end
397
+
398
+ def &(other)
399
+ a = first_param
400
+ b = other.first_param
401
+
402
+ case
403
+ when a.is_a?(RequiredPositional) && b.is_a?(RequiredPositional)
404
+ AST::Types::Intersection.build(types: [a.type, b.type]).yield_self do |type|
405
+ (self.drop_first & other.drop_first).with_first_param(RequiredPositional.new(type))
406
+ end
407
+ when a.is_a?(RequiredPositional) && b.is_a?(OptionalPositional)
408
+ AST::Types::Intersection.build(types: [a.type, b.type]).yield_self do |type|
409
+ (self.drop_first & other.drop_first).with_first_param(RequiredPositional.new(type))
410
+ end
411
+ when a.is_a?(RequiredPositional) && b.is_a?(RestPositional)
412
+ AST::Types::Intersection.build(types: [a.type, b.type]).yield_self do |type|
413
+ (self.drop_first & other).with_first_param(RequiredPositional.new(type))
414
+ end
415
+ when a.is_a?(RequiredPositional) && b.nil?
416
+ (self.drop_first & other).with_first_param(RequiredPositional.new(AST::Types::Bot.new))
417
+ when a.is_a?(OptionalPositional) && b.is_a?(RequiredPositional)
418
+ AST::Types::Intersection.build(types: [a.type, b.type]).yield_self do |type|
419
+ (self.drop_first & other.drop_first).with_first_param(RequiredPositional.new(type))
420
+ end
421
+ when a.is_a?(OptionalPositional) && b.is_a?(OptionalPositional)
422
+ AST::Types::Intersection.build(types: [a.type, b.type]).yield_self do |type|
423
+ (self.drop_first & other.drop_first).with_first_param(OptionalPositional.new(type))
424
+ end
425
+ when a.is_a?(OptionalPositional) && b.is_a?(RestPositional)
426
+ AST::Types::Intersection.build(types: [a.type, b.type]).yield_self do |type|
427
+ (self.drop_first & other).with_first_param(OptionalPositional.new(type))
428
+ end
429
+ when a.is_a?(OptionalPositional) && b.nil?
430
+ self.drop_first & other
431
+ when a.is_a?(RestPositional) && b.is_a?(RequiredPositional)
432
+ AST::Types::Intersection.build(types: [a.type, b.type]).yield_self do |type|
433
+ (self & other.drop_first).with_first_param(RequiredPositional.new(type))
434
+ end
435
+ when a.is_a?(RestPositional) && b.is_a?(OptionalPositional)
436
+ AST::Types::Intersection.build(types: [a.type, b.type]).yield_self do |type|
437
+ (self & other.drop_first).with_first_param(OptionalPositional.new(type))
438
+ end
439
+ when a.is_a?(RestPositional) && b.is_a?(RestPositional)
440
+ AST::Types::Intersection.build(types: [a.type, b.type]).yield_self do |type|
441
+ (self.drop_first & other.drop_first).with_first_param(RestPositional.new(type))
442
+ end
443
+ when a.is_a?(RestPositional) && b.nil?
444
+ self.drop_first & other
445
+ when a.nil? && b.is_a?(RequiredPositional)
446
+ (self & other.drop_first).with_first_param(RequiredPositional.new(AST::Types::Bot.new))
447
+ when a.nil? && b.is_a?(OptionalPositional)
448
+ self & other.drop_first
449
+ when a.nil? && b.is_a?(RestPositional)
450
+ self & other.drop_first
451
+ when a.nil? && b.nil?
452
+ optional_keywords = {}
453
+
454
+ (Set.new(self.optional_keywords.keys) & Set.new(other.optional_keywords.keys)).each do |keyword|
455
+ self.optional_keywords[keyword] = AST::Types::Intersection.build(
456
+ types: [
457
+ self.optional_keywords[keyword],
458
+ other.optional_keywords[keyword]
459
+ ]
460
+ )
461
+ end
462
+
463
+ required_keywords = {}
464
+ self.optional_keywords.each do |keyword, t|
465
+ unless optional_keywords.key?(keyword)
466
+ case
467
+ when other.required_keywords.key?(keyword)
468
+ required_keywords[keyword] = AST::Types::Intersection.build(types: [t, other.required_keywords[keyword]])
469
+ when other.rest_keywords
470
+ required_keywords[keyword] = AST::Types::Intersection.build(types: [t, other.rest_keywords])
471
+ else
472
+ required_keywords[keyword] = t
473
+ end
474
+ end
475
+ end
476
+ other.optional_keywords.each do |keyword, t|
477
+ unless optional_keywords.key?(keyword)
478
+ case
479
+ when self.required_keywords.key?(keyword)
480
+ required_keywords[keyword] = AST::Types::Intersection.build(types: [t, self.required_keywords[keyword]])
481
+ when self.rest_keywords
482
+ required_keywords[keyword] = AST::Types::Intersection.build(types: [t, self.rest_keywords])
483
+ else
484
+ required_keywords[keyword] = t
485
+ end
486
+ end
487
+ end
488
+ self.required_keywords.each do |keyword, t|
489
+ unless required_keywords.key?(keyword)
490
+ case
491
+ when other.required_keywords.key?(keyword)
492
+ required_keywords[keyword] = AST::Types::Intersection.build(types: [t, other.required_keywords[keyword]])
493
+ when other.rest_keywords
494
+ required_keywords[keyword] = AST::Types::Intersection.build(types: [t, other.rest_keywords])
495
+ else
496
+ required_keywords[keyword] = t
497
+ end
498
+ end
499
+ end
500
+ other.required_keywords.each do |keyword, t|
501
+ unless required_keywords.key?(keyword)
502
+ case
503
+ when self.required_keywords.key?(keyword)
504
+ required_keywords[keyword] = AST::Types::Intersection.build(types: [t, self.required_keywords[keyword]])
505
+ when self.rest_keywords
506
+ required_keywords[keyword] = AST::Types::Intersection.build(types: [t, self.rest_keywords])
507
+ else
508
+ required_keywords[keyword] = t
509
+ end
510
+ end
511
+ end
512
+
513
+ rest = case
514
+ when self.rest_keywords && other.rest_keywords
515
+ AST::Types::Intersection.build(types: [self.rest_keywords, other.rest_keywords])
516
+ else
517
+ self.rest_keywords || other.rest_keywords
518
+ end
519
+
520
+ Params.new(
521
+ required: [],
522
+ optional: [],
523
+ rest: nil,
524
+ required_keywords: required_keywords,
525
+ optional_keywords: optional_keywords,
526
+ rest_keywords: rest)
527
+ end
230
528
  end
231
529
  end
232
530
 
@@ -243,6 +541,13 @@ module Steep
243
541
  @optional
244
542
  end
245
543
 
544
+ def to_optional
545
+ self.class.new(
546
+ type: type,
547
+ optional: true
548
+ )
549
+ end
550
+
246
551
  def ==(other)
247
552
  other.is_a?(self.class) && other.type == type && other.optional == optional
248
553
  end
@@ -265,6 +570,24 @@ module Steep
265
570
  def to_s
266
571
  "#{optional? ? "?" : ""}{ #{type.params} -> #{type.return_type} }"
267
572
  end
573
+
574
+ def map_type(&block)
575
+ self.class.new(
576
+ type: type.map_type(&block),
577
+ optional: optional
578
+ )
579
+ end
580
+
581
+ def +(other)
582
+ optional = self.optional? || other.optional?
583
+ type = AST::Types::Proc.new(params: self.type.params | other.type.params,
584
+ return_type: AST::Types::Union.build(types: [self.type.return_type,
585
+ other.type.return_type]))
586
+ self.class.new(
587
+ type: type,
588
+ optional: optional
589
+ )
590
+ end
268
591
  end
269
592
 
270
593
  class MethodType
@@ -343,12 +666,49 @@ module Steep
343
666
  end
344
667
 
345
668
  def to_s
346
- type_params = !self.type_params.empty? ? "<#{self.type_params.map{|x| "'#{x}" }.join(", ")}> " : ""
669
+ type_params = !self.type_params.empty? ? "[#{self.type_params.map{|x| "#{x}" }.join(", ")}] " : ""
347
670
  params = self.params.to_s
348
671
  block = self.block ? " #{self.block}" : ""
349
672
 
350
673
  "#{type_params}#{params}#{block} -> #{return_type}"
351
674
  end
675
+
676
+ def map_type(&block)
677
+ self.class.new(
678
+ type_params: type_params,
679
+ params: params.map_type(&block),
680
+ block: self.block&.yield_self {|blk| blk.map_type(&block) },
681
+ return_type: yield(return_type),
682
+ location: location
683
+ )
684
+ end
685
+
686
+ def +(other)
687
+ type_params = []
688
+ s1 = Substitution.build(self.type_params)
689
+ type_params.push(*s1.dictionary.values.map(&:name))
690
+ s2 = Substitution.build(other.type_params)
691
+ type_params.push(*s2.dictionary.values.map(&:name))
692
+
693
+ block = case
694
+ when self.block && other.block
695
+ self.block.subst(s1) + other.block.subst(s2)
696
+ when self.block
697
+ self.block.to_optional.subst(s1)
698
+ when other.block
699
+ other.block.to_optional.subst(s2)
700
+ end
701
+
702
+ self.class.new(
703
+ type_params: type_params,
704
+ params: params.subst(s1) | other.params.subst(s2),
705
+ block: block,
706
+ return_type: AST::Types::Union.build(
707
+ types: [return_type.subst(s1),other.return_type.subst(s2)]
708
+ ),
709
+ location: nil
710
+ )
711
+ end
352
712
  end
353
713
  end
354
714
  end