rbs 1.7.1 → 2.0.0.pre2
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 +104 -3
- data/core/array.rbs +3 -3
- data/core/builtin.rbs +4 -0
- data/core/enumerable.rbs +3 -3
- data/docs/collection.md +23 -1
- data/docs/syntax.md +117 -61
- data/ext/rbs_extension/constants.c +2 -6
- data/ext/rbs_extension/constants.h +1 -2
- data/ext/rbs_extension/parser.c +220 -184
- data/ext/rbs_extension/parserstate.c +6 -2
- data/ext/rbs_extension/parserstate.h +10 -0
- data/ext/rbs_extension/ruby_objs.c +17 -17
- data/ext/rbs_extension/ruby_objs.h +3 -4
- data/lib/rbs/ast/declarations.rb +6 -99
- data/lib/rbs/ast/type_param.rb +134 -0
- data/lib/rbs/cli.rb +33 -5
- data/lib/rbs/collection/config/lockfile_generator.rb +26 -18
- data/lib/rbs/collection/sources/git.rb +18 -7
- data/lib/rbs/collection/sources/rubygems.rb +7 -0
- data/lib/rbs/collection/sources/stdlib.rb +6 -0
- data/lib/rbs/definition.rb +9 -0
- data/lib/rbs/definition_builder.rb +78 -16
- data/lib/rbs/environment.rb +32 -8
- data/lib/rbs/environment_loader.rb +0 -2
- data/lib/rbs/environment_walker.rb +4 -1
- data/lib/rbs/errors.rb +31 -6
- data/lib/rbs/location_aux.rb +2 -0
- data/lib/rbs/method_type.rb +29 -6
- data/lib/rbs/prototype/rb.rb +3 -3
- data/lib/rbs/prototype/rbi.rb +8 -6
- data/lib/rbs/prototype/runtime.rb +4 -4
- data/lib/rbs/type_alias_regularity.rb +115 -0
- data/lib/rbs/types.rb +99 -22
- data/lib/rbs/validator.rb +99 -15
- data/lib/rbs/variance_calculator.rb +60 -31
- data/lib/rbs/version.rb +1 -1
- data/lib/rbs/writer.rb +2 -14
- data/lib/rbs.rb +2 -0
- data/schema/decls.json +19 -46
- data/schema/methodType.json +1 -1
- data/schema/typeParam.json +36 -0
- data/schema/types.json +8 -2
- data/sig/collection/collections.rbs +11 -2
- data/sig/collection/config.rbs +2 -2
- data/sig/declarations.rbs +15 -62
- data/sig/definition.rbs +11 -1
- data/sig/definition_builder.rbs +37 -1
- data/sig/environment.rbs +7 -1
- data/sig/environment_walker.rbs +26 -0
- data/sig/errors.rbs +28 -3
- data/sig/location.rbs +3 -1
- data/sig/locator.rbs +1 -1
- data/sig/method_types.rbs +25 -4
- data/sig/type_alias_regularity.rbs +92 -0
- data/sig/type_param.rbs +74 -0
- data/sig/types.rbs +37 -8
- data/sig/validator.rbs +38 -2
- data/sig/variance_calculator.rbs +50 -0
- data/sig/writer.rbs +1 -1
- data/stdlib/bigdecimal-math/0/manifest.yaml +2 -0
- data/stdlib/csv/0/manifest.yaml +2 -0
- data/stdlib/date/0/date.rbs +2 -2
- data/stdlib/logger/0/manifest.yaml +2 -0
- data/stdlib/net-http/0/manifest.yaml +2 -0
- data/stdlib/openssl/0/manifest.yaml +2 -0
- data/stdlib/prime/0/manifest.yaml +2 -0
- data/stdlib/resolv/0/manifest.yaml +3 -0
- data/stdlib/set/0/set.rbs +3 -3
- data/stdlib/uri/0/common.rbs +10 -5
- data/stdlib/uri/0/ftp.rbs +10 -0
- data/stdlib/uri/0/generic.rbs +34 -34
- data/stdlib/uri/0/mailto.rbs +5 -0
- data/stdlib/uri/0/ws.rbs +10 -0
- data/stdlib/uri/0/wss.rbs +7 -0
- data/stdlib/yaml/0/manifest.yaml +3 -0
- data/steep/Gemfile.lock +10 -10
- metadata +21 -4
data/sig/declarations.rbs
CHANGED
@@ -6,56 +6,6 @@ module RBS
|
|
6
6
|
class Base
|
7
7
|
end
|
8
8
|
|
9
|
-
type variance = :invariant | :covariant | :contravariant
|
10
|
-
|
11
|
-
class ModuleTypeParams
|
12
|
-
class TypeParam
|
13
|
-
# Key
|
14
|
-
# ^^^ name
|
15
|
-
#
|
16
|
-
# unchecked out Elem
|
17
|
-
# ^^^^^^^^^ unchecked
|
18
|
-
# ^^^ variance
|
19
|
-
# ^^^^ name
|
20
|
-
type loc = Location[:name, :variance | :unchecked]
|
21
|
-
|
22
|
-
attr_reader name: Symbol
|
23
|
-
attr_reader variance: variance
|
24
|
-
attr_reader skip_validation: bool
|
25
|
-
attr_reader location: loc?
|
26
|
-
|
27
|
-
def initialize: (name: Symbol, variance: variance, skip_validation: boolish, location: loc?) -> void
|
28
|
-
|
29
|
-
include _ToJson
|
30
|
-
end
|
31
|
-
|
32
|
-
attr_reader params: Array[TypeParam]
|
33
|
-
|
34
|
-
def initialize: () -> void
|
35
|
-
|
36
|
-
def add: (TypeParam param) -> self
|
37
|
-
|
38
|
-
include _HashEqual
|
39
|
-
include _ToJson
|
40
|
-
|
41
|
-
def []: (Symbol) -> TypeParam?
|
42
|
-
|
43
|
-
def each: { (TypeParam) -> void } -> void
|
44
|
-
| () -> Enumerator[TypeParam, void]
|
45
|
-
|
46
|
-
def self.empty: () -> instance
|
47
|
-
|
48
|
-
def variance: (Symbol) -> variance
|
49
|
-
|
50
|
-
def skip_validation?: (Symbol) -> bool
|
51
|
-
|
52
|
-
def empty?: () -> bool
|
53
|
-
|
54
|
-
def size: () -> Integer
|
55
|
-
|
56
|
-
def rename_to: (Array[Symbol] names) -> ModuleTypeParams
|
57
|
-
end
|
58
|
-
|
59
9
|
interface _WithMember
|
60
10
|
def members: () -> Array[untyped]
|
61
11
|
end
|
@@ -118,14 +68,14 @@ module RBS
|
|
118
68
|
include MixinHelper
|
119
69
|
|
120
70
|
attr_reader name: TypeName
|
121
|
-
attr_reader type_params:
|
71
|
+
attr_reader type_params: Array[TypeParam]
|
122
72
|
attr_reader members: Array[member]
|
123
73
|
attr_reader super_class: Super?
|
124
74
|
attr_reader annotations: Array[Annotation]
|
125
75
|
attr_reader location: loc?
|
126
76
|
attr_reader comment: Comment?
|
127
77
|
|
128
|
-
def initialize: (name: TypeName, type_params:
|
78
|
+
def initialize: (name: TypeName, type_params: Array[TypeParam], members: Array[member], super_class: Super?, annotations: Array[Annotation], location: loc?, comment: Comment?) -> void
|
129
79
|
|
130
80
|
include _HashEqual
|
131
81
|
include _ToJson
|
@@ -172,14 +122,14 @@ module RBS
|
|
172
122
|
include MixinHelper
|
173
123
|
|
174
124
|
attr_reader name: TypeName
|
175
|
-
attr_reader type_params:
|
125
|
+
attr_reader type_params: Array[TypeParam]
|
176
126
|
attr_reader members: Array[member]
|
177
127
|
attr_reader location: loc?
|
178
128
|
attr_reader annotations: Array[Annotation]
|
179
129
|
attr_reader self_types: Array[Self]
|
180
130
|
attr_reader comment: Comment?
|
181
131
|
|
182
|
-
def initialize: (name: TypeName, type_params:
|
132
|
+
def initialize: (name: TypeName, type_params: Array[TypeParam], members: Array[member], location: loc?, annotations: Array[Annotation], self_types: Array[Self], comment: Comment?) -> void
|
183
133
|
|
184
134
|
include _HashEqual
|
185
135
|
include _ToJson
|
@@ -202,13 +152,13 @@ module RBS
|
|
202
152
|
type loc = Location[:name | :keyword | :end, :type_params]
|
203
153
|
|
204
154
|
attr_reader name: TypeName
|
205
|
-
attr_reader type_params:
|
155
|
+
attr_reader type_params: Array[TypeParam]
|
206
156
|
attr_reader members: Array[member]
|
207
157
|
attr_reader annotations: Array[Annotation]
|
208
158
|
attr_reader location: loc?
|
209
159
|
attr_reader comment: Comment?
|
210
160
|
|
211
|
-
def initialize: (name: TypeName, type_params:
|
161
|
+
def initialize: (name: TypeName, type_params: Array[TypeParam], members: Array[member], annotations: Array[Annotation], location: loc?, comment: Comment?) -> void
|
212
162
|
|
213
163
|
include MixinHelper
|
214
164
|
|
@@ -217,19 +167,22 @@ module RBS
|
|
217
167
|
end
|
218
168
|
|
219
169
|
class Alias < Base
|
220
|
-
# type loc = Location
|
221
|
-
# ^^^^
|
222
|
-
# ^^^
|
223
|
-
#
|
224
|
-
|
170
|
+
# type loc[T] = Location[T, bot]
|
171
|
+
# ^^^^ keyword
|
172
|
+
# ^^^ name
|
173
|
+
# ^^^ type_params
|
174
|
+
# ^ eq
|
175
|
+
#
|
176
|
+
type loc = Location[:keyword | :name | :eq, :type_params]
|
225
177
|
|
226
178
|
attr_reader name: TypeName
|
179
|
+
attr_reader type_params: Array[TypeParam]
|
227
180
|
attr_reader type: Types::t
|
228
181
|
attr_reader annotations: Array[Annotation]
|
229
182
|
attr_reader location: loc?
|
230
183
|
attr_reader comment: Comment?
|
231
184
|
|
232
|
-
def initialize: (name: TypeName, type: Types::t, annotations: Array[Annotation], location: loc?, comment: Comment?) -> void
|
185
|
+
def initialize: (name: TypeName, type_params: Array[TypeParam], type: Types::t, annotations: Array[Annotation], location: loc?, comment: Comment?) -> void
|
233
186
|
|
234
187
|
include _HashEqual
|
235
188
|
include _ToJson
|
data/sig/definition.rbs
CHANGED
@@ -54,10 +54,20 @@ module RBS
|
|
54
54
|
|
55
55
|
def private?: () -> bool
|
56
56
|
|
57
|
+
# Substitutes type variables to some types.
|
58
|
+
# Takes care of type parameter bounds.
|
59
|
+
#
|
57
60
|
def sub: (Substitution) -> Method
|
58
61
|
|
62
|
+
# Applies the mapping from `Types::t` to `Types::t`.
|
63
|
+
#
|
64
|
+
# Note this method doesn't handle upper bound in type params.
|
65
|
+
# You may want to use `#map_type_bound` explicitly, or `#sub` for simple substitution.
|
66
|
+
#
|
59
67
|
def map_type: () { (Types::t) -> Types::t } -> Method
|
60
68
|
|
69
|
+
def map_type_bound: () { (AST::TypeParam::bound) -> AST::TypeParam::bound } -> Method
|
70
|
+
|
61
71
|
def map_method_type: () { (MethodType) -> MethodType } -> Method
|
62
72
|
end
|
63
73
|
|
@@ -127,7 +137,7 @@ module RBS
|
|
127
137
|
|
128
138
|
def type_params: () -> Array[Symbol]
|
129
139
|
|
130
|
-
def type_params_decl: () -> AST::
|
140
|
+
def type_params_decl: () -> Array[AST::TypeParam]
|
131
141
|
|
132
142
|
def sub: (Substitution) -> Definition
|
133
143
|
|
data/sig/definition_builder.rbs
CHANGED
@@ -33,7 +33,7 @@ module RBS
|
|
33
33
|
def try_cache: (TypeName, cache: Hash[TypeName, Definition | false | nil]) { () -> Definition } -> Definition
|
34
34
|
| [A] (TypeName, cache: Hash[A, Definition | false | nil], key: A) { () -> Definition } -> Definition
|
35
35
|
|
36
|
-
def validate_params_with: (AST::
|
36
|
+
def validate_params_with: (Array[AST::TypeParam], result: VarianceCalculator::Result) { (AST::TypeParam) -> void } -> void
|
37
37
|
|
38
38
|
def validate_type_params: (Definition, ancestors: AncestorBuilder::OneAncestors, methods: MethodBuilder::Methods) -> void
|
39
39
|
|
@@ -43,8 +43,44 @@ module RBS
|
|
43
43
|
|
44
44
|
def define_methods: (Definition, interface_methods: Hash[Symbol, Definition::Method], methods: MethodBuilder::Methods, super_interface_method: bool) -> void
|
45
45
|
|
46
|
+
# Validates presence of type names recursively.
|
47
|
+
# Assumes the type names are already resolved.
|
48
|
+
#
|
49
|
+
def validate_type_presence: (Types::t) -> void
|
50
|
+
|
51
|
+
def validate_type_name: (TypeName, Location[untyped, untyped]?) -> void
|
52
|
+
|
53
|
+
# Expand a type alias of given name without type arguments.
|
54
|
+
# Raises an error if the type alias requires arguments.
|
55
|
+
#
|
56
|
+
# Assume `type foo[T] = [T, T]`:
|
57
|
+
#
|
58
|
+
# ```
|
59
|
+
# expand_alias("::foo") # => error
|
60
|
+
# ```
|
61
|
+
#
|
46
62
|
def expand_alias: (TypeName) -> Types::t
|
47
63
|
|
64
|
+
# Expand a type alias of given name with arguments of `untyped`.
|
65
|
+
#
|
66
|
+
# Assume `type foo[T] = [T, T]`:
|
67
|
+
#
|
68
|
+
# ```
|
69
|
+
# expand_alias1("::foo") # => [untyped, untyped]
|
70
|
+
# ```
|
71
|
+
#
|
72
|
+
def expand_alias1: (TypeName) -> Types::t
|
73
|
+
|
74
|
+
# Expand a type alias of given name with `args`.
|
75
|
+
#
|
76
|
+
# Assume `type foo[T] = [T, T]`:
|
77
|
+
#
|
78
|
+
# ```
|
79
|
+
# expand_alias2("::foo", ["::Integer"]) # => [::Integer, ::Integer]
|
80
|
+
# ```
|
81
|
+
#
|
82
|
+
def expand_alias2: (TypeName, Array[Types::t] args) -> Types::t
|
83
|
+
|
48
84
|
def update: (env: Environment, ancestor_builder: AncestorBuilder, except: _Each[TypeName]) -> DefinitionBuilder
|
49
85
|
end
|
50
86
|
end
|
data/sig/environment.rbs
CHANGED
@@ -31,7 +31,9 @@ module RBS
|
|
31
31
|
|
32
32
|
def validate_type_params: () -> void
|
33
33
|
|
34
|
-
def
|
34
|
+
def compatible_params?: (Array[AST::TypeParam], Array[AST::TypeParam]) -> boolish
|
35
|
+
|
36
|
+
def type_params: () -> Array[AST::TypeParam]
|
35
37
|
|
36
38
|
def primary: () -> D[module_decl]
|
37
39
|
end
|
@@ -96,6 +98,10 @@ module RBS
|
|
96
98
|
|
97
99
|
def resolve_member: (TypeNameResolver, AST::Members::t, context: Array[Namespace]) -> AST::Members::t
|
98
100
|
|
101
|
+
def resolve_method_type: (TypeNameResolver, RBS::MethodType, context: Array[Namespace]) -> RBS::MethodType
|
102
|
+
|
103
|
+
def resolve_type_params: (TypeNameResolver resolver, Array[AST::TypeParam], context: Array[Namespace]) -> Array[AST::TypeParam]
|
104
|
+
|
99
105
|
def absolute_type: (TypeNameResolver, Types::t, context: Array[Namespace]) -> Types::t
|
100
106
|
|
101
107
|
def absolute_type_name: (TypeNameResolver, TypeName, context: Array[Namespace]) -> TypeName
|
data/sig/environment_walker.rbs
CHANGED
@@ -1,4 +1,28 @@
|
|
1
1
|
module RBS
|
2
|
+
# EnvironmentWalker provides topological sort of class/module definitions.
|
3
|
+
#
|
4
|
+
# If a method, attribute, or ancestor in a class definition have a reference to another class, it is dependency.
|
5
|
+
#
|
6
|
+
# ```rb
|
7
|
+
# walker = EnvironmentWalker.new(env: env)
|
8
|
+
#
|
9
|
+
# walker.each_strongly_connected_component do |scc|
|
10
|
+
# # Yields an array of strongly connected components.
|
11
|
+
# end
|
12
|
+
# ```
|
13
|
+
#
|
14
|
+
# The `#only_ancestors!` method limits the dependency only to ancestors.
|
15
|
+
# Only super classes and included modules are dependencies with the option.
|
16
|
+
# This is useful to calculate the dependencies of class hierarchy.
|
17
|
+
#
|
18
|
+
# ```rb
|
19
|
+
# walker = EnvironmentWalker.new(env: env).only_ancestors!
|
20
|
+
#
|
21
|
+
# walker.each_strongly_connected_component do |scc|
|
22
|
+
# # Yields an array of strongly connected components.
|
23
|
+
# end
|
24
|
+
# ```
|
25
|
+
#
|
2
26
|
class EnvironmentWalker
|
3
27
|
class InstanceNode
|
4
28
|
attr_reader type_name: TypeName
|
@@ -32,6 +56,8 @@ module RBS
|
|
32
56
|
|
33
57
|
def tsort_each_child: (node) { (node) -> void } -> void
|
34
58
|
|
59
|
+
private
|
60
|
+
|
35
61
|
def each_type_name: (Types::t) { (TypeName) -> void } -> void
|
36
62
|
|
37
63
|
def each_type_node: (Types::t) { (node) -> void } -> void
|
data/sig/errors.rbs
CHANGED
@@ -179,10 +179,10 @@ module RBS
|
|
179
179
|
|
180
180
|
class InvalidVarianceAnnotationError < DefinitionError
|
181
181
|
attr_reader type_name: TypeName
|
182
|
-
attr_reader param: AST::
|
182
|
+
attr_reader param: AST::TypeParam
|
183
183
|
attr_reader location: Location[untyped, untyped]?
|
184
184
|
|
185
|
-
def initialize: (type_name: TypeName, param: AST::
|
185
|
+
def initialize: (type_name: TypeName, param: AST::TypeParam, location: Location[untyped, untyped]?) -> void
|
186
186
|
end
|
187
187
|
|
188
188
|
class RecursiveAliasDefinitionError < DefinitionError
|
@@ -212,7 +212,7 @@ module RBS
|
|
212
212
|
def mixin_name: () -> String
|
213
213
|
end
|
214
214
|
|
215
|
-
class RecursiveTypeAliasError <
|
215
|
+
class RecursiveTypeAliasError < BaseError
|
216
216
|
attr_reader alias_names: Array[TypeName]
|
217
217
|
attr_reader location: Location[untyped, untyped]?
|
218
218
|
|
@@ -220,4 +220,29 @@ module RBS
|
|
220
220
|
|
221
221
|
def name: () -> String
|
222
222
|
end
|
223
|
+
|
224
|
+
class NonregularTypeAliasError < BaseError
|
225
|
+
# Diagnostic reported from `TypeAliasRegularity`.
|
226
|
+
attr_reader diagnostic: TypeAliasRegularity::Diagnostic
|
227
|
+
|
228
|
+
# Location of the definition.
|
229
|
+
attr_reader location: Location[untyped, untyped]?
|
230
|
+
|
231
|
+
def initialize: (diagnostic: TypeAliasRegularity::Diagnostic, location: Location[untyped, untyped]?) -> void
|
232
|
+
end
|
233
|
+
|
234
|
+
class CyclicTypeParameterBound < BaseError
|
235
|
+
attr_reader location: Location[untyped, untyped]?
|
236
|
+
|
237
|
+
# Array of parameters which contains cyclic dependencies.
|
238
|
+
attr_reader params: Array[AST::TypeParam]
|
239
|
+
|
240
|
+
# Type name
|
241
|
+
attr_reader type_name: TypeName
|
242
|
+
|
243
|
+
# Method name
|
244
|
+
attr_reader method_name: Symbol?
|
245
|
+
|
246
|
+
def initialize: (type_name: TypeName, method_name: Symbol?, params: Array[AST::TypeParam], location: Location[untyped, untyped]?) -> void
|
247
|
+
end
|
223
248
|
end
|
data/sig/location.rbs
CHANGED
@@ -8,7 +8,7 @@ module RBS
|
|
8
8
|
#
|
9
9
|
# ```
|
10
10
|
#
|
11
|
-
class Location[RequiredChildKeys, OptionalChildKeys]
|
11
|
+
class Location[in RequiredChildKeys, in OptionalChildKeys]
|
12
12
|
# The buffer this location points on.
|
13
13
|
attr_reader buffer (): Buffer
|
14
14
|
|
@@ -79,6 +79,8 @@ module RBS
|
|
79
79
|
| (OptionalChildKeys) -> Location[bot, bot]?
|
80
80
|
| (Symbol) -> Location[bot, bot]?
|
81
81
|
|
82
|
+
alias aref []
|
83
|
+
|
82
84
|
def each_optional_key: () { (Symbol) -> void } -> void
|
83
85
|
| () -> Enumerator[Symbol, void]
|
84
86
|
|
data/sig/locator.rbs
CHANGED
data/sig/method_types.rbs
CHANGED
@@ -1,27 +1,48 @@
|
|
1
1
|
module RBS
|
2
2
|
class MethodType
|
3
|
-
|
3
|
+
# () -> void
|
4
|
+
# ^^^^^^^^^^ type
|
5
|
+
#
|
6
|
+
# [A] () { () -> A } -> A
|
7
|
+
# ^^^ type_params
|
8
|
+
# ^^^^^^^^^^^^^^^^^^^ type
|
9
|
+
#
|
10
|
+
type loc = Location[:type, :type_params]
|
11
|
+
|
12
|
+
attr_reader type_params: Array[AST::TypeParam]
|
4
13
|
attr_reader type: Types::Function
|
5
14
|
attr_reader block: Types::Block?
|
6
|
-
attr_reader location:
|
15
|
+
attr_reader location: loc?
|
7
16
|
|
8
|
-
def initialize: (type_params: Array[
|
17
|
+
def initialize: (type_params: Array[AST::TypeParam], type: Types::Function, block: Types::Block?, location: loc?) -> void
|
9
18
|
|
10
19
|
def ==: (untyped other) -> bool
|
11
20
|
|
12
21
|
include _ToJson
|
13
22
|
|
23
|
+
# Substitute type variables to some types.
|
24
|
+
# Takes care of type parameter bounds.
|
25
|
+
#
|
14
26
|
def sub: (Substitution) -> MethodType
|
15
27
|
|
16
|
-
def update: (?type_params: Array[
|
28
|
+
def update: (?type_params: Array[AST::TypeParam], ?type: Types::Function, ?block: Types::Block?, ?location: loc?) -> MethodType
|
17
29
|
|
18
30
|
def free_variables: (?Set[Symbol] set) -> Set[Symbol]
|
19
31
|
|
32
|
+
# Apply the mapping included in the MethodType.
|
33
|
+
#
|
34
|
+
# Note that type bound in generics parameter is not handled by this method.
|
35
|
+
# You may want to use `#map_type_bound` explicitly, or `#sub` for simple substitution.
|
36
|
+
#
|
20
37
|
def map_type: () { (Types::t) -> Types::t } -> MethodType
|
21
38
|
|
39
|
+
def map_type_bound: () { (AST::TypeParam::bound) -> AST::TypeParam::bound } -> MethodType
|
40
|
+
|
22
41
|
def each_type: () { (Types::t) -> void } -> void
|
23
42
|
| () -> Enumerator[Types::t, void]
|
24
43
|
|
25
44
|
def to_s: () -> String
|
45
|
+
|
46
|
+
def type_param_names: () -> Array[Symbol]
|
26
47
|
end
|
27
48
|
end
|
@@ -0,0 +1,92 @@
|
|
1
|
+
module RBS
|
2
|
+
# `TypeAliasRegularity` validates if a type alias is regular or not.
|
3
|
+
#
|
4
|
+
# Generic and recursive type alias cannot be polymorphic in their definitions.
|
5
|
+
#
|
6
|
+
# ```rbs
|
7
|
+
# type foo[T] = Integer
|
8
|
+
# | foo[T]? # Allowed. The type argument of `foo` doesn't change.
|
9
|
+
#
|
10
|
+
# type bar[T] = Integer
|
11
|
+
# | foo[T]
|
12
|
+
# | foo[Array[T]] # Allowed. There are two type arguments `T` and `Array[T]` of `foo`, but it's not definition of `foo`.
|
13
|
+
#
|
14
|
+
# type baz[T] = Integer
|
15
|
+
# | baz[Array[T]] # Error. Recursive definition of `baz` has different type argument from the definition.
|
16
|
+
# ```
|
17
|
+
#
|
18
|
+
# The `#nonregular?` method can be used to test if given type name is regular or not.
|
19
|
+
#
|
20
|
+
# ```rb
|
21
|
+
# validator = RBS::TypeAliasRegularity.validate(env: env)
|
22
|
+
#
|
23
|
+
# validator.nonregular?(TypeName("::foo")) # => nil
|
24
|
+
# validator.nonregular?(TypeName("::bar")) # => nil
|
25
|
+
# validator.nonregular?(TypeName("::baz")) # => TypeAliasRegularity::Diagnostic
|
26
|
+
# ```
|
27
|
+
#
|
28
|
+
# A special case is when the type argument is `untyped`.
|
29
|
+
#
|
30
|
+
# ```rbs
|
31
|
+
# type foo[T] = Integer | foo[untyped] # This is allowed.
|
32
|
+
# ```
|
33
|
+
#
|
34
|
+
class TypeAliasRegularity
|
35
|
+
attr_reader env: Environment
|
36
|
+
|
37
|
+
attr_reader builder: DefinitionBuilder
|
38
|
+
|
39
|
+
attr_reader diagnostics: Hash[TypeName, Diagnostic]
|
40
|
+
|
41
|
+
# `Diagnostic` represents an non-regular type alias declaration error.
|
42
|
+
# It consists of the name of the alias type and a type on which the nonregularity is detected.
|
43
|
+
#
|
44
|
+
# ```rbs
|
45
|
+
# type t[T] = Integer | t[T?]
|
46
|
+
# ```
|
47
|
+
#
|
48
|
+
# The type `t` is nonregular because it contains `t[T?]` on it's right hand side.
|
49
|
+
#
|
50
|
+
# ```
|
51
|
+
# diagnostic = validator.nonregular?(TypeName("::t"))
|
52
|
+
# diagnostic.type_name # => TypeName("::t")
|
53
|
+
# diagnostic.nonregular_type # => t[T?]
|
54
|
+
# ```
|
55
|
+
#
|
56
|
+
class Diagnostic
|
57
|
+
attr_reader type_name: TypeName
|
58
|
+
|
59
|
+
attr_reader nonregular_type: Types::Alias
|
60
|
+
|
61
|
+
def initialize: (type_name: TypeName, nonregular_type: Types::Alias) -> void
|
62
|
+
end
|
63
|
+
|
64
|
+
# Returns new instance which already run `#validate`.
|
65
|
+
#
|
66
|
+
def self.validate: (env: Environment) -> TypeAliasRegularity
|
67
|
+
|
68
|
+
def initialize: (env: Environment) -> void
|
69
|
+
|
70
|
+
# Returns `Diagnostic` instance if the alias type is nonregular.
|
71
|
+
# Regurns `nil` if the alias type is regular.
|
72
|
+
#
|
73
|
+
def nonregular?: (TypeName) -> Diagnostic?
|
74
|
+
|
75
|
+
def validate: () -> void
|
76
|
+
|
77
|
+
private
|
78
|
+
|
79
|
+
def validate_alias_type: (Types::Alias, Set[TypeName], Hash[TypeName, Types::Alias]) -> void
|
80
|
+
|
81
|
+
# Returns alias type for given type name, if the alias is generic.
|
82
|
+
# Returns nil if the type alias is not generic.
|
83
|
+
#
|
84
|
+
def build_alias_type: (TypeName) -> Types::Alias?
|
85
|
+
|
86
|
+
def compatible_args?: (Array[Types::t], Array[Types::t]) -> boolish
|
87
|
+
|
88
|
+
def each_alias_type: (Types::t) { (Types::Alias) -> void } -> void
|
89
|
+
|
90
|
+
def each_mutual_alias_defs: () { (Set[TypeName]) -> void } -> void
|
91
|
+
end
|
92
|
+
end
|
data/sig/type_param.rbs
ADDED
@@ -0,0 +1,74 @@
|
|
1
|
+
module RBS
|
2
|
+
module AST
|
3
|
+
class TypeParam
|
4
|
+
# Key
|
5
|
+
# ^^^ name
|
6
|
+
#
|
7
|
+
# unchecked out Elem < _ToJson
|
8
|
+
# ^^^^^^^^^ unchecked
|
9
|
+
# ^^^ variance
|
10
|
+
# ^^^^ name
|
11
|
+
# ^^^^^^^^^ upper_bound
|
12
|
+
type loc = Location[:name, :variance | :unchecked | :upper_bound]
|
13
|
+
|
14
|
+
type variance = :invariant | :covariant | :contravariant
|
15
|
+
|
16
|
+
type bound = Types::ClassInstance | Types::ClassSingleton | Types::Interface
|
17
|
+
|
18
|
+
attr_reader name: Symbol
|
19
|
+
attr_reader variance: variance
|
20
|
+
attr_reader location: loc?
|
21
|
+
|
22
|
+
attr_reader upper_bound: bound?
|
23
|
+
|
24
|
+
def initialize: (name: Symbol, variance: variance, upper_bound: bound?, location: loc?) -> void
|
25
|
+
|
26
|
+
include _ToJson
|
27
|
+
|
28
|
+
def ==: (untyped) -> bool
|
29
|
+
|
30
|
+
def eql?: (untyped) -> bool
|
31
|
+
|
32
|
+
def hash: () -> Integer
|
33
|
+
|
34
|
+
@unchecked: bool
|
35
|
+
|
36
|
+
def unchecked!: (?boolish) -> self
|
37
|
+
|
38
|
+
def unchecked?: () -> bool
|
39
|
+
|
40
|
+
def map_type: () { (bound) -> bound } -> TypeParam
|
41
|
+
|
42
|
+
# Helper function to resolve _class instance types_ to _type variables_.
|
43
|
+
#
|
44
|
+
# We need this step because RBS language has an identical syntax for both unqualified class instance types and type variables.
|
45
|
+
# `String` may be an instance of `::String` class or type variable depending on the list of bound type variables.
|
46
|
+
#
|
47
|
+
# So, we need second pass to parse the following generics parameter declaration.
|
48
|
+
#
|
49
|
+
# ```rbs
|
50
|
+
# class Foo[X < _Each[Y], Y]
|
51
|
+
# # ^ We want this `Y` to be a type variable.
|
52
|
+
# end
|
53
|
+
# ```
|
54
|
+
#
|
55
|
+
def self.resolve_variables: (Array[TypeParam]) -> void
|
56
|
+
|
57
|
+
def self.subst_var: (Set[Symbol], Types::t) -> Types::t
|
58
|
+
|
59
|
+
# Rename type parameter name.
|
60
|
+
#
|
61
|
+
# The renaming cannot be done separately because a set of `TypeParam` decls may be mutual recursive.
|
62
|
+
#
|
63
|
+
# Example:
|
64
|
+
#
|
65
|
+
# * Renaming `A -> X, B -> Y`
|
66
|
+
# * Input `[A, B < _Pushable[A]]`
|
67
|
+
# * Result `[X, Y < _Pushable[X]]`
|
68
|
+
#
|
69
|
+
def self.rename: (Array[TypeParam], new_names: Array[Symbol]) -> Array[TypeParam]
|
70
|
+
|
71
|
+
def to_s: () -> String
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
data/sig/types.rbs
CHANGED
@@ -55,6 +55,11 @@ module RBS
|
|
55
55
|
module EmptyEachType
|
56
56
|
def each_type: () { (t) -> void } -> void
|
57
57
|
| () -> Enumerator[t, void]
|
58
|
+
|
59
|
+
# `map_type` returns itself, because there is no sub type.
|
60
|
+
#
|
61
|
+
def map_type: () { (t) -> t } -> self
|
62
|
+
| () -> Enumerator[t, self]
|
58
63
|
end
|
59
64
|
|
60
65
|
module NoTypeName
|
@@ -199,6 +204,9 @@ module RBS
|
|
199
204
|
include _TypeBase
|
200
205
|
|
201
206
|
attr_reader location: loc?
|
207
|
+
|
208
|
+
def map_type: () { (t) -> t } -> Interface
|
209
|
+
| () -> Enumerator[t, Interface]
|
202
210
|
end
|
203
211
|
|
204
212
|
# ClassInstance represents a type of an instance of a class.
|
@@ -224,21 +232,30 @@ module RBS
|
|
224
232
|
attr_reader location: loc?
|
225
233
|
|
226
234
|
include _TypeBase
|
235
|
+
|
236
|
+
def map_type: () { (t) -> t } -> ClassInstance
|
237
|
+
| () -> Enumerator[t, ClassInstance]
|
227
238
|
end
|
228
239
|
|
229
240
|
class Alias
|
230
|
-
|
241
|
+
# foo
|
242
|
+
# ^^^ => name
|
243
|
+
#
|
244
|
+
# foo[bar, baz]
|
245
|
+
# ^^^ => name
|
246
|
+
# ^^^^^^^^^^ => args
|
247
|
+
#
|
248
|
+
type loc = Location[:name, :args]
|
231
249
|
|
232
|
-
|
250
|
+
attr_reader location: loc?
|
233
251
|
|
234
|
-
def initialize: (name: TypeName, location: loc?) -> void
|
252
|
+
def initialize: (name: TypeName, args: Array[t], location: loc?) -> void
|
235
253
|
|
236
254
|
include _TypeBase
|
237
|
-
include
|
238
|
-
include NoSubst
|
239
|
-
include EmptyEachType
|
255
|
+
include Application
|
240
256
|
|
241
|
-
|
257
|
+
def map_type: () { (t) -> t } -> Alias
|
258
|
+
| () -> Enumerator[t, Alias]
|
242
259
|
end
|
243
260
|
|
244
261
|
class Tuple
|
@@ -251,6 +268,9 @@ module RBS
|
|
251
268
|
include _TypeBase
|
252
269
|
|
253
270
|
attr_reader location: loc?
|
271
|
+
|
272
|
+
def map_type: () { (t) -> t } -> Tuple
|
273
|
+
| () -> Enumerator[t, Tuple]
|
254
274
|
end
|
255
275
|
|
256
276
|
class Record
|
@@ -263,6 +283,9 @@ module RBS
|
|
263
283
|
include _TypeBase
|
264
284
|
|
265
285
|
attr_reader location: loc?
|
286
|
+
|
287
|
+
def map_type: () { (t) -> t } -> Record
|
288
|
+
| () -> Enumerator[t, Record]
|
266
289
|
end
|
267
290
|
|
268
291
|
class Optional
|
@@ -275,6 +298,9 @@ module RBS
|
|
275
298
|
include _TypeBase
|
276
299
|
|
277
300
|
attr_reader location: loc?
|
301
|
+
|
302
|
+
def map_type: () { (t) -> t } -> Optional
|
303
|
+
| () -> Enumerator[t, Optional]
|
278
304
|
end
|
279
305
|
|
280
306
|
class Union
|
@@ -392,7 +418,7 @@ module RBS
|
|
392
418
|
|
393
419
|
def sub: (Substitution) -> Block
|
394
420
|
|
395
|
-
def map_type: () { (
|
421
|
+
def map_type: () { (t) -> t } -> Block
|
396
422
|
end
|
397
423
|
|
398
424
|
class Proc
|
@@ -406,6 +432,9 @@ module RBS
|
|
406
432
|
include _TypeBase
|
407
433
|
|
408
434
|
attr_reader location: loc?
|
435
|
+
|
436
|
+
def map_type: () { (t) -> t } -> Proc
|
437
|
+
| () -> Enumerator[t, Proc]
|
409
438
|
end
|
410
439
|
|
411
440
|
class Literal
|