steep 1.6.0 → 1.7.0.dev.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (314) hide show
  1. checksums.yaml +4 -4
  2. data/.github/dependabot.yml +6 -0
  3. data/.github/workflows/ruby-windows.yml +2 -1
  4. data/.github/workflows/ruby.yml +9 -10
  5. data/.gitignore +0 -1
  6. data/Gemfile +1 -1
  7. data/Gemfile.lock +30 -28
  8. data/Rakefile +5 -0
  9. data/bin/output_test.rb +1 -0
  10. data/doc/narrowing.md +195 -0
  11. data/gemfile_steep/Gemfile +1 -1
  12. data/gemfile_steep/Gemfile.lock +31 -16
  13. data/guides/src/getting-started/getting-started.md +10 -11
  14. data/lib/steep/ast/ignore.rb +148 -0
  15. data/lib/steep/cli.rb +6 -1
  16. data/lib/steep/diagnostic/ruby.rb +16 -0
  17. data/lib/steep/drivers/utils/driver_helper.rb +22 -11
  18. data/lib/steep/node_helper.rb +12 -0
  19. data/lib/steep/project/dsl.rb +18 -21
  20. data/lib/steep/project/options.rb +39 -2
  21. data/lib/steep/project.rb +11 -7
  22. data/lib/steep/server/change_buffer.rb +2 -2
  23. data/lib/steep/server/interaction_worker.rb +61 -11
  24. data/lib/steep/server/worker_process.rb +3 -1
  25. data/lib/steep/services/completion_provider.rb +39 -8
  26. data/lib/steep/services/file_loader.rb +3 -2
  27. data/lib/steep/services/signature_help_provider.rb +20 -17
  28. data/lib/steep/services/type_check_service.rb +36 -8
  29. data/lib/steep/source/ignore_ranges.rb +69 -0
  30. data/lib/steep/source.rb +10 -4
  31. data/lib/steep/subtyping/check.rb +6 -0
  32. data/lib/steep/subtyping/result.rb +6 -0
  33. data/lib/steep/type_construction.rb +6 -151
  34. data/lib/steep/type_inference/case_when.rb +301 -0
  35. data/lib/steep/version.rb +1 -1
  36. data/lib/steep.rb +14 -1
  37. data/rbs_collection.steep.lock.yaml +8 -6
  38. data/sig/shims/parser.rbs +10 -0
  39. data/sig/shims/yaml.rbs +4 -0
  40. data/sig/steep/ast/ignore.rbs +66 -0
  41. data/sig/steep/diagnostic/ruby.rbs +8 -0
  42. data/sig/steep/node_helper.rbs +2 -0
  43. data/sig/steep/project/dsl.rbs +8 -4
  44. data/sig/steep/project/options.rbs +21 -1
  45. data/sig/steep/project.rbs +3 -3
  46. data/sig/steep/server/change_buffer.rbs +6 -4
  47. data/sig/steep/server/interaction_worker.rbs +10 -0
  48. data/sig/steep/server/worker_process.rbs +4 -4
  49. data/sig/steep/services/completion_provider.rbs +14 -1
  50. data/sig/steep/services/type_check_service.rbs +6 -1
  51. data/sig/steep/source/ignore_ranges.rbs +38 -0
  52. data/sig/steep/source.rbs +5 -2
  53. data/sig/steep/subtyping/check.rbs +4 -2
  54. data/sig/steep/subtyping/result.rbs +5 -1
  55. data/sig/steep/type_construction.rbs +1 -26
  56. data/sig/steep/type_inference/case_when.rbs +130 -0
  57. data/sig/steep.rbs +9 -0
  58. data/steep.gemspec +1 -1
  59. metadata +11 -258
  60. data/smoke/alias/Steepfile +0 -6
  61. data/smoke/alias/a.rb +0 -16
  62. data/smoke/alias/a.rbs +0 -10
  63. data/smoke/alias/b.rb +0 -6
  64. data/smoke/alias/c.rb +0 -8
  65. data/smoke/alias/test_expectations.yml +0 -96
  66. data/smoke/and/Steepfile +0 -6
  67. data/smoke/and/a.rb +0 -8
  68. data/smoke/and/test_expectations.yml +0 -29
  69. data/smoke/array/Steepfile +0 -6
  70. data/smoke/array/a.rb +0 -18
  71. data/smoke/array/b.rb +0 -12
  72. data/smoke/array/c.rb +0 -6
  73. data/smoke/array/test_expectations.yml +0 -103
  74. data/smoke/block/Steepfile +0 -6
  75. data/smoke/block/a.rb +0 -10
  76. data/smoke/block/a.rbs +0 -6
  77. data/smoke/block/b.rb +0 -13
  78. data/smoke/block/c.rb +0 -9
  79. data/smoke/block/c.rbs +0 -3
  80. data/smoke/block/d.rb +0 -11
  81. data/smoke/block/e.rb +0 -12
  82. data/smoke/block/e.rbs +0 -4
  83. data/smoke/block/test_expectations.yml +0 -133
  84. data/smoke/case/Steepfile +0 -6
  85. data/smoke/case/a.rb +0 -18
  86. data/smoke/case/test_expectations.yml +0 -47
  87. data/smoke/class/Steepfile +0 -6
  88. data/smoke/class/a.rb +0 -25
  89. data/smoke/class/a.rbs +0 -23
  90. data/smoke/class/b.rb +0 -5
  91. data/smoke/class/c.rb +0 -9
  92. data/smoke/class/f.rb +0 -10
  93. data/smoke/class/g.rb +0 -6
  94. data/smoke/class/h.rb +0 -19
  95. data/smoke/class/h.rbs +0 -6
  96. data/smoke/class/i.rb +0 -14
  97. data/smoke/class/i.rbs +0 -9
  98. data/smoke/class/test_expectations.yml +0 -117
  99. data/smoke/compact/Steepfile +0 -6
  100. data/smoke/compact/a.rb +0 -2
  101. data/smoke/compact/a.rbs +0 -5
  102. data/smoke/compact/b.rb +0 -2
  103. data/smoke/compact/test_expectations.yml +0 -18
  104. data/smoke/const/Steepfile +0 -6
  105. data/smoke/const/a.rb +0 -27
  106. data/smoke/const/b.rb +0 -7
  107. data/smoke/const/b.rbs +0 -5
  108. data/smoke/const/test_expectations.yml +0 -134
  109. data/smoke/diagnostics/Steepfile +0 -6
  110. data/smoke/diagnostics/a.rbs +0 -22
  111. data/smoke/diagnostics/argument_type_mismatch.rb +0 -1
  112. data/smoke/diagnostics/block_body_type_mismatch.rb +0 -1
  113. data/smoke/diagnostics/block_type_mismatch.rb +0 -3
  114. data/smoke/diagnostics/break_type_mismatch.rb +0 -1
  115. data/smoke/diagnostics/different_method_parameter_kind.rb +0 -9
  116. data/smoke/diagnostics/else_on_exhaustive_case.rb +0 -12
  117. data/smoke/diagnostics/incompatible_annotation.rb +0 -6
  118. data/smoke/diagnostics/incompatible_argument.rb +0 -1
  119. data/smoke/diagnostics/incompatible_assignment.rb +0 -8
  120. data/smoke/diagnostics/method_arity_mismatch.rb +0 -11
  121. data/smoke/diagnostics/method_body_type_mismatch.rb +0 -6
  122. data/smoke/diagnostics/method_definition_missing.rb +0 -2
  123. data/smoke/diagnostics/method_parameter_mismatch.rb +0 -10
  124. data/smoke/diagnostics/method_return_type_annotation_mismatch.rb +0 -7
  125. data/smoke/diagnostics/missing_keyword.rb +0 -1
  126. data/smoke/diagnostics/no_method.rb +0 -1
  127. data/smoke/diagnostics/proc_type_expected.rb +0 -3
  128. data/smoke/diagnostics/required_block_missing.rb +0 -1
  129. data/smoke/diagnostics/return_type_mismatch.rb +0 -6
  130. data/smoke/diagnostics/test_expectations.yml +0 -591
  131. data/smoke/diagnostics/unexpected_block_given.rb +0 -1
  132. data/smoke/diagnostics/unexpected_dynamic_method.rb +0 -3
  133. data/smoke/diagnostics/unexpected_jump.rb +0 -4
  134. data/smoke/diagnostics/unexpected_jump_value.rb +0 -3
  135. data/smoke/diagnostics/unexpected_keyword.rb +0 -1
  136. data/smoke/diagnostics/unexpected_splat.rb +0 -1
  137. data/smoke/diagnostics/unexpected_yield.rb +0 -6
  138. data/smoke/diagnostics/unknown_constant_assigned.rb +0 -7
  139. data/smoke/diagnostics/unresolved_overloading.rb +0 -1
  140. data/smoke/diagnostics/unsupported_syntax.rb +0 -2
  141. data/smoke/diagnostics-rbs/Steepfile +0 -8
  142. data/smoke/diagnostics-rbs/duplicated-method-definition.rbs +0 -20
  143. data/smoke/diagnostics-rbs/generic-parameter-mismatch.rbs +0 -7
  144. data/smoke/diagnostics-rbs/inherit-module.rbs +0 -2
  145. data/smoke/diagnostics-rbs/invalid-method-overload.rbs +0 -3
  146. data/smoke/diagnostics-rbs/invalid-type-application.rbs +0 -7
  147. data/smoke/diagnostics-rbs/invalid_variance_annotation.rbs +0 -3
  148. data/smoke/diagnostics-rbs/mixin-class-error.rbs +0 -6
  149. data/smoke/diagnostics-rbs/nonregular-type-alias.rbs +0 -3
  150. data/smoke/diagnostics-rbs/recursive-alias.rbs +0 -5
  151. data/smoke/diagnostics-rbs/recursive-class.rbs +0 -8
  152. data/smoke/diagnostics-rbs/recursive-type-alias.rbs +0 -3
  153. data/smoke/diagnostics-rbs/superclass-mismatch.rbs +0 -7
  154. data/smoke/diagnostics-rbs/test_expectations.yml +0 -300
  155. data/smoke/diagnostics-rbs/unknown-method-alias.rbs +0 -3
  156. data/smoke/diagnostics-rbs/unknown-type-name-2.rbs +0 -5
  157. data/smoke/diagnostics-rbs/unknown-type-name.rbs +0 -13
  158. data/smoke/diagnostics-rbs-duplicated/Steepfile +0 -6
  159. data/smoke/diagnostics-rbs-duplicated/a.rbs +0 -5
  160. data/smoke/diagnostics-rbs-duplicated/test_expectations.yml +0 -13
  161. data/smoke/diagnostics-ruby-unsat/Steepfile +0 -6
  162. data/smoke/diagnostics-ruby-unsat/a.rbs +0 -3
  163. data/smoke/diagnostics-ruby-unsat/test_expectations.yml +0 -27
  164. data/smoke/diagnostics-ruby-unsat/unsatisfiable_constraint.rb +0 -6
  165. data/smoke/dstr/Steepfile +0 -6
  166. data/smoke/dstr/a.rb +0 -5
  167. data/smoke/dstr/test_expectations.yml +0 -13
  168. data/smoke/ensure/Steepfile +0 -6
  169. data/smoke/ensure/a.rb +0 -18
  170. data/smoke/ensure/test_expectations.yml +0 -62
  171. data/smoke/enumerator/Steepfile +0 -6
  172. data/smoke/enumerator/a.rb +0 -6
  173. data/smoke/enumerator/b.rb +0 -17
  174. data/smoke/enumerator/test_expectations.yml +0 -47
  175. data/smoke/extension/Steepfile +0 -6
  176. data/smoke/extension/a.rb +0 -10
  177. data/smoke/extension/a.rbs +0 -13
  178. data/smoke/extension/b.rb +0 -10
  179. data/smoke/extension/c.rb +0 -9
  180. data/smoke/extension/d.rb +0 -2
  181. data/smoke/extension/e.rb +0 -2
  182. data/smoke/extension/e.rbs +0 -7
  183. data/smoke/extension/f.rb +0 -2
  184. data/smoke/extension/f.rbs +0 -3
  185. data/smoke/extension/test_expectations.yml +0 -73
  186. data/smoke/hash/Steepfile +0 -6
  187. data/smoke/hash/a.rb +0 -17
  188. data/smoke/hash/a.rbs +0 -8
  189. data/smoke/hash/b.rb +0 -6
  190. data/smoke/hash/c.rb +0 -15
  191. data/smoke/hash/d.rb +0 -5
  192. data/smoke/hash/e.rb +0 -1
  193. data/smoke/hash/e.rbs +0 -3
  194. data/smoke/hash/f.rb +0 -11
  195. data/smoke/hash/test_expectations.yml +0 -81
  196. data/smoke/hello/Steepfile +0 -6
  197. data/smoke/hello/hello.rb +0 -11
  198. data/smoke/hello/hello.rbs +0 -7
  199. data/smoke/hello/test_expectations.yml +0 -25
  200. data/smoke/if/Steepfile +0 -6
  201. data/smoke/if/a.rb +0 -20
  202. data/smoke/if/test_expectations.yml +0 -34
  203. data/smoke/implements/Steepfile +0 -6
  204. data/smoke/implements/a.rb +0 -12
  205. data/smoke/implements/a.rbs +0 -6
  206. data/smoke/implements/b.rb +0 -13
  207. data/smoke/implements/b.rbs +0 -12
  208. data/smoke/implements/test_expectations.yml +0 -23
  209. data/smoke/initialize/Steepfile +0 -6
  210. data/smoke/initialize/a.rb +0 -12
  211. data/smoke/initialize/a.rbs +0 -3
  212. data/smoke/initialize/test_expectations.yml +0 -1
  213. data/smoke/integer/Steepfile +0 -6
  214. data/smoke/integer/a.rb +0 -26
  215. data/smoke/integer/test_expectations.yml +0 -110
  216. data/smoke/interface/Steepfile +0 -6
  217. data/smoke/interface/a.rb +0 -12
  218. data/smoke/interface/a.rbs +0 -12
  219. data/smoke/interface/test_expectations.yml +0 -23
  220. data/smoke/kwbegin/Steepfile +0 -6
  221. data/smoke/kwbegin/a.rb +0 -7
  222. data/smoke/kwbegin/test_expectations.yml +0 -17
  223. data/smoke/lambda/Steepfile +0 -6
  224. data/smoke/lambda/a.rb +0 -10
  225. data/smoke/lambda/test_expectations.yml +0 -17
  226. data/smoke/literal/Steepfile +0 -6
  227. data/smoke/literal/a.rb +0 -11
  228. data/smoke/literal/b.rb +0 -7
  229. data/smoke/literal/literal_methods.rbs +0 -4
  230. data/smoke/literal/test_expectations.yml +0 -106
  231. data/smoke/map/Steepfile +0 -6
  232. data/smoke/map/a.rb +0 -5
  233. data/smoke/map/test_expectations.yml +0 -1
  234. data/smoke/method/Steepfile +0 -6
  235. data/smoke/method/a.rb +0 -21
  236. data/smoke/method/a.rbs +0 -4
  237. data/smoke/method/b.rb +0 -25
  238. data/smoke/method/c.rb +0 -5
  239. data/smoke/method/d.rb +0 -1
  240. data/smoke/method/d.rbs +0 -3
  241. data/smoke/method/test_expectations.yml +0 -121
  242. data/smoke/module/Steepfile +0 -6
  243. data/smoke/module/a.rb +0 -19
  244. data/smoke/module/a.rbs +0 -16
  245. data/smoke/module/b.rb +0 -6
  246. data/smoke/module/c.rb +0 -22
  247. data/smoke/module/d.rb +0 -4
  248. data/smoke/module/e.rb +0 -13
  249. data/smoke/module/f.rb +0 -11
  250. data/smoke/module/test_expectations.yml +0 -75
  251. data/smoke/regexp/Steepfile +0 -6
  252. data/smoke/regexp/a.rb +0 -109
  253. data/smoke/regexp/b.rb +0 -79
  254. data/smoke/regexp/test_expectations.yml +0 -615
  255. data/smoke/regression/Steepfile +0 -6
  256. data/smoke/regression/array.rb +0 -7
  257. data/smoke/regression/block_param_split.rb +0 -7
  258. data/smoke/regression/block_param_split.rbs +0 -3
  259. data/smoke/regression/empty_yield.rb +0 -5
  260. data/smoke/regression/empty_yield.rbs +0 -3
  261. data/smoke/regression/enumerator_product.rb +0 -1
  262. data/smoke/regression/fun.rb +0 -8
  263. data/smoke/regression/fun.rbs +0 -4
  264. data/smoke/regression/hash.rb +0 -7
  265. data/smoke/regression/hello world.rb +0 -1
  266. data/smoke/regression/issue_328.rb +0 -1
  267. data/smoke/regression/issue_328.rbs +0 -0
  268. data/smoke/regression/issue_332.rb +0 -11
  269. data/smoke/regression/issue_332.rbs +0 -19
  270. data/smoke/regression/issue_372.rb +0 -8
  271. data/smoke/regression/issue_372.rbs +0 -4
  272. data/smoke/regression/lambda.rb +0 -3
  273. data/smoke/regression/masgn.rb +0 -4
  274. data/smoke/regression/poly_new.rb +0 -2
  275. data/smoke/regression/poly_new.rbs +0 -4
  276. data/smoke/regression/range.rb +0 -5
  277. data/smoke/regression/set_divide.rb +0 -12
  278. data/smoke/regression/test_expectations.yml +0 -120
  279. data/smoke/regression/thread.rb +0 -7
  280. data/smoke/rescue/Steepfile +0 -6
  281. data/smoke/rescue/a.rb +0 -48
  282. data/smoke/rescue/test_expectations.yml +0 -79
  283. data/smoke/self/Steepfile +0 -6
  284. data/smoke/self/a.rb +0 -21
  285. data/smoke/self/a.rbs +0 -4
  286. data/smoke/self/test_expectations.yml +0 -23
  287. data/smoke/skip/Steepfile +0 -6
  288. data/smoke/skip/skip.rb +0 -13
  289. data/smoke/skip/test_expectations.yml +0 -23
  290. data/smoke/stdout/Steepfile +0 -6
  291. data/smoke/stdout/a.rb +0 -8
  292. data/smoke/stdout/a.rbs +0 -7
  293. data/smoke/stdout/test_expectations.yml +0 -1
  294. data/smoke/super/Steepfile +0 -6
  295. data/smoke/super/a.rb +0 -30
  296. data/smoke/super/a.rbs +0 -10
  297. data/smoke/super/test_expectations.yml +0 -69
  298. data/smoke/toplevel/Steepfile +0 -6
  299. data/smoke/toplevel/a.rb +0 -3
  300. data/smoke/toplevel/a.rbs +0 -3
  301. data/smoke/toplevel/test_expectations.yml +0 -15
  302. data/smoke/tsort/Steepfile +0 -7
  303. data/smoke/tsort/a.rb +0 -12
  304. data/smoke/tsort/test_expectations.yml +0 -1
  305. data/smoke/type_case/Steepfile +0 -6
  306. data/smoke/type_case/a.rb +0 -24
  307. data/smoke/type_case/test_expectations.yml +0 -58
  308. data/smoke/unexpected/Steepfile +0 -6
  309. data/smoke/unexpected/test_expectations.yml +0 -13
  310. data/smoke/unexpected/unexpected.rbs +0 -3
  311. data/smoke/yield/Steepfile +0 -6
  312. data/smoke/yield/a.rb +0 -15
  313. data/smoke/yield/b.rb +0 -6
  314. data/smoke/yield/test_expectations.yml +0 -88
@@ -178,6 +178,18 @@ module Steep
178
178
  def comments: () -> Array[RBS::AST::Comment]
179
179
  end
180
180
 
181
+ class TextItem
182
+ attr_reader label: String
183
+
184
+ attr_reader text: String
185
+
186
+ attr_reader help_text: String?
187
+
188
+ attr_reader range: Range
189
+
190
+ def initialize: (text: String, help_text: String?, range: Range, label: String) -> void
191
+ end
192
+
181
193
  type item = InstanceVariableItem
182
194
  | KeywordArgumentItem
183
195
  | LocalVariableItem
@@ -186,6 +198,7 @@ module Steep
186
198
  | ComplexMethodNameItem
187
199
  | GeneratedMethodNameItem
188
200
  | TypeNameItem
201
+ | TextItem
189
202
 
190
203
  attr_reader source_text: String
191
204
 
@@ -209,7 +222,7 @@ module Steep
209
222
 
210
223
  def range_from_loc: (Parser::Source::Range loc) -> Range
211
224
 
212
- def at_comment?: (Position pos) -> bool
225
+ def at_comment?: (Position pos) -> Parser::Source::Comment?
213
226
 
214
227
  def at_end?: (Position pos, of: Parser::Source::Map | Parser::Source::Range | nil) -> boolish
215
228
 
@@ -20,6 +20,8 @@ module Steep
20
20
 
21
21
  attr_reader typing: Typing?
22
22
 
23
+ attr_reader ignores: Source::IgnoreRanges?
24
+
23
25
  attr_reader errors: Array[Diagnostic::Ruby::Base]?
24
26
 
25
27
  def initialize: (
@@ -27,17 +29,20 @@ module Steep
27
29
  node: Parser::AST::Node | nil | false,
28
30
  content: String,
29
31
  typing: Typing?,
32
+ ignores: Source::IgnoreRanges?,
30
33
  errors: Array[Diagnostic::Ruby::Base]?
31
34
  ) -> void
32
35
 
33
36
  def self.with_syntax_error: (path: Pathname, content: String, error: Diagnostic::Ruby::SyntaxError) -> SourceFile
34
37
 
35
- def self.with_typing: (path: Pathname, content: String, typing: Typing, node: Parser::AST::Node?) -> SourceFile
38
+ def self.with_typing: (path: Pathname, content: String, typing: Typing, ignores: Source::IgnoreRanges, node: Parser::AST::Node?) -> SourceFile
36
39
 
37
40
  def self.no_data: (path: Pathname, content: String) -> SourceFile
38
41
 
39
42
  def update_content: (String content) -> SourceFile
40
43
 
44
+ # Diagnostics filgered by `ignores`
45
+ #
41
46
  def diagnostics: () -> Array[Diagnostic::Ruby::Base]
42
47
  end
43
48
 
@@ -0,0 +1,38 @@
1
+ use Steep::AST::Ignore, RBS::Location
2
+
3
+ module Steep
4
+ class Source
5
+ class IgnoreRanges
6
+ attr_reader all_ignores: Array[Ignore::t]
7
+
8
+ attr_reader error_ignores: Array[Ignore::t]
9
+
10
+ attr_reader ignored_ranges: Array[Range[Integer]]
11
+
12
+ attr_reader ignored_lines: Hash[Integer, Ignore::IgnoreLine]
13
+
14
+ def initialize: (ignores: Array[Ignore::t]) -> void
15
+
16
+ # If given diagnostic code at the location is ignored or not
17
+ #
18
+ # Ignore ranges work for location that is completely inside the range.
19
+ # Both the starting point and ending point should be in one range.
20
+ # Only diagnostic (1) is ignored in the following example.
21
+ #
22
+ # ```ruby
23
+ # + <2
24
+ # # steep:ignore:start |
25
+ # 1> + +
26
+ # + +
27
+ # # steep:ignore:end |
28
+ # + <3
29
+ # ```
30
+ #
31
+ # Ignore lines work for location that has starting line or ending line.
32
+ #
33
+ def ignore?: (Integer start_line, Integer end_line, String code) -> bool
34
+
35
+ def ignore_code?: (Ignore::IgnoreLine, String code) -> bool
36
+ end
37
+ end
38
+ end
data/sig/steep/source.rbs CHANGED
@@ -12,19 +12,22 @@ module Steep
12
12
 
13
13
  attr_reader comments: Array[Parser::Source::Comment]
14
14
 
15
+ attr_reader ignores: Array[AST::Ignore::t]
16
+
15
17
  def initialize: (
16
18
  buffer: RBS::Buffer,
17
19
  path: Pathname,
18
20
  node: Parser::AST::Node?,
19
21
  mapping: Hash[Parser::AST::Node, Array[AST::Annotation::t]],
20
- comments: Array[Parser::Source::Comment]
22
+ comments: Array[Parser::Source::Comment],
23
+ ignores: Array[AST::Ignore::t]
21
24
  ) -> void
22
25
 
23
26
  class Builder < ::Parser::Builders::Default
24
27
  def string_value: (untyped token) -> untyped
25
28
  end
26
29
 
27
- def self.new_parser: () -> Parser::Ruby32
30
+ def self.new_parser: () -> Parser::Ruby33
28
31
 
29
32
  def self.parse: (String source_code, path: Pathname, factory: AST::Types::Factory) -> Source
30
33
 
@@ -1,6 +1,8 @@
1
1
  module Steep
2
2
  module Subtyping
3
3
  class Check
4
+ ABORT_LIMIT: Integer
5
+
4
6
  attr_reader builder: Interface::Builder
5
7
 
6
8
  attr_reader cache: Cache
@@ -21,7 +23,7 @@ module Steep
21
23
 
22
24
  def factory: () -> AST::Types::Factory
23
25
 
24
- def with_context: [A] (self_type: AST::Types::t, instance_type: AST::Types::t, class_type: AST::Types::t, constraints: Constraints) { () -> A } -> A
26
+ def with_context: [A] (self_type: AST::Types::t?, instance_type: AST::Types::t?, class_type: AST::Types::t?, constraints: Constraints?) { () -> A } -> A
25
27
 
26
28
  def self_type: () -> AST::Types::t
27
29
 
@@ -50,7 +52,7 @@ module Steep
50
52
 
51
53
  def singleton_super_types: (RBS::TypeName type_name) -> Array[super_type]
52
54
 
53
- def check: (Relation[AST::Types::t] relation, constraints: Constraints, self_type: AST::Types::t, instance_type: AST::Types::t, class_type: AST::Types::t) -> Result::t
55
+ def check: (Relation[AST::Types::t] relation, constraints: Constraints, self_type: AST::Types::t?, instance_type: AST::Types::t?, class_type: AST::Types::t?) -> Result::t
54
56
 
55
57
  def check_type: (Relation[AST::Types::t] relation) -> Result::t
56
58
 
@@ -81,7 +81,7 @@ module Steep
81
81
  class Failure < Base
82
82
  type error = MethodMissingError | BlockMismatchError | ParameterMismatchError
83
83
  | UnknownPairError | PolyMethodSubtyping | UnsatisfiedConstraints
84
- | SelfBindingMismatch
84
+ | SelfBindingMismatch | LoopAbort
85
85
 
86
86
  class MethodMissingError
87
87
  attr_reader name: untyped
@@ -145,6 +145,10 @@ module Steep
145
145
  def message: () -> String
146
146
  end
147
147
 
148
+ class LoopAbort
149
+ def message: () -> String
150
+ end
151
+
148
152
  attr_reader error: error
149
153
 
150
154
  def initialize: (Relation[untyped] relation, error error) -> void
@@ -400,7 +400,7 @@ module Steep
400
400
  #
401
401
  def namespace_module?: (Parser::AST::Node node) -> bool
402
402
 
403
- def type_any_rec: (Parser::AST::Node node) -> Pair
403
+ def type_any_rec: (Parser::AST::Node node, ?only_children: bool) -> Pair
404
404
 
405
405
  def unwrap: (AST::Types::t `type`) -> AST::Types::t
406
406
 
@@ -533,35 +533,10 @@ module Steep
533
533
  #
534
534
  def pure_send?: (TypeInference::MethodCall::Typed call, Parser::AST::Node? receiver, Array[Parser::AST::Node] arguments) -> bool
535
535
 
536
- # Transform given `node` to a node that has a local variable instead of the outer most call/non-value node
537
- #
538
- # Returns a pair of transformed node and the outer most call/non-value node if present.
539
- #
540
- # ```rb
541
- # x = y = foo() # Call `#transform_condition_node` with the node and var_name `:__foo__`
542
- # # => Returns [x = y = __foo__, foo()]
543
- #
544
- # x # Call `#transform_condition_node` with the node and var_name `:__foo__`
545
- # # => Returns [__foo__, x]
546
- # ```
547
- #
548
- # This is typically used for transforming assginment node for case condition.
549
- #
550
- def transform_condition_node: (Parser::AST::Node node, Symbol) -> [Parser::AST::Node, Parser::AST::Node]
551
-
552
536
  def type_name: (AST::Types::t) -> RBS::TypeName?
553
537
 
554
538
  def singleton_type: (AST::Types::t) -> AST::Types::t?
555
539
 
556
540
  def instance_type: (AST::Types::t) -> AST::Types::t?
557
-
558
- # Propagate an entry of `source` in TypeEnv to `dest`
559
- #
560
- # `source` is name of a local variable.
561
- #
562
- # If `dest` is a `lvar` node, it updates local variable entry of TypeEnv.
563
- # Otherwise, it updates *pure* call of `dest` if it already exists.
564
- #
565
- def propagate_type_env: (Symbol source, Parser::AST::Node dest, TypeInference::TypeEnv) -> TypeInference::TypeEnv
566
541
  end
567
542
  end
@@ -0,0 +1,130 @@
1
+ use Parser::AST::Node
2
+ use Steep::TypeConstruction::Pair, Steep::TypeInference::LogicTypeInterpreter::Result
3
+ use Steep::NodeHelper::condition_loc, Steep::NodeHelper::keyword_loc
4
+
5
+ module Steep
6
+ module TypeInference
7
+ class CaseWhen
8
+ class WhenPatterns
9
+ include NodeHelper
10
+
11
+ attr_reader logic: LogicTypeInterpreter
12
+
13
+ attr_reader initial_constr: TypeConstruction
14
+
15
+ # True if the `when` clause is unreachable
16
+ attr_reader unreachable_clause: bool
17
+
18
+ @assignment_node: Node
19
+
20
+ attr_reader pattern_results: Array[[Node, Result, Result]]
21
+
22
+ def initialize: (LogicTypeInterpreter logic, TypeConstruction initial_constr, bool unreachable, Node assignment_node) -> void
23
+
24
+ def add_pattern: (Node pattern) { (Node, TypeConstruction, bool) -> Pair } -> void
25
+
26
+ # The result for body of the when-clause
27
+ #
28
+ # Raises an error when no patern is registered.
29
+ #
30
+ def body_result: () { (TypeEnv) -> TypeEnv? } -> [TypeConstruction, bool]
31
+
32
+ # The result for next when-clause
33
+ #
34
+ # Raises an error when no patern is registered.
35
+ #
36
+ def falsy_result: () -> [TypeConstruction, bool]
37
+
38
+ # The result for incoming pattern
39
+ def latest_result: () -> [TypeConstruction, bool]
40
+
41
+ # Returns new object equivalent to @assignment_node
42
+ def assignment_node: () -> Node
43
+ end
44
+
45
+ type when_result = [
46
+ Result, # Type of the body of the when-clause
47
+ Result # Result for the case the when-clause doesn't match
48
+ ]
49
+
50
+ include NodeHelper
51
+ extend NodeHelper
52
+
53
+ # The location of `#node`
54
+ attr_reader location: condition_loc
55
+
56
+ # `case` node
57
+ attr_reader node: Node
58
+
59
+ attr_reader condition_node: Node
60
+
61
+ attr_reader when_nodes: Array[Node]
62
+
63
+ attr_reader else_node: Node?
64
+
65
+ attr_reader logic: LogicTypeInterpreter
66
+
67
+ attr_reader clause_results: Array[when_result]
68
+
69
+ attr_reader else_result: Pair?
70
+
71
+ # Fresh local variable name that contains the value of `#condition_node`
72
+ attr_reader var_name: Symbol
73
+
74
+ # `lvasgn` node that propagates the value of `#condition_node` to local variables
75
+ attr_reader assignment_node: Node
76
+
77
+ # A node that points to the value of `#condition_node`
78
+ #
79
+ # `nil` if it is an local variable.
80
+ #
81
+ attr_reader value_node: Node?
82
+
83
+ # The result of the type checking of `#condition_node`
84
+ #
85
+ attr_reader initial_constr: TypeConstruction
86
+
87
+ # The public API
88
+ #
89
+ # It type checks given `case` node with condition node, and records types and errors of sub nodes.
90
+ #
91
+ def self.type_check: (TypeConstruction, Node, LogicTypeInterpreter, hint: AST::Types::t?, condition: bool) -> [Array[AST::Types::t], Array[TypeEnv]]
92
+
93
+ def initialize: (Node, LogicTypeInterpreter) { (Node) -> Pair } -> void
94
+
95
+ def when_clauses: () { (WhenPatterns, Array[Node], Node?, keyword_loc) -> when_result } -> void
96
+
97
+ def else_clause: () { (Node, TypeConstruction) -> Pair } -> void
98
+
99
+ def result: () -> [Array[AST::Types::t], Array[TypeEnv]]
100
+
101
+ # Assign type of `value_node`
102
+ def propagate_value_node_type: (TypeEnv) -> TypeEnv?
103
+
104
+ # Returns `true` is `else` keyword is given
105
+ #
106
+ # `else_node` may be `nil` because body expression might be omitted.
107
+ #
108
+ # ```ruby
109
+ # case x
110
+ # when 1
111
+ # else
112
+ # # The body expression is omitted, but the branch is given.
113
+ # end
114
+ # ```
115
+ #
116
+ def has_else_clause?: () -> Parser::Source::Range?
117
+
118
+ # def typing: () -> Typing
119
+
120
+ # Extract assignments
121
+ #
122
+ # Returns a pair of the node that represents the value and assignment.
123
+ #
124
+ def rewrite_condition_node: (Symbol, Node) ->[Node?, Node]
125
+
126
+ # TypeConstruction for incoming clause
127
+ def latest_result: () -> [TypeConstruction, bool]
128
+ end
129
+ end
130
+ end
data/sig/steep.rbs CHANGED
@@ -1,6 +1,13 @@
1
1
  module Steep
2
2
  VERSION: String
3
3
 
4
+ # `ui_logger` is a logger for user interaction messages
5
+ #
6
+ # The *main* process has the logger.
7
+ # The *worker* processes disables the logging through this.
8
+ #
9
+ def self.ui_logger: () -> (Logger & ActiveSupport::TaggedLogging)
10
+
4
11
  def self.logger: () -> (Logger & ActiveSupport::TaggedLogging)
5
12
 
6
13
  def self.new_logger: (IO output, Integer? prev_level) -> (Logger & ActiveSupport::TaggedLogging)
@@ -13,6 +20,8 @@ module Steep
13
20
 
14
21
  self.@logger: (Logger & ActiveSupport::TaggedLogging)?
15
22
 
23
+ self.@ui_logger: (Logger & ActiveSupport::TaggedLogging)?
24
+
16
25
  class Sampler
17
26
  type sample = [String, Float]
18
27
  @samples: Array[sample]
data/steep.gemspec CHANGED
@@ -19,7 +19,7 @@ Gem::Specification.new do |spec|
19
19
  spec.metadata["changelog_uri"] = "https://github.com/soutaro/steep/blob/master/CHANGELOG.md"
20
20
 
21
21
  spec.files = `git ls-files -z`.split("\x0").reject {|f|
22
- f.match(%r{^(test|spec|features)/})
22
+ f.match(%r{^(test|spec|features|smoke)/})
23
23
  }
24
24
 
25
25
  spec.bindir = "exe"