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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +20 -0
- data/Gemfile +0 -1
- data/Gemfile.lock +12 -11
- data/Gemfile.steep +1 -1
- data/Gemfile.steep.lock +9 -9
- data/README.md +3 -3
- data/Steepfile +23 -0
- data/bin/steep-prof +2 -1
- data/lib/steep/annotation_parser.rb +1 -1
- data/lib/steep/ast/types/class.rb +4 -0
- data/lib/steep/ast/types/factory.rb +86 -602
- data/lib/steep/ast/types/instance.rb +4 -0
- data/lib/steep/ast/types/literal.rb +1 -1
- data/lib/steep/ast/types/proc.rb +22 -8
- data/lib/steep/ast/types/self.rb +4 -0
- data/lib/steep/ast/types/union.rb +1 -1
- data/lib/steep/cli.rb +24 -1
- data/lib/steep/diagnostic/ruby.rb +17 -22
- data/lib/steep/drivers/checkfile.rb +205 -0
- data/lib/steep/drivers/validate.rb +3 -1
- data/lib/steep/equatable.rb +2 -0
- data/lib/steep/interface/block.rb +21 -11
- data/lib/steep/interface/builder.rb +756 -0
- data/lib/steep/interface/function.rb +32 -24
- data/lib/steep/interface/method_type.rb +191 -78
- data/lib/steep/interface/shape.rb +132 -0
- data/lib/steep/interface/substitution.rb +23 -12
- data/lib/steep/interface/type_param.rb +1 -2
- data/lib/steep/path_helper.rb +1 -1
- data/lib/steep/project.rb +5 -7
- data/lib/steep/server/base_worker.rb +2 -2
- data/lib/steep/server/change_buffer.rb +4 -3
- data/lib/steep/server/interaction_worker.rb +1 -1
- data/lib/steep/server/master.rb +69 -9
- data/lib/steep/server/type_check_worker.rb +13 -11
- data/lib/steep/server/worker_process.rb +9 -7
- data/lib/steep/services/completion_provider.rb +15 -3
- data/lib/steep/services/hover_provider/singleton_methods.rb +5 -6
- data/lib/steep/services/signature_service.rb +13 -8
- data/lib/steep/services/type_check_service.rb +2 -0
- data/lib/steep/signature/validator.rb +1 -1
- data/lib/steep/subtyping/check.rb +154 -103
- data/lib/steep/subtyping/relation.rb +3 -3
- data/lib/steep/subtyping/result.rb +20 -2
- data/lib/steep/subtyping/variable_variance.rb +9 -0
- data/lib/steep/type_construction.rb +558 -299
- data/lib/steep/type_inference/block_params.rb +169 -86
- data/lib/steep/type_inference/logic_type_interpreter.rb +9 -14
- data/lib/steep/type_inference/method_params.rb +12 -7
- data/lib/steep/type_inference/send_args.rb +41 -35
- data/lib/steep/type_inference/type_env_builder.rb +1 -1
- data/lib/steep/version.rb +1 -1
- data/lib/steep.rb +71 -2
- data/rbs_collection.steep.lock.yaml +18 -30
- data/rbs_collection.steep.yaml +1 -0
- data/sig/shims/language-server_protocol.rbs +20 -0
- data/sig/shims/tagged_logging.rbs +6 -0
- data/sig/steep/ast/annotation/collection.rbs +6 -6
- data/sig/steep/ast/types/class.rbs +3 -0
- data/sig/steep/ast/types/factory.rbs +38 -32
- data/sig/steep/ast/types/instance.rbs +3 -0
- data/sig/steep/ast/types/intersection.rbs +1 -1
- data/sig/steep/ast/types/literal.rbs +7 -7
- data/sig/steep/ast/types/name.rbs +14 -13
- data/sig/steep/ast/types/proc.rbs +3 -1
- data/sig/steep/ast/types/self.rbs +3 -0
- data/sig/steep/ast/types/var.rbs +1 -1
- data/sig/steep/diagnostic/ruby.rbs +30 -34
- data/sig/steep/drivers/annotations.rbs +17 -0
- data/sig/steep/drivers/check.rbs +33 -0
- data/sig/steep/drivers/checkfile.rbs +26 -0
- data/sig/steep/drivers/diagnostic_printer.rbs +25 -0
- data/sig/steep/drivers/init.rbs +19 -0
- data/sig/steep/drivers/langserver.rbs +35 -0
- data/sig/steep/drivers/print_project.rbs +15 -0
- data/sig/steep/drivers/stats.rbs +37 -0
- data/sig/steep/drivers/utils/driver_helper.rbs +23 -0
- data/sig/steep/drivers/utils/jobs_count.rbs +11 -0
- data/sig/steep/drivers/validate.rbs +15 -0
- data/sig/steep/drivers/vendor.rbs +19 -0
- data/sig/steep/drivers/watch.rbs +27 -0
- data/sig/steep/drivers/worker.rbs +31 -0
- data/sig/steep/equatable.rbs +11 -0
- data/sig/steep/index/rbs_index.rbs +91 -0
- data/sig/steep/index/signature_symbol_provider.rbs +29 -0
- data/sig/steep/index/source_index.rbs +63 -0
- data/sig/steep/interface/block.rbs +3 -1
- data/sig/steep/interface/builder.rbs +152 -0
- data/sig/steep/interface/function.rbs +67 -55
- data/sig/steep/interface/method_type.rbs +60 -12
- data/sig/steep/interface/shape.rbs +61 -0
- data/sig/steep/interface/substitution.rbs +18 -22
- data/sig/steep/interface/type_param.rbs +9 -1
- data/sig/steep/path_helper.rbs +7 -0
- data/sig/steep/project/pattern.rbs +10 -10
- data/sig/steep/project/target.rbs +2 -2
- data/sig/steep/project.rbs +15 -8
- data/sig/steep/server/base_worker.rbs +49 -0
- data/sig/steep/server/change_buffer.rbs +32 -0
- data/sig/steep/server/interaction_worker.rbs +41 -0
- data/sig/steep/server/lsp_formatter.rbs +29 -0
- data/sig/steep/server/master.rbs +260 -0
- data/sig/steep/server/type_check_worker.rbs +135 -0
- data/sig/steep/server/worker_process.rbs +29 -0
- data/sig/steep/services/completion_provider.rbs +5 -5
- data/sig/steep/services/content_change.rbs +14 -12
- data/sig/steep/services/file_loader.rbs +12 -4
- data/sig/steep/services/hover_provider/singleton_methods.rbs +1 -1
- data/sig/steep/services/path_assignment.rbs +7 -7
- data/sig/steep/services/signature_service.rbs +67 -40
- data/sig/steep/services/type_check_service.rbs +53 -39
- data/sig/steep/subtyping/check.rbs +80 -44
- data/sig/steep/subtyping/relation.rbs +24 -22
- data/sig/steep/subtyping/result.rbs +48 -30
- data/sig/steep/subtyping/variable_variance.rbs +2 -0
- data/sig/steep/type_construction.rbs +132 -23
- data/sig/steep/type_inference/block_params.rbs +120 -18
- data/sig/steep/type_inference/context.rbs +45 -20
- data/sig/steep/type_inference/context_array.rbs +37 -0
- data/sig/steep/type_inference/logic_type_interpreter.rbs +3 -1
- data/sig/steep/type_inference/method_params.rbs +13 -9
- data/sig/steep/type_inference/send_args.rbs +229 -0
- data/sig/steep/type_inference/type_env_builder.rbs +1 -1
- data/sig/steep/typing.rbs +4 -4
- data/sig/steep.rbs +4 -2
- data/smoke/block/e.rb +12 -0
- data/smoke/block/e.rbs +4 -0
- data/smoke/block/test_expectations.yml +12 -0
- data/smoke/regression/block_param_split.rb +7 -0
- data/smoke/regression/block_param_split.rbs +3 -0
- data/smoke/regression/empty_yield.rb +5 -0
- data/smoke/regression/empty_yield.rbs +3 -0
- data/smoke/regression/test_expectations.yml +12 -0
- data/smoke/yield/test_expectations.yml +4 -4
- data/steep.gemspec +2 -1
- metadata +61 -9
- data/lib/steep/interface/interface.rb +0 -34
- data/sig/steep/interface/interface.rbs +0 -23
- 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:
|
3
|
+
class Relation[out Subject < Object]
|
4
|
+
attr_reader sub_type: Subject
|
5
5
|
|
6
|
-
attr_reader super_type:
|
6
|
+
attr_reader super_type: Subject
|
7
7
|
|
8
|
-
def initialize: (sub_type:
|
8
|
+
def initialize: (sub_type: Subject, super_type: Subject) -> void
|
9
9
|
|
10
|
-
def hash: () ->
|
10
|
+
def hash: () -> Integer
|
11
11
|
|
12
|
-
def ==: (untyped other) ->
|
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: () ->
|
18
|
+
def to_ary: () -> [Subject, Subject]
|
19
19
|
|
20
|
-
def type?: () ->
|
20
|
+
def type?: () -> bool
|
21
21
|
|
22
|
-
def interface?: () ->
|
22
|
+
def interface?: () -> bool
|
23
23
|
|
24
|
-
def method?: () ->
|
24
|
+
def method?: () -> bool
|
25
25
|
|
26
|
-
def function?: () ->
|
26
|
+
def function?: () -> bool
|
27
27
|
|
28
|
-
def params?: () ->
|
28
|
+
def params?: () -> bool
|
29
29
|
|
30
|
-
def block?: () ->
|
30
|
+
def block?: () -> bool
|
31
31
|
|
32
|
-
|
32
|
+
type relation_type = :type | :interface | :method | :function | :params | :block
|
33
33
|
|
34
|
-
def
|
34
|
+
def assert_type: (relation_type `type`) -> void
|
35
35
|
|
36
|
-
def
|
36
|
+
def type!: () -> void
|
37
37
|
|
38
|
-
def
|
38
|
+
def interface!: () -> void
|
39
39
|
|
40
|
-
def
|
40
|
+
def method!: () -> void
|
41
41
|
|
42
|
-
def
|
42
|
+
def function!: () -> void
|
43
43
|
|
44
|
-
def
|
44
|
+
def params!: () -> void
|
45
45
|
|
46
|
-
def
|
46
|
+
def block!: () -> void
|
47
47
|
|
48
|
-
def
|
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:
|
15
|
+
def then: () { (self) -> void } -> self
|
16
16
|
|
17
|
-
def else:
|
17
|
+
def else: () { (self) -> void } -> self
|
18
18
|
|
19
|
-
def failure_path: (?
|
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:
|
31
|
+
attr_reader child: t
|
32
32
|
|
33
|
-
def initialize: (untyped relation) { (untyped) ->
|
33
|
+
def initialize: (Relation[untyped] relation) { (Relation[untyped]) -> t } -> void
|
34
34
|
|
35
|
-
def success?: () ->
|
35
|
+
def success?: () -> bool
|
36
36
|
|
37
|
-
def failure_path: (?
|
37
|
+
def failure_path: (?Array[t] path) -> Array[t]?
|
38
38
|
end
|
39
39
|
|
40
40
|
class All < Base
|
41
|
-
attr_reader branches:
|
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: (*
|
48
|
+
def add: [T < Object] (*Relation[T] relations) { (Relation[T]) -> t? } -> bool
|
47
49
|
|
48
|
-
|
50
|
+
# Returns `false` if no future `#add` changes the result.
|
51
|
+
def add_result: (t?) -> bool
|
49
52
|
|
50
|
-
def
|
53
|
+
def success?: () -> bool
|
54
|
+
|
55
|
+
def failure?: () -> bool
|
51
56
|
|
52
|
-
def failure_path: (?
|
57
|
+
def failure_path: (?Array[t] path) -> Array[t]?
|
53
58
|
end
|
54
59
|
|
55
60
|
class Any < Base
|
56
|
-
attr_reader branches:
|
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: (*
|
68
|
+
def add: [T < Object] (*Relation[T] relations) { (Relation[T]) -> t } -> bool
|
62
69
|
|
63
|
-
def success?: () ->
|
70
|
+
def success?: () -> bool
|
64
71
|
|
65
|
-
def failure_path: (?
|
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: (?
|
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
|
-
|
142
|
+
class SelfBindingMismatch
|
143
|
+
def initialize: () -> void
|
132
144
|
|
133
|
-
|
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: (?
|
154
|
+
def failure_path: (?Array[t] path) -> Array[t]?
|
138
155
|
end
|
139
156
|
|
140
157
|
module Helper
|
141
|
-
def Skip: (untyped relation) ->
|
158
|
+
def Skip: (Relation[untyped] relation) -> Skip
|
142
159
|
|
143
|
-
def Expand: (
|
160
|
+
def Expand: [T < Object] (Relation[T] relation) { (Relation[T]) -> t } -> Expand
|
144
161
|
|
145
|
-
def All: (untyped relation) { () ->
|
162
|
+
def All: (Relation[untyped] relation) { (All) -> void } -> All
|
146
163
|
|
147
|
-
def Any: (untyped relation) { () ->
|
164
|
+
def Any: (Relation[untyped] relation) { (Any) -> void } -> Any
|
148
165
|
|
149
|
-
def Success: (untyped relation) ->
|
166
|
+
def Success: (Relation[untyped] relation) -> Success
|
150
167
|
|
151
168
|
alias success Success
|
152
169
|
|
153
|
-
def Failure: (untyped relation,
|
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: () ->
|
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::
|
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
|
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::
|
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:
|
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: (
|
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
|
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
|
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:
|
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: (
|
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: (
|
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::
|
302
|
+
def try_tuple_type!: (Parser::AST::Node node, ?hint: AST::Types::Tuple?) -> Pair
|
236
303
|
|
237
|
-
|
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
|
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
|
-
|
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:
|
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
|
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
|
-
|
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
|
98
|
+
attr_reader rest_param: Param?
|
25
99
|
|
26
|
-
attr_reader
|
100
|
+
attr_reader trailing_params: Array[Param | MultipleParam]
|
27
101
|
|
28
|
-
attr_reader
|
102
|
+
attr_reader block_param: Param?
|
29
103
|
|
30
|
-
|
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
|
112
|
+
def params: () -> Array[Param | MultipleParam]
|
33
113
|
|
34
|
-
def
|
114
|
+
def self.from_node: (Parser::AST::Node node, annotations: AST::Annotation::Collection) -> BlockParams
|
35
115
|
|
36
|
-
def self.
|
116
|
+
def self.from_multiple: (Parser::AST::Node node, AST::Annotation::Collection) -> MultipleParam
|
37
117
|
|
38
|
-
def params_type: (?hint:
|
118
|
+
def params_type: (?hint: Interface::Function::Params?) -> Interface::Function::Params
|
39
119
|
|
40
|
-
def params_type0: (hint:
|
120
|
+
def params_type0: (hint: nil) -> Interface::Function::Params
|
121
|
+
| (hint: Interface::Function::Params?) -> Interface::Function::Params?
|
41
122
|
|
42
|
-
def zip: (
|
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
|
-
|
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
|
-
|
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
|