steep 1.6.0 → 1.7.0.dev.2

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 (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"