steep 0.11.1 → 0.12.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (299) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ruby.yml +27 -0
  3. data/.gitmodules +3 -0
  4. data/CHANGELOG.md +5 -0
  5. data/README.md +48 -90
  6. data/Rakefile +10 -6
  7. data/Steepfile +1 -0
  8. data/bin/setup +1 -0
  9. data/bin/smoke_runner.rb +9 -14
  10. data/exe/rbs +3 -0
  11. data/exe/ruby-signature +3 -0
  12. data/exe/steep +1 -0
  13. data/lib/steep.rb +32 -26
  14. data/lib/steep/annotation_parser.rb +167 -0
  15. data/lib/steep/ast/annotation/collection.rb +7 -7
  16. data/lib/steep/ast/types.rb +60 -0
  17. data/lib/steep/ast/types/any.rb +1 -1
  18. data/lib/steep/ast/types/factory.rb +535 -0
  19. data/lib/steep/ast/types/name.rb +3 -3
  20. data/lib/steep/ast/types/var.rb +1 -1
  21. data/lib/steep/cli.rb +56 -240
  22. data/lib/steep/drivers/annotations.rb +36 -19
  23. data/lib/steep/drivers/check.rb +55 -91
  24. data/lib/steep/drivers/init.rb +54 -0
  25. data/lib/steep/drivers/langserver.rb +241 -150
  26. data/lib/steep/drivers/print_project.rb +56 -0
  27. data/lib/steep/drivers/signature_error_printer.rb +25 -0
  28. data/lib/steep/drivers/trace_printer.rb +25 -0
  29. data/lib/steep/drivers/utils/driver_helper.rb +26 -0
  30. data/lib/steep/drivers/validate.rb +18 -38
  31. data/lib/steep/drivers/vendor.rb +46 -0
  32. data/lib/steep/drivers/watch.rb +78 -140
  33. data/lib/steep/errors.rb +22 -13
  34. data/lib/steep/interface/interface.rb +91 -0
  35. data/lib/steep/interface/method.rb +0 -4
  36. data/lib/steep/interface/method_type.rb +362 -2
  37. data/lib/steep/interface/substitution.rb +22 -0
  38. data/lib/steep/project.rb +25 -233
  39. data/lib/steep/project/dsl.rb +132 -0
  40. data/lib/steep/project/file.rb +93 -76
  41. data/lib/steep/project/file_loader.rb +63 -0
  42. data/lib/steep/project/options.rb +7 -0
  43. data/lib/steep/project/target.rb +190 -0
  44. data/lib/steep/signature/errors.rb +25 -77
  45. data/lib/steep/signature/validator.rb +122 -0
  46. data/lib/steep/source.rb +12 -7
  47. data/lib/steep/subtyping/check.rb +357 -633
  48. data/lib/steep/subtyping/constraints.rb +2 -2
  49. data/lib/steep/subtyping/trace.rb +23 -0
  50. data/lib/steep/type_construction.rb +509 -455
  51. data/lib/steep/type_inference/constant_env.rb +16 -24
  52. data/lib/steep/type_inference/type_env.rb +26 -18
  53. data/lib/steep/version.rb +1 -1
  54. data/sample/Steepfile +6 -0
  55. data/sample/lib/conference.rb +12 -0
  56. data/sample/sig/conference.rbs +6 -0
  57. data/smoke/alias/Steepfile +4 -0
  58. data/smoke/alias/a.rb +2 -2
  59. data/smoke/alias/{a.rbi → a.rbs} +1 -1
  60. data/smoke/and/Steepfile +4 -0
  61. data/smoke/array/Steepfile +4 -0
  62. data/smoke/array/a.rb +2 -2
  63. data/smoke/array/b.rb +4 -4
  64. data/smoke/array/c.rb +2 -2
  65. data/smoke/block/Steepfile +5 -0
  66. data/smoke/block/{a.rbi → a.rbs} +1 -1
  67. data/smoke/block/{c.rbi → c.rbs} +0 -0
  68. data/smoke/block/d.rb +6 -6
  69. data/smoke/case/Steepfile +4 -0
  70. data/smoke/case/a.rb +4 -3
  71. data/smoke/class/Steepfile +4 -0
  72. data/smoke/class/a.rb +1 -4
  73. data/smoke/class/a.rbs +24 -0
  74. data/smoke/class/h.rb +6 -2
  75. data/smoke/class/{h.rbi → h.rbs} +1 -2
  76. data/smoke/class/i.rb +1 -2
  77. data/smoke/class/i.rbs +9 -0
  78. data/smoke/const/Steepfile +4 -0
  79. data/smoke/dstr/Steepfile +4 -0
  80. data/smoke/ensure/Steepfile +4 -0
  81. data/smoke/ensure/a.rb +1 -1
  82. data/smoke/enumerator/Steepfile +4 -0
  83. data/smoke/enumerator/a.rb +7 -7
  84. data/smoke/enumerator/b.rb +6 -6
  85. data/smoke/extension/Steepfile +4 -0
  86. data/smoke/extension/{a.rbi → a.rbs} +2 -2
  87. data/smoke/extension/{e.rbi → e.rbs} +2 -2
  88. data/smoke/hash/Steepfile +4 -0
  89. data/smoke/hash/{a.rbi → a.rbs} +0 -0
  90. data/smoke/hash/b.rb +2 -2
  91. data/smoke/hash/c.rb +1 -1
  92. data/smoke/hash/e.rbs +3 -0
  93. data/smoke/hash/f.rb +1 -1
  94. data/smoke/hello/Steepfile +4 -0
  95. data/smoke/hello/hello.rbs +7 -0
  96. data/smoke/if/Steepfile +4 -0
  97. data/smoke/implements/Steepfile +4 -0
  98. data/smoke/implements/a.rbs +6 -0
  99. data/smoke/initialize/Steepfile +4 -0
  100. data/smoke/initialize/a.rbs +3 -0
  101. data/smoke/integer/Steepfile +4 -0
  102. data/smoke/integer/a.rb +5 -3
  103. data/smoke/interface/Steepfile +4 -0
  104. data/smoke/interface/{a.rbi → a.rbs} +0 -0
  105. data/smoke/kwbegin/Steepfile +4 -0
  106. data/smoke/lambda/Steepfile +4 -0
  107. data/smoke/lambda/a.rb +9 -2
  108. data/smoke/literal/Steepfile +4 -0
  109. data/smoke/literal/{literal_methods.rbi → literal_methods.rbs} +0 -0
  110. data/smoke/map/Steepfile +4 -0
  111. data/smoke/map/a.rb +1 -1
  112. data/smoke/method/Steepfile +4 -0
  113. data/smoke/method/{a.rbi → a.rbs} +0 -0
  114. data/smoke/method/b.rb +1 -4
  115. data/smoke/method/d.rb +1 -0
  116. data/smoke/method/d.rbs +3 -0
  117. data/smoke/module/Steepfile +4 -0
  118. data/smoke/module/a.rb +1 -1
  119. data/smoke/module/a.rbs +16 -0
  120. data/smoke/module/c.rb +1 -1
  121. data/smoke/regexp/Steepfile +4 -0
  122. data/smoke/regexp/a.rb +2 -2
  123. data/smoke/regexp/b.rb +16 -16
  124. data/smoke/regression/Steepfile +5 -0
  125. data/smoke/regression/array.rb +2 -2
  126. data/smoke/regression/hash.rb +2 -2
  127. data/smoke/regression/poly_new.rb +2 -0
  128. data/smoke/regression/poly_new.rbs +4 -0
  129. data/smoke/regression/set_divide.rb +2 -2
  130. data/smoke/rescue/Steepfile +4 -0
  131. data/smoke/rescue/a.rb +1 -1
  132. data/smoke/self/Steepfile +4 -0
  133. data/smoke/self/a.rbs +4 -0
  134. data/smoke/skip/Steepfile +4 -0
  135. data/smoke/stdout/Steepfile +4 -0
  136. data/smoke/stdout/{a.rbi → a.rbs} +1 -1
  137. data/smoke/super/Steepfile +4 -0
  138. data/smoke/super/a.rbs +10 -0
  139. data/smoke/type_case/Steepfile +4 -0
  140. data/smoke/type_case/a.rb +1 -1
  141. data/smoke/yield/Steepfile +4 -0
  142. data/smoke/yield/a.rb +2 -2
  143. data/steep.gemspec +14 -7
  144. data/vendor/ruby-signature/.github/workflows/ruby.yml +27 -0
  145. data/vendor/ruby-signature/.gitignore +12 -0
  146. data/vendor/ruby-signature/.rubocop.yml +15 -0
  147. data/vendor/ruby-signature/BSDL +22 -0
  148. data/vendor/ruby-signature/COPYING +56 -0
  149. data/vendor/ruby-signature/Gemfile +6 -0
  150. data/vendor/ruby-signature/README.md +93 -0
  151. data/vendor/ruby-signature/Rakefile +66 -0
  152. data/vendor/ruby-signature/bin/annotate-with-rdoc +156 -0
  153. data/vendor/ruby-signature/bin/console +14 -0
  154. data/vendor/ruby-signature/bin/query-rdoc +103 -0
  155. data/vendor/ruby-signature/bin/setup +10 -0
  156. data/vendor/ruby-signature/bin/sort +88 -0
  157. data/vendor/ruby-signature/bin/test_runner.rb +17 -0
  158. data/vendor/ruby-signature/docs/CONTRIBUTING.md +97 -0
  159. data/vendor/ruby-signature/docs/sigs.md +148 -0
  160. data/vendor/ruby-signature/docs/stdlib.md +152 -0
  161. data/vendor/ruby-signature/docs/syntax.md +528 -0
  162. data/vendor/ruby-signature/exe/rbs +3 -0
  163. data/vendor/ruby-signature/exe/ruby-signature +7 -0
  164. data/vendor/ruby-signature/lib/ruby/signature.rb +64 -0
  165. data/vendor/ruby-signature/lib/ruby/signature/ast/annotation.rb +29 -0
  166. data/vendor/ruby-signature/lib/ruby/signature/ast/comment.rb +29 -0
  167. data/vendor/ruby-signature/lib/ruby/signature/ast/declarations.rb +391 -0
  168. data/vendor/ruby-signature/lib/ruby/signature/ast/members.rb +364 -0
  169. data/vendor/ruby-signature/lib/ruby/signature/buffer.rb +52 -0
  170. data/vendor/ruby-signature/lib/ruby/signature/builtin_names.rb +54 -0
  171. data/vendor/ruby-signature/lib/ruby/signature/cli.rb +534 -0
  172. data/vendor/ruby-signature/lib/ruby/signature/constant.rb +28 -0
  173. data/vendor/ruby-signature/lib/ruby/signature/constant_table.rb +152 -0
  174. data/vendor/ruby-signature/lib/ruby/signature/definition.rb +172 -0
  175. data/vendor/ruby-signature/lib/ruby/signature/definition_builder.rb +921 -0
  176. data/vendor/ruby-signature/lib/ruby/signature/environment.rb +283 -0
  177. data/vendor/ruby-signature/lib/ruby/signature/environment_loader.rb +138 -0
  178. data/vendor/ruby-signature/lib/ruby/signature/environment_walker.rb +126 -0
  179. data/vendor/ruby-signature/lib/ruby/signature/errors.rb +189 -0
  180. data/vendor/ruby-signature/lib/ruby/signature/location.rb +104 -0
  181. data/vendor/ruby-signature/lib/ruby/signature/method_type.rb +125 -0
  182. data/vendor/ruby-signature/lib/ruby/signature/namespace.rb +93 -0
  183. data/vendor/ruby-signature/lib/ruby/signature/parser.y +1343 -0
  184. data/vendor/ruby-signature/lib/ruby/signature/prototype/rb.rb +441 -0
  185. data/vendor/ruby-signature/lib/ruby/signature/prototype/rbi.rb +579 -0
  186. data/vendor/ruby-signature/lib/ruby/signature/prototype/runtime.rb +383 -0
  187. data/vendor/ruby-signature/lib/ruby/signature/substitution.rb +48 -0
  188. data/vendor/ruby-signature/lib/ruby/signature/test.rb +28 -0
  189. data/vendor/ruby-signature/lib/ruby/signature/test/errors.rb +63 -0
  190. data/vendor/ruby-signature/lib/ruby/signature/test/hook.rb +290 -0
  191. data/vendor/ruby-signature/lib/ruby/signature/test/setup.rb +58 -0
  192. data/vendor/ruby-signature/lib/ruby/signature/test/spy.rb +324 -0
  193. data/vendor/ruby-signature/lib/ruby/signature/test/test_helper.rb +185 -0
  194. data/vendor/ruby-signature/lib/ruby/signature/test/type_check.rb +256 -0
  195. data/vendor/ruby-signature/lib/ruby/signature/type_name.rb +72 -0
  196. data/vendor/ruby-signature/lib/ruby/signature/types.rb +932 -0
  197. data/vendor/ruby-signature/lib/ruby/signature/variance_calculator.rb +140 -0
  198. data/vendor/ruby-signature/lib/ruby/signature/vendorer.rb +49 -0
  199. data/vendor/ruby-signature/lib/ruby/signature/version.rb +5 -0
  200. data/vendor/ruby-signature/lib/ruby/signature/writer.rb +271 -0
  201. data/vendor/ruby-signature/ruby-signature.gemspec +45 -0
  202. data/vendor/ruby-signature/stdlib/abbrev/abbrev.rbs +3 -0
  203. data/vendor/ruby-signature/stdlib/base64/base64.rbs +15 -0
  204. data/vendor/ruby-signature/stdlib/builtin/array.rbs +1997 -0
  205. data/vendor/ruby-signature/stdlib/builtin/basic_object.rbs +280 -0
  206. data/vendor/ruby-signature/stdlib/builtin/binding.rbs +177 -0
  207. data/vendor/ruby-signature/stdlib/builtin/builtin.rbs +35 -0
  208. data/vendor/ruby-signature/stdlib/builtin/class.rbs +145 -0
  209. data/vendor/ruby-signature/stdlib/builtin/comparable.rbs +116 -0
  210. data/vendor/ruby-signature/stdlib/builtin/complex.rbs +400 -0
  211. data/vendor/ruby-signature/stdlib/builtin/constants.rbs +37 -0
  212. data/vendor/ruby-signature/stdlib/builtin/data.rbs +5 -0
  213. data/vendor/ruby-signature/stdlib/builtin/deprecated.rbs +2 -0
  214. data/vendor/ruby-signature/stdlib/builtin/dir.rbs +419 -0
  215. data/vendor/ruby-signature/stdlib/builtin/encoding.rbs +606 -0
  216. data/vendor/ruby-signature/stdlib/builtin/enumerable.rbs +404 -0
  217. data/vendor/ruby-signature/stdlib/builtin/enumerator.rbs +260 -0
  218. data/vendor/ruby-signature/stdlib/builtin/errno.rbs +781 -0
  219. data/vendor/ruby-signature/stdlib/builtin/errors.rbs +582 -0
  220. data/vendor/ruby-signature/stdlib/builtin/exception.rbs +193 -0
  221. data/vendor/ruby-signature/stdlib/builtin/false_class.rbs +40 -0
  222. data/vendor/ruby-signature/stdlib/builtin/fiber.rbs +68 -0
  223. data/vendor/ruby-signature/stdlib/builtin/fiber_error.rbs +12 -0
  224. data/vendor/ruby-signature/stdlib/builtin/file.rbs +476 -0
  225. data/vendor/ruby-signature/stdlib/builtin/file_test.rbs +59 -0
  226. data/vendor/ruby-signature/stdlib/builtin/float.rbs +696 -0
  227. data/vendor/ruby-signature/stdlib/builtin/gc.rbs +121 -0
  228. data/vendor/ruby-signature/stdlib/builtin/hash.rbs +1029 -0
  229. data/vendor/ruby-signature/stdlib/builtin/integer.rbs +710 -0
  230. data/vendor/ruby-signature/stdlib/builtin/io.rbs +683 -0
  231. data/vendor/ruby-signature/stdlib/builtin/kernel.rbs +574 -0
  232. data/vendor/ruby-signature/stdlib/builtin/marshal.rbs +135 -0
  233. data/vendor/ruby-signature/stdlib/builtin/match_data.rbs +141 -0
  234. data/vendor/ruby-signature/stdlib/builtin/math.rbs +66 -0
  235. data/vendor/ruby-signature/stdlib/builtin/method.rbs +182 -0
  236. data/vendor/ruby-signature/stdlib/builtin/module.rbs +248 -0
  237. data/vendor/ruby-signature/stdlib/builtin/nil_class.rbs +82 -0
  238. data/vendor/ruby-signature/stdlib/builtin/numeric.rbs +409 -0
  239. data/vendor/ruby-signature/stdlib/builtin/object.rbs +824 -0
  240. data/vendor/ruby-signature/stdlib/builtin/proc.rbs +426 -0
  241. data/vendor/ruby-signature/stdlib/builtin/process.rbs +354 -0
  242. data/vendor/ruby-signature/stdlib/builtin/random.rbs +93 -0
  243. data/vendor/ruby-signature/stdlib/builtin/range.rbs +226 -0
  244. data/vendor/ruby-signature/stdlib/builtin/rational.rbs +424 -0
  245. data/vendor/ruby-signature/stdlib/builtin/rb_config.rbs +10 -0
  246. data/vendor/ruby-signature/stdlib/builtin/regexp.rbs +131 -0
  247. data/vendor/ruby-signature/stdlib/builtin/ruby_vm.rbs +14 -0
  248. data/vendor/ruby-signature/stdlib/builtin/signal.rbs +55 -0
  249. data/vendor/ruby-signature/stdlib/builtin/string.rbs +770 -0
  250. data/vendor/ruby-signature/stdlib/builtin/string_io.rbs +13 -0
  251. data/vendor/ruby-signature/stdlib/builtin/struct.rbs +40 -0
  252. data/vendor/ruby-signature/stdlib/builtin/symbol.rbs +230 -0
  253. data/vendor/ruby-signature/stdlib/builtin/thread.rbs +1112 -0
  254. data/vendor/ruby-signature/stdlib/builtin/thread_group.rbs +23 -0
  255. data/vendor/ruby-signature/stdlib/builtin/time.rbs +739 -0
  256. data/vendor/ruby-signature/stdlib/builtin/trace_point.rbs +91 -0
  257. data/vendor/ruby-signature/stdlib/builtin/true_class.rbs +46 -0
  258. data/vendor/ruby-signature/stdlib/builtin/unbound_method.rbs +159 -0
  259. data/vendor/ruby-signature/stdlib/builtin/warning.rbs +17 -0
  260. data/vendor/ruby-signature/stdlib/erb/erb.rbs +18 -0
  261. data/vendor/ruby-signature/stdlib/find/find.rbs +44 -0
  262. data/vendor/ruby-signature/stdlib/pathname/pathname.rbs +21 -0
  263. data/vendor/ruby-signature/stdlib/prime/integer-extension.rbs +23 -0
  264. data/vendor/ruby-signature/stdlib/prime/prime.rbs +188 -0
  265. data/vendor/ruby-signature/stdlib/securerandom/securerandom.rbs +9 -0
  266. data/vendor/ruby-signature/stdlib/set/set.rbs +77 -0
  267. data/vendor/ruby-signature/stdlib/tmpdir/tmpdir.rbs +53 -0
  268. metadata +244 -54
  269. data/.travis.yml +0 -7
  270. data/lib/steep/ast/signature/alias.rb +0 -19
  271. data/lib/steep/ast/signature/class.rb +0 -33
  272. data/lib/steep/ast/signature/const.rb +0 -17
  273. data/lib/steep/ast/signature/env.rb +0 -138
  274. data/lib/steep/ast/signature/extension.rb +0 -21
  275. data/lib/steep/ast/signature/gvar.rb +0 -17
  276. data/lib/steep/ast/signature/interface.rb +0 -31
  277. data/lib/steep/ast/signature/members.rb +0 -115
  278. data/lib/steep/ast/signature/module.rb +0 -21
  279. data/lib/steep/drivers/print_interface.rb +0 -94
  280. data/lib/steep/drivers/scaffold.rb +0 -321
  281. data/lib/steep/drivers/utils/each_signature.rb +0 -31
  282. data/lib/steep/interface/abstract.rb +0 -68
  283. data/lib/steep/interface/builder.rb +0 -637
  284. data/lib/steep/interface/instantiated.rb +0 -163
  285. data/lib/steep/interface/ivar_chain.rb +0 -26
  286. data/lib/steep/parser.y +0 -1278
  287. data/lib/steep/project/listener.rb +0 -53
  288. data/smoke/class/a.rbi +0 -24
  289. data/smoke/class/d.rb +0 -9
  290. data/smoke/class/e.rb +0 -12
  291. data/smoke/class/i.rbi +0 -9
  292. data/smoke/hash/e.rbi +0 -3
  293. data/smoke/hello/hello.rbi +0 -7
  294. data/smoke/implements/a.rbi +0 -6
  295. data/smoke/initialize/a.rbi +0 -3
  296. data/smoke/module/a.rbi +0 -16
  297. data/smoke/self/a.rbi +0 -4
  298. data/smoke/super/a.rbi +0 -10
  299. data/stdlib/builtin.rbi +0 -787
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