steep 1.1.1 → 1.2.0.pre.1

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 (140) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +20 -0
  3. data/Gemfile +0 -1
  4. data/Gemfile.lock +12 -11
  5. data/Gemfile.steep +1 -1
  6. data/Gemfile.steep.lock +9 -9
  7. data/README.md +3 -3
  8. data/Steepfile +23 -0
  9. data/bin/steep-prof +2 -1
  10. data/lib/steep/annotation_parser.rb +1 -1
  11. data/lib/steep/ast/types/class.rb +4 -0
  12. data/lib/steep/ast/types/factory.rb +86 -602
  13. data/lib/steep/ast/types/instance.rb +4 -0
  14. data/lib/steep/ast/types/literal.rb +1 -1
  15. data/lib/steep/ast/types/proc.rb +22 -8
  16. data/lib/steep/ast/types/self.rb +4 -0
  17. data/lib/steep/ast/types/union.rb +1 -1
  18. data/lib/steep/cli.rb +24 -1
  19. data/lib/steep/diagnostic/ruby.rb +17 -22
  20. data/lib/steep/drivers/checkfile.rb +205 -0
  21. data/lib/steep/drivers/validate.rb +3 -1
  22. data/lib/steep/equatable.rb +2 -0
  23. data/lib/steep/interface/block.rb +21 -11
  24. data/lib/steep/interface/builder.rb +756 -0
  25. data/lib/steep/interface/function.rb +32 -24
  26. data/lib/steep/interface/method_type.rb +191 -78
  27. data/lib/steep/interface/shape.rb +132 -0
  28. data/lib/steep/interface/substitution.rb +23 -12
  29. data/lib/steep/interface/type_param.rb +1 -2
  30. data/lib/steep/path_helper.rb +1 -1
  31. data/lib/steep/project.rb +5 -7
  32. data/lib/steep/server/base_worker.rb +2 -2
  33. data/lib/steep/server/change_buffer.rb +4 -3
  34. data/lib/steep/server/interaction_worker.rb +1 -1
  35. data/lib/steep/server/master.rb +69 -9
  36. data/lib/steep/server/type_check_worker.rb +13 -11
  37. data/lib/steep/server/worker_process.rb +9 -7
  38. data/lib/steep/services/completion_provider.rb +15 -3
  39. data/lib/steep/services/hover_provider/singleton_methods.rb +5 -6
  40. data/lib/steep/services/signature_service.rb +13 -8
  41. data/lib/steep/services/type_check_service.rb +2 -0
  42. data/lib/steep/signature/validator.rb +1 -1
  43. data/lib/steep/subtyping/check.rb +154 -103
  44. data/lib/steep/subtyping/relation.rb +3 -3
  45. data/lib/steep/subtyping/result.rb +20 -2
  46. data/lib/steep/subtyping/variable_variance.rb +9 -0
  47. data/lib/steep/type_construction.rb +558 -299
  48. data/lib/steep/type_inference/block_params.rb +169 -86
  49. data/lib/steep/type_inference/logic_type_interpreter.rb +9 -14
  50. data/lib/steep/type_inference/method_params.rb +12 -7
  51. data/lib/steep/type_inference/send_args.rb +41 -35
  52. data/lib/steep/type_inference/type_env_builder.rb +1 -1
  53. data/lib/steep/version.rb +1 -1
  54. data/lib/steep.rb +71 -2
  55. data/rbs_collection.steep.lock.yaml +18 -30
  56. data/rbs_collection.steep.yaml +1 -0
  57. data/sig/shims/language-server_protocol.rbs +20 -0
  58. data/sig/shims/tagged_logging.rbs +6 -0
  59. data/sig/steep/ast/annotation/collection.rbs +6 -6
  60. data/sig/steep/ast/types/class.rbs +3 -0
  61. data/sig/steep/ast/types/factory.rbs +38 -32
  62. data/sig/steep/ast/types/instance.rbs +3 -0
  63. data/sig/steep/ast/types/intersection.rbs +1 -1
  64. data/sig/steep/ast/types/literal.rbs +7 -7
  65. data/sig/steep/ast/types/name.rbs +14 -13
  66. data/sig/steep/ast/types/proc.rbs +3 -1
  67. data/sig/steep/ast/types/self.rbs +3 -0
  68. data/sig/steep/ast/types/var.rbs +1 -1
  69. data/sig/steep/diagnostic/ruby.rbs +30 -34
  70. data/sig/steep/drivers/annotations.rbs +17 -0
  71. data/sig/steep/drivers/check.rbs +33 -0
  72. data/sig/steep/drivers/checkfile.rbs +26 -0
  73. data/sig/steep/drivers/diagnostic_printer.rbs +25 -0
  74. data/sig/steep/drivers/init.rbs +19 -0
  75. data/sig/steep/drivers/langserver.rbs +35 -0
  76. data/sig/steep/drivers/print_project.rbs +15 -0
  77. data/sig/steep/drivers/stats.rbs +37 -0
  78. data/sig/steep/drivers/utils/driver_helper.rbs +23 -0
  79. data/sig/steep/drivers/utils/jobs_count.rbs +11 -0
  80. data/sig/steep/drivers/validate.rbs +15 -0
  81. data/sig/steep/drivers/vendor.rbs +19 -0
  82. data/sig/steep/drivers/watch.rbs +27 -0
  83. data/sig/steep/drivers/worker.rbs +31 -0
  84. data/sig/steep/equatable.rbs +11 -0
  85. data/sig/steep/index/rbs_index.rbs +91 -0
  86. data/sig/steep/index/signature_symbol_provider.rbs +29 -0
  87. data/sig/steep/index/source_index.rbs +63 -0
  88. data/sig/steep/interface/block.rbs +3 -1
  89. data/sig/steep/interface/builder.rbs +152 -0
  90. data/sig/steep/interface/function.rbs +67 -55
  91. data/sig/steep/interface/method_type.rbs +60 -12
  92. data/sig/steep/interface/shape.rbs +61 -0
  93. data/sig/steep/interface/substitution.rbs +18 -22
  94. data/sig/steep/interface/type_param.rbs +9 -1
  95. data/sig/steep/path_helper.rbs +7 -0
  96. data/sig/steep/project/pattern.rbs +10 -10
  97. data/sig/steep/project/target.rbs +2 -2
  98. data/sig/steep/project.rbs +15 -8
  99. data/sig/steep/server/base_worker.rbs +49 -0
  100. data/sig/steep/server/change_buffer.rbs +32 -0
  101. data/sig/steep/server/interaction_worker.rbs +41 -0
  102. data/sig/steep/server/lsp_formatter.rbs +29 -0
  103. data/sig/steep/server/master.rbs +260 -0
  104. data/sig/steep/server/type_check_worker.rbs +135 -0
  105. data/sig/steep/server/worker_process.rbs +29 -0
  106. data/sig/steep/services/completion_provider.rbs +5 -5
  107. data/sig/steep/services/content_change.rbs +14 -12
  108. data/sig/steep/services/file_loader.rbs +12 -4
  109. data/sig/steep/services/hover_provider/singleton_methods.rbs +1 -1
  110. data/sig/steep/services/path_assignment.rbs +7 -7
  111. data/sig/steep/services/signature_service.rbs +67 -40
  112. data/sig/steep/services/type_check_service.rbs +53 -39
  113. data/sig/steep/subtyping/check.rbs +80 -44
  114. data/sig/steep/subtyping/relation.rbs +24 -22
  115. data/sig/steep/subtyping/result.rbs +48 -30
  116. data/sig/steep/subtyping/variable_variance.rbs +2 -0
  117. data/sig/steep/type_construction.rbs +132 -23
  118. data/sig/steep/type_inference/block_params.rbs +120 -18
  119. data/sig/steep/type_inference/context.rbs +45 -20
  120. data/sig/steep/type_inference/context_array.rbs +37 -0
  121. data/sig/steep/type_inference/logic_type_interpreter.rbs +3 -1
  122. data/sig/steep/type_inference/method_params.rbs +13 -9
  123. data/sig/steep/type_inference/send_args.rbs +229 -0
  124. data/sig/steep/type_inference/type_env_builder.rbs +1 -1
  125. data/sig/steep/typing.rbs +4 -4
  126. data/sig/steep.rbs +4 -2
  127. data/smoke/block/e.rb +12 -0
  128. data/smoke/block/e.rbs +4 -0
  129. data/smoke/block/test_expectations.yml +12 -0
  130. data/smoke/regression/block_param_split.rb +7 -0
  131. data/smoke/regression/block_param_split.rbs +3 -0
  132. data/smoke/regression/empty_yield.rb +5 -0
  133. data/smoke/regression/empty_yield.rbs +3 -0
  134. data/smoke/regression/test_expectations.yml +12 -0
  135. data/smoke/yield/test_expectations.yml +4 -4
  136. data/steep.gemspec +2 -1
  137. metadata +61 -9
  138. data/lib/steep/interface/interface.rb +0 -34
  139. data/sig/steep/interface/interface.rbs +0 -23
  140. data/sig/version.rbs +0 -3
@@ -1,51 +1,53 @@
1
1
  module Steep
2
2
  module Subtyping
3
- class Relation
4
- attr_reader sub_type: untyped
3
+ class Relation[out Subject < Object]
4
+ attr_reader sub_type: Subject
5
5
 
6
- attr_reader super_type: untyped
6
+ attr_reader super_type: Subject
7
7
 
8
- def initialize: (sub_type: untyped, super_type: untyped) -> void
8
+ def initialize: (sub_type: Subject, super_type: Subject) -> void
9
9
 
10
- def hash: () -> untyped
10
+ def hash: () -> Integer
11
11
 
12
- def ==: (untyped other) -> untyped
12
+ def ==: (untyped other) -> bool
13
13
 
14
14
  alias eql? ==
15
15
 
16
16
  def to_s: () -> ::String
17
17
 
18
- def to_ary: () -> ::Array[untyped]
18
+ def to_ary: () -> [Subject, Subject]
19
19
 
20
- def type?: () -> untyped
20
+ def type?: () -> bool
21
21
 
22
- def interface?: () -> untyped
22
+ def interface?: () -> bool
23
23
 
24
- def method?: () -> untyped
24
+ def method?: () -> bool
25
25
 
26
- def function?: () -> untyped
26
+ def function?: () -> bool
27
27
 
28
- def params?: () -> untyped
28
+ def params?: () -> bool
29
29
 
30
- def block?: () -> untyped
30
+ def block?: () -> bool
31
31
 
32
- def assert_type: (untyped `type`) -> (untyped | nil)
32
+ type relation_type = :type | :interface | :method | :function | :params | :block
33
33
 
34
- def type!: () -> untyped
34
+ def assert_type: (relation_type `type`) -> void
35
35
 
36
- def interface!: () -> untyped
36
+ def type!: () -> void
37
37
 
38
- def method!: () -> untyped
38
+ def interface!: () -> void
39
39
 
40
- def function!: () -> untyped
40
+ def method!: () -> void
41
41
 
42
- def params!: () -> untyped
42
+ def function!: () -> void
43
43
 
44
- def block!: () -> untyped
44
+ def params!: () -> void
45
45
 
46
- def map: () { (untyped) -> untyped } -> untyped
46
+ def block!: () -> void
47
47
 
48
- def flip: () -> untyped
48
+ def map: [T < Object] () { (Subject) -> T } -> Relation[T]
49
+
50
+ def flip: () -> Relation[Subject]
49
51
  end
50
52
  end
51
53
  end
@@ -4,19 +4,19 @@ module Steep
4
4
  type t = Skip | Expand | All | Any | Success | Failure
5
5
 
6
6
  class Base
7
- attr_reader relation: Relation
7
+ attr_reader relation: Relation[untyped]
8
8
 
9
- def initialize: (Relation relation) -> void
9
+ def initialize: (Relation[untyped] relation) -> void
10
10
 
11
11
  def failure?: () -> bool
12
12
 
13
13
  def success?: () -> bool
14
14
 
15
- def then: [A] () { (self) -> A } -> A
15
+ def then: () { (self) -> void } -> self
16
16
 
17
- def else: [A] () { (self) -> A } -> A
17
+ def else: () { (self) -> void } -> self
18
18
 
19
- def failure_path: (?untyped path) -> untyped
19
+ def failure_path: (?Array[t] path) -> Array[t]?
20
20
  end
21
21
 
22
22
  class Skip < Base
@@ -28,50 +28,61 @@ module Steep
28
28
  end
29
29
 
30
30
  class Expand < Base
31
- attr_reader child: untyped
31
+ attr_reader child: t
32
32
 
33
- def initialize: (untyped relation) { (untyped) -> untyped } -> void
33
+ def initialize: (Relation[untyped] relation) { (Relation[untyped]) -> t } -> void
34
34
 
35
- def success?: () -> untyped
35
+ def success?: () -> bool
36
36
 
37
- def failure_path: (?untyped path) -> (untyped | nil)
37
+ def failure_path: (?Array[t] path) -> Array[t]?
38
38
  end
39
39
 
40
40
  class All < Base
41
- attr_reader branches: untyped
41
+ attr_reader branches: Array[t]
42
42
 
43
- def initialize: (untyped relation) -> void
43
+ def initialize: (Relation[untyped] relation) -> void
44
+
45
+ @failure: bool
44
46
 
45
47
  # Returns `false` if no future `#add` changes the result.
46
- def add: (*untyped relations) { (untyped) -> untyped } -> untyped
48
+ def add: [T < Object] (*Relation[T] relations) { (Relation[T]) -> t? } -> bool
47
49
 
48
- def success?: () -> untyped
50
+ # Returns `false` if no future `#add` changes the result.
51
+ def add_result: (t?) -> bool
49
52
 
50
- def failure?: () -> untyped
53
+ def success?: () -> bool
54
+
55
+ def failure?: () -> bool
51
56
 
52
- def failure_path: (?untyped path) -> (untyped | nil)
57
+ def failure_path: (?Array[t] path) -> Array[t]?
53
58
  end
54
59
 
55
60
  class Any < Base
56
- attr_reader branches: untyped
61
+ attr_reader branches: Array[t]
57
62
 
58
- def initialize: (untyped relation) -> void
63
+ def initialize: (Relation[untyped] relation) -> void
64
+
65
+ @success: bool
59
66
 
60
67
  # Returns `false` if no future `#add` changes the result.
61
- def add: (*untyped relations) { (untyped) -> untyped } -> untyped
68
+ def add: [T < Object] (*Relation[T] relations) { (Relation[T]) -> t } -> bool
62
69
 
63
- def success?: () -> untyped
70
+ def success?: () -> bool
64
71
 
65
- def failure_path: (?untyped path) -> (untyped | nil)
72
+ def failure_path: (?Array[t] path) -> Array[t]?
66
73
  end
67
74
 
68
75
  class Success < Base
69
76
  def success?: () -> true
70
77
 
71
- def failure_path: (?untyped path) -> nil
78
+ def failure_path: (?Array[t] path) -> Array[t]?
72
79
  end
73
80
 
74
81
  class Failure < Base
82
+ type error = MethodMissingError | BlockMismatchError | ParameterMismatchError
83
+ | UnknownPairError | PolyMethodSubtyping | UnsatisfiedConstraints
84
+ | SelfBindingMismatch
85
+
75
86
  class MethodMissingError
76
87
  attr_reader name: untyped
77
88
 
@@ -128,29 +139,36 @@ module Steep
128
139
  def message: () -> ::String
129
140
  end
130
141
 
131
- attr_reader error: untyped
142
+ class SelfBindingMismatch
143
+ def initialize: () -> void
132
144
 
133
- def initialize: (untyped relation, untyped error) -> void
145
+ def message: () -> String
146
+ end
147
+
148
+ attr_reader error: error
149
+
150
+ def initialize: (Relation[untyped] relation, error error) -> void
134
151
 
135
152
  def success?: () -> false
136
153
 
137
- def failure_path: (?untyped path) -> untyped
154
+ def failure_path: (?Array[t] path) -> Array[t]?
138
155
  end
139
156
 
140
157
  module Helper
141
- def Skip: (untyped relation) -> untyped
158
+ def Skip: (Relation[untyped] relation) -> Skip
142
159
 
143
- def Expand: (untyped relation) { () -> untyped } -> untyped
160
+ def Expand: [T < Object] (Relation[T] relation) { (Relation[T]) -> t } -> Expand
144
161
 
145
- def All: (untyped relation) { () -> untyped } -> untyped
162
+ def All: (Relation[untyped] relation) { (All) -> void } -> All
146
163
 
147
- def Any: (untyped relation) { () -> untyped } -> untyped
164
+ def Any: (Relation[untyped] relation) { (Any) -> void } -> Any
148
165
 
149
- def Success: (untyped relation) -> untyped
166
+ def Success: (Relation[untyped] relation) -> Success
150
167
 
151
168
  alias success Success
152
169
 
153
- def Failure: (untyped relation, ?untyped? error) { () -> untyped } -> untyped
170
+ def Failure: (Relation[untyped] relation, Failure::error) -> Failure
171
+ | (Relation[untyped]) { () -> Failure::error } -> Failure
154
172
  end
155
173
  end
156
174
  end
@@ -13,6 +13,8 @@ module Steep
13
13
 
14
14
  def invariant?: (untyped var) -> untyped
15
15
 
16
+ def self.from_type: (AST::Types::t) -> VariableVariance
17
+
16
18
  def self.from_method_type: (untyped method_type) -> untyped
17
19
 
18
20
  def self.add_params: (untyped params, block: untyped, covariants: untyped, contravariants: untyped) -> untyped
@@ -30,17 +30,17 @@ module Steep
30
30
 
31
31
  attr_reader context: TypeInference::Context
32
32
 
33
- def module_context: () -> TypeInference::Context::ModuleContext?
33
+ %a{pure} def module_context: () -> TypeInference::Context::ModuleContext?
34
34
 
35
- def method_context: () -> TypeInference::Context::MethodContext?
35
+ %a{pure} def method_context: () -> TypeInference::Context::MethodContext?
36
36
 
37
- def block_context: () -> TypeInference::Context::BlockContext?
37
+ %a{pure} def block_context: () -> TypeInference::Context::BlockContext?
38
38
 
39
- def break_context: () -> TypeInference::Context::BreakContext?
39
+ %a{pure} def break_context: () -> TypeInference::Context::BreakContext?
40
40
 
41
- def self_type: () -> untyped
41
+ %a{pure} def self_type: () -> AST::Types::t
42
42
 
43
- def variable_context: () -> TypeInference::Context::TypeVariableContext
43
+ %a{pure} def variable_context: () -> TypeInference::Context::TypeVariableContext
44
44
 
45
45
  def initialize: (checker: untyped, source: untyped, annotations: untyped, typing: untyped, context: untyped) -> void
46
46
 
@@ -90,6 +90,14 @@ module Steep
90
90
 
91
91
  def with_sclass_constr: [A] (Parser::AST::Node node, AST::Types::t `type`) { (TypeConstruction?) -> A } -> A
92
92
 
93
+ # Returns one-level _meta_ type from given type
94
+ #
95
+ # * Returns singleton type of the type name if instance type is given
96
+ # * Returns `::Class` if singleton type is given
97
+ # * Returns `nil` otherwise
98
+ #
99
+ def meta_type: (AST::Types::t) -> AST::Types::t?
100
+
93
101
  def for_sclass: (Parser::AST::Node node, AST::Types::t `type`) -> TypeConstruction?
94
102
 
95
103
  def for_branch: (Parser::AST::Node node, ?break_context: TypeInference::Context::BreakContext?) -> untyped
@@ -122,11 +130,19 @@ module Steep
122
130
 
123
131
  def synthesize_children: (Parser::AST::Node node, ?skips: Array[Parser::AST::Node]) -> TypeConstruction
124
132
 
125
- def type_send_interface: (Parser::AST::Node node, interface: Interface::Interface, receiver: Parser::AST::Node, receiver_type: AST::Types::t, method_name: Symbol, arguments: Array[Parser::AST::Node], block_params: Parser::AST::Node?, block_body: Parser::AST::Node?) -> Pair
133
+ def type_send_interface: (Parser::AST::Node node, interface: Interface::Shape, receiver: Parser::AST::Node, receiver_type: AST::Types::t, method_name: Symbol, arguments: Array[Parser::AST::Node], block_params: Parser::AST::Node?, block_body: Parser::AST::Node?) -> Pair
126
134
 
127
135
  def type_send: (untyped node, send_node: untyped, block_params: untyped, block_body: untyped, ?unwrap: bool) -> untyped
128
136
 
129
- def calculate_interface: (untyped `type`, private: untyped, ?self_type: untyped) -> untyped
137
+ def builder_config: () -> Interface::Builder::Config
138
+
139
+ # Calculates the shape (interface) of an type
140
+ #
141
+ # * Returns `nil` if the type cannot be translated to a shape
142
+ # * Returns Shape::Entry instead of Shape, if `method_name` is given
143
+ #
144
+ def calculate_interface: (AST::Types::t `type`, private: bool) -> Interface::Shape?
145
+ | (AST::Types::t `type`, Symbol method_name, private: bool) -> Interface::Shape::Entry?
130
146
 
131
147
  def expand_self: (untyped `type`) -> untyped
132
148
 
@@ -140,7 +156,7 @@ module Steep
140
156
  Parser::AST::Node node,
141
157
  method_name: Symbol,
142
158
  receiver_type: AST::Types::t,
143
- method: Interface::Interface::Entry,
159
+ method: Interface::Shape::Entry,
144
160
  arguments: Array[Parser::AST::Node],
145
161
  block_params: Parser::AST::Node?,
146
162
  block_body: Parser::AST::Node?,
@@ -149,7 +165,8 @@ module Steep
149
165
 
150
166
  def inspect: () -> ::String
151
167
 
152
- def with_child_typing: (range: untyped) { (untyped) -> untyped } -> untyped
168
+ def with_child_typing: [A] (range: Range[Integer]) { (TypeConstruction) -> A } -> A
169
+ | (range: Range[Integer]) -> TypeConstruction
153
170
 
154
171
  # Bypass :splat and :kwsplat
155
172
  def bypass_splat: (untyped node) { (untyped) -> untyped } -> untyped
@@ -169,25 +186,57 @@ module Steep
169
186
 
170
187
  def eliminate_vars: (untyped `type`, untyped variables, ?to: untyped) -> untyped
171
188
 
172
- def try_method_type: (Parser::AST::Node node, receiver_type: AST::Types::t, method_name: Symbol, method_type: Interface::MethodType, arguments: Array[Parser::AST::Node], block_params: Parser::AST::Node?, block_body: Parser::AST::Node?, topdown_hint: untyped) -> [TypeInference::MethodCall::t, TypeConstruction]
189
+ def try_method_type: (
190
+ Parser::AST::Node node,
191
+ receiver_type: AST::Types::t,
192
+ method_name: Symbol,
193
+ method_type: Interface::MethodType,
194
+ arguments: Array[Parser::AST::Node],
195
+ block_params: Parser::AST::Node?,
196
+ block_body: Parser::AST::Node?,
197
+ topdown_hint: untyped
198
+ ) -> [TypeInference::MethodCall::t, TypeConstruction]
199
+
200
+ def type_check_args: (
201
+ TypeInference::SendArgs,
202
+ Subtyping::Constraints,
203
+ Array[Diagnostic::Ruby::Base]
204
+ ) -> TypeConstruction
205
+
206
+ def type_check_argument: (Parser::AST::Node node, type: AST::Types::t, constraints: Subtyping::Constraints, errors: Array[Diagnostic::Ruby::Base], ?report_node: Parser::AST::Node) -> Pair
173
207
 
174
- def type_check_argument: (Parser::AST::Node node, receiver_type: AST::Types::t, type: AST::Types::t, constraints: Subtyping::Constraints, errors: Array[Diagnostic::Ruby::Base], ?report_node: Parser::AST::Node) -> Pair
208
+ def type_block_without_hint: (node: Parser::AST::Node, block_annotations: AST::Annotation::Collection, block_params: TypeInference::BlockParams?, block_body: Parser::AST::Node?) ?{ (Diagnostic::Ruby::Base) -> void } -> void
175
209
 
176
- def type_block_without_hint: (node: untyped, block_annotations: untyped, block_params: untyped, block_body: untyped) { () -> untyped } -> untyped
210
+ def set_up_block_mlhs_params_env: (
211
+ Parser::AST::Node mlhs_node,
212
+ AST::Types::t type,
213
+ Hash[Symbol, AST::Types::t]
214
+ ) { (Parser::AST::Node error_mlhs_node, AST::Types::t type) -> void } -> void
177
215
 
178
216
  # Returns a Pair of
179
217
  #
180
218
  # * TypeConstruction to type check the block, and
181
219
  # * Set of local variable names to unpin after type checking the block
182
220
  #
221
+ # ### Arguments
222
+ #
223
+ # * `body_node` Block body node
224
+ # * `block_params` BlockParams object
225
+ # * `block_param_hint` Type hint of the block parameters
226
+ # * `block_type_hint` Type hint of the block body
227
+ # * `block_block_hint` Type hint of the block that will be given to the block
228
+ # * `block_annotations` Annotations given to the block body
229
+ # * `node_type_hint` Type hint of block call node
230
+ #
183
231
  def for_block: (
184
232
  Parser::AST::Node? body_node,
185
233
  block_params: TypeInference::BlockParams,
186
- block_param_hint: TypeInference::MethodParams?,
234
+ block_param_hint: Interface::Function::Params?,
187
235
  block_type_hint: AST::Types::t?,
188
236
  block_block_hint: Interface::Block?,
189
237
  block_annotations: AST::Annotation::Collection,
190
- node_type_hint: AST::Types::t?
238
+ node_type_hint: AST::Types::t?,
239
+ block_self_hint: AST::Types::t?
191
240
  ) -> TypeConstruction
192
241
 
193
242
  # Synthesize the block body and returns the type of the body
@@ -202,6 +251,25 @@ module Steep
202
251
 
203
252
  def union_type: (*AST::Types::t types) -> AST::Types::t
204
253
 
254
+ # Returns union type of given types
255
+ #
256
+ # If one of the types is a subtype of another type, the _subtype_ will be ignored.
257
+ #
258
+ # ```ruby
259
+ # union_type(`String`, `Object`) # => `Object`
260
+ # union_type(`String`, `Integer`) # => `String | Integer`
261
+ # ```
262
+ #
263
+ def union_type_unify: (*AST::Types::t types) -> AST::Types::t
264
+
265
+ # Translate a union of tuple types to a tuple of union types
266
+ #
267
+ # * ([A, B] | [C, D, E]) => [A | C, B | D, E?]
268
+ #
269
+ # Returns `nil` if the translation cannot apply.
270
+ #
271
+ def union_of_tuple_to_tuple_of_union: (AST::Types::Union) -> AST::Types::Tuple?
272
+
205
273
  def validate_method_definitions: (untyped node, untyped module_name) -> (nil | untyped)
206
274
 
207
275
  def fallback_to_any: (Parser::AST::Node node) ?{ () -> Diagnostic::Ruby::Base } -> Pair
@@ -212,12 +280,11 @@ module Steep
212
280
 
213
281
  def type_any_rec: (Parser::AST::Node node) -> Pair
214
282
 
215
- def unwrap: (untyped `type`) -> untyped
283
+ def unwrap: (AST::Types::t `type`) -> AST::Types::t
216
284
 
217
- def deep_expand_alias: (AST::Types::t `type`) -> AST::Types::t
218
- | [A] (AST::Types::t) { (AST::Types::t) -> A } -> A
285
+ def deep_expand_alias: (AST::Types::t `type`) -> AST::Types::t?
219
286
 
220
- def flatten_union: (untyped `type`) -> untyped
287
+ def flatten_union: (AST::Types::t `type`) -> Array[AST::Types::t]
221
288
 
222
289
  def select_flatten_types: (untyped `type`) { () -> untyped } -> untyped
223
290
 
@@ -232,11 +299,28 @@ module Steep
232
299
 
233
300
  def to_instance_type: (untyped `type`, ?args: untyped?) -> untyped
234
301
 
235
- def try_tuple_type!: (Parser::AST::Node node, ?hint: AST::Types::t?) -> Pair
302
+ def try_tuple_type!: (Parser::AST::Node node, ?hint: AST::Types::Tuple?) -> Pair
236
303
 
237
- def try_tuple_type: (Parser::AST::Node node, AST::Types::Tuple? hint) -> (nil | untyped)
304
+ # Try to give `array_node` a tuple type
305
+ #
306
+ # * If `hint` is given, the array element would receive a hint of element of `hint` type.
307
+ # * If `hint` it not given, `array_node` is assumed to have a tuple type, but no assumption on element types.
308
+ #
309
+ # Returns `nil` when `array_node` includes `*` (splat) node.
310
+ #
311
+ # ```ruby
312
+ # try_tuple_type(`[1, 2]`, nil) # => `[Integer, Integer, Integer]`
313
+ # try_tuple_type(`[1]`, `[Integer, Integer]`) # => `[Integer]`
314
+ # try_tuple_type(`[1, 2]`, `[Integer]`) # => `[Integer, Integer]`
315
+ # try_tuple_type(`[1, *]`, `[Integer]`) # => nil
316
+ # ```
317
+ #
318
+ # Note that `typing` will be updated even when it returns `nil`.
319
+ # You probably should try `with_new_typing` to make the result _atomic_.
320
+ #
321
+ def try_tuple_type: (Parser::AST::Node array_node, AST::Types::Tuple? hint) -> Pair?
238
322
 
239
- # Try to convert a object of `type` with zero-arity method `method`.
323
+ # Try to convert an object of `type` with zero-arity method `method`.
240
324
  #
241
325
  # Returns `nil` when
242
326
  #
@@ -250,7 +334,26 @@ module Steep
250
334
  #
251
335
  def try_convert: (AST::Types::t `type`, Symbol method) -> AST::Types::t?
252
336
 
253
- def try_array_type: (untyped node, untyped hint) -> untyped
337
+ # Try to convert an object of `type` to an Array-ish
338
+ #
339
+ # * `untyped` is arrayish
340
+ #
341
+ def try_convert_to_array: (AST::Types::t) -> AST::Types::t?
342
+
343
+ # Returns a type if given type is arrayish
344
+ #
345
+ # * Aliases will be unfolded to arrayish type
346
+ # * Returns `nil` if given type is not arrayish
347
+ # * `untyped` is arrayish if `untyped_is:` is `true` (defaults to `false`)
348
+ #
349
+ def arrayish_type?: (AST::Types::t, ?untyped_is: bool) -> AST::Types::t?
350
+
351
+ # Returns the type is given type is a subtype of Array
352
+ def semantically_arrayish_type?: (AST::Types::t) -> AST::Types::t?
353
+
354
+ # Give an array node a type with hint
355
+ #
356
+ def try_array_type: (Parser::AST::Node node, AST::Types::Name::Instance? hint) -> Pair
254
357
 
255
358
  # Returns a record type if `hash_node` can have a record type.
256
359
  #
@@ -296,5 +399,11 @@ module Steep
296
399
  # This is typically used for transforming assginment node for case condition.
297
400
  #
298
401
  def extract_outermost_call: (Parser::AST::Node node, Symbol) -> [Parser::AST::Node, Parser::AST::Node?]
402
+
403
+ def type_name: (AST::Types::t) -> RBS::TypeName?
404
+
405
+ def singleton_type: (AST::Types::t) -> AST::Types::t?
406
+
407
+ def instance_type: (AST::Types::t) -> AST::Types::t?
299
408
  end
300
409
  end
@@ -1,52 +1,154 @@
1
1
  module Steep
2
2
  module TypeInference
3
+ # Block parameters have the following differences from method parameters:
4
+ #
5
+ # * Allows arity mismatch
6
+ # * Distributing array-ish argument to parameters
7
+ # * Allows _multiple_ parameter assignments
8
+ #
9
+ # ### Allows arity mismatch
10
+ #
11
+ # (TBD)
12
+ #
13
+ # ### Distributing array-ish argument to parameters
14
+ #
15
+ # A block can receive an array(-ish) argument as follows:
16
+ # Assume `yield [1,2,3]` evaluates to call the block.
17
+ #
18
+ # 1. With one parameter `{|x| ... }` (`x` is `[1, 2, 3]`)
19
+ # 2. With several parameters (splatting) `{|x, y, z| ... }` (`x` is `1`, ...)
20
+ #
21
+ # The splatting applies only when one argument that is an array-ish is yielded.
22
+ #
23
+ # Because we have another rule which allows parameter omission, Ruby has another rule to avoid ambiguity.
24
+ #
25
+ # 3. One parameter with trailing comma splats `{|x,| ... }` (`x` is `1`)
26
+ #
27
+ # The parser has `:procarg0` node for case 1 and `arg` nodes for other cases.
28
+ #
29
+ # ### Allows _multiple_ parameter assignments
30
+ #
3
31
  class BlockParams
32
+ # Param object represents a block parameter
33
+ #
34
+ # * `var` is name of the parameter
35
+ # * `type` is the type of the parameter, if given through inline annotation
36
+ # * `value` is the default value node
37
+ # * `node` is the node of the parameter
38
+ #
4
39
  class Param
5
40
  attr_reader var: Symbol
6
41
 
7
- attr_reader type: AST::Types::t
42
+ attr_reader type: AST::Types::t?
8
43
 
9
- attr_reader value: untyped
44
+ attr_reader value: Parser::AST::Node?
10
45
 
11
46
  attr_reader node: Parser::AST::Node
12
47
 
13
- def initialize: (var: Symbol, type: AST::Types::t, value: untyped, node: Parser::AST::Node) -> void
48
+ def initialize: (var: Symbol, type: AST::Types::t?, value: Parser::AST::Node?, node: Parser::AST::Node) -> void
14
49
 
15
50
  def ==: (untyped other) -> bool
16
51
 
17
52
  alias eql? ==
18
53
 
19
54
  def hash: () -> Integer
55
+
56
+ def each_param: () { (Param) -> void } -> void
57
+ | () -> Enumerator[Param, void]
20
58
  end
21
59
 
22
- attr_reader leading_params: untyped
60
+ # MultipleParam object represents a _multiple_ block parameter
61
+ #
62
+ # ```ruby
63
+ # foo do |(x, y)|
64
+ # # ^^^^^^ This is the multiple block parameter
65
+ # end
66
+ # ```
67
+ #
68
+ # * `#node` is `:mlhs` node or `:procarg0` node
69
+ # * Param objects in `#params` don't have `value` because of Ruby syntax rule
70
+ #
71
+ class MultipleParam
72
+ attr_reader node: Parser::AST::Node
73
+
74
+ attr_reader params: Array[Param | MultipleParam]
75
+
76
+ def initialize: (node: Parser::AST::Node, params: Array[Param | MultipleParam]) -> void
77
+
78
+ def ==: (untyped other) -> bool
79
+
80
+ alias eql? ==
81
+
82
+ def hash: () -> Integer
83
+
84
+ # Returns a hash table that associates variables to its type annotation
85
+ #
86
+ def variable_types: () -> Hash[Symbol, AST::Types::t?]
87
+
88
+ # Yields Param objects in `self` and it's `params` recursively
89
+ #
90
+ def each_param: () { (Param) -> void } -> void
91
+ | () -> Enumerator[Param, void]
92
+ end
93
+
94
+ attr_reader leading_params: Array[Param | MultipleParam]
95
+
96
+ attr_reader optional_params: Array[Param]
23
97
 
24
- attr_reader optional_params: untyped
98
+ attr_reader rest_param: Param?
25
99
 
26
- attr_reader rest_param: untyped
100
+ attr_reader trailing_params: Array[Param | MultipleParam]
27
101
 
28
- attr_reader trailing_params: untyped
102
+ attr_reader block_param: Param?
29
103
 
30
- attr_reader block_param: untyped
104
+ def initialize: (
105
+ leading_params: Array[Param | MultipleParam],
106
+ optional_params: Array[Param],
107
+ rest_param: Param?,
108
+ trailing_params: Array[Param | MultipleParam],
109
+ block_param: Param?
110
+ ) -> void
31
111
 
32
- def initialize: (leading_params: untyped, optional_params: untyped, rest_param: untyped, trailing_params: untyped, block_param: untyped) -> void
112
+ def params: () -> Array[Param | MultipleParam]
33
113
 
34
- def params: () -> untyped
114
+ def self.from_node: (Parser::AST::Node node, annotations: AST::Annotation::Collection) -> BlockParams
35
115
 
36
- def self.from_node: (untyped node, annotations: untyped) -> (nil | untyped)
116
+ def self.from_multiple: (Parser::AST::Node node, AST::Annotation::Collection) -> MultipleParam
37
117
 
38
- def params_type: (?hint: untyped?) -> untyped
118
+ def params_type: (?hint: Interface::Function::Params?) -> Interface::Function::Params
39
119
 
40
- def params_type0: (hint: untyped) -> (nil | untyped)
120
+ def params_type0: (hint: nil) -> Interface::Function::Params
121
+ | (hint: Interface::Function::Params?) -> Interface::Function::Params?
41
122
 
42
- def zip: (untyped params_type, untyped block) -> untyped
123
+ def zip: (
124
+ Interface::Function::Params params_type,
125
+ Interface::Block? block,
126
+ factory: AST::Types::Factory
127
+ ) -> Array[[Param | MultipleParam, AST::Types::t]]
43
128
 
44
- def expandable_params?: (untyped params_type) -> (untyped | nil)
129
+ # Returns true if given possible block yields are subject to auto expand/splat
130
+ #
131
+ # ```rbs
132
+ # { (Array[String]) -> void } # Array[String]
133
+ # { ([Integer, String]) -> void } # [Integer, String]
134
+ # { (String) -> void } # nil
135
+ # ```
136
+ #
137
+ def expandable_params?: (Interface::Function::Params params_type, AST::Types::Factory) -> AST::Types::t?
45
138
 
46
- def expandable?: () -> untyped
139
+ # Returns true if the block is defined to expand/splat automatically
140
+ #
141
+ # ```ruby
142
+ # foo {|x, y| ... } # true (has multiple parameters)
143
+ # foo {|x, *x| ... } # true (has normal and rest parameters)
144
+ # foo {|x,| ... } # true s(:arg, :x) (has one parameter with trailing comma)
145
+ # foo {|x| ... } # false s(:procarg0, s(:arg :x))
146
+ # ```
147
+ #
148
+ def expandable?: () -> bool
47
149
 
48
- def each: () { (Param) -> void } -> void
49
- | () -> Enumerator[Param, void]
150
+ def each: () { (Param | MultipleParam) -> void } -> void
151
+ | () -> Enumerator[Param | MultipleParam, void]
50
152
  end
51
153
  end
52
154
  end