rbs 1.7.1 → 1.8.0
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 +23 -0
- data/core/array.rbs +3 -3
- data/core/builtin.rbs +4 -0
- data/core/enumerable.rbs +3 -3
- data/docs/syntax.md +23 -20
- data/ext/rbs_extension/parser.c +96 -94
- data/ext/rbs_extension/ruby_objs.c +8 -6
- data/ext/rbs_extension/ruby_objs.h +2 -2
- data/lib/rbs/ast/declarations.rb +6 -2
- data/lib/rbs/cli.rb +1 -1
- data/lib/rbs/definition_builder.rb +29 -2
- data/lib/rbs/environment.rb +1 -0
- data/lib/rbs/environment_walker.rb +4 -1
- data/lib/rbs/errors.rb +12 -0
- data/lib/rbs/type_alias_regularity.rb +115 -0
- data/lib/rbs/types.rb +10 -22
- data/lib/rbs/validator.rb +40 -7
- data/lib/rbs/variance_calculator.rb +52 -24
- data/lib/rbs/version.rb +1 -1
- data/lib/rbs/writer.rb +1 -1
- data/lib/rbs.rb +1 -0
- data/schema/decls.json +13 -1
- data/schema/types.json +8 -2
- data/sig/declarations.rbs +9 -6
- data/sig/definition_builder.rbs +29 -0
- data/sig/environment_walker.rbs +26 -0
- data/sig/errors.rbs +10 -0
- data/sig/type_alias_regularity.rbs +92 -0
- data/sig/types.rbs +11 -8
- data/sig/validator.rbs +7 -0
- data/sig/variance_calculator.rbs +50 -0
- data/stdlib/date/0/date.rbs +2 -2
- data/stdlib/set/0/set.rbs +3 -3
- data/steep/Gemfile.lock +10 -10
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9b12d92ea4eeeb5dbd6de6c5d58351b0306bdcd017d0f1e51a36599766bfded3
|
4
|
+
data.tar.gz: d60cfb836027441a5bb3f85fbebb0e2ab9bc03c49a21f00c3f10d4ab8dd1de65
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9ef926a62415189173d41204d1a16674a4a8331e3fdefafe00a4e52c9cbf0f3eb84281194a5b5c43027455334c13ea0ab14e1b3f0a6b8d5f5644cb80733a246b
|
7
|
+
data.tar.gz: ce07016eee6b4142a66a28d8c7ffc356b3d4fdd747027f2dd521b347efcb6ac791385e903a1e3b9f8d468ec66e13995e341516137ceba990db511982c6d0d206
|
data/CHANGELOG.md
CHANGED
@@ -2,6 +2,29 @@
|
|
2
2
|
|
3
3
|
## master
|
4
4
|
|
5
|
+
## 1.8.0 (2021-12-02)
|
6
|
+
|
7
|
+
RBS 1.8.0 ships with a language feature enchancement, _generic type alias_.
|
8
|
+
You can define a type alias with type parameters now.
|
9
|
+
|
10
|
+
```rbs
|
11
|
+
type list[T] = [T, list[T]] | nil # Defines a list of type T
|
12
|
+
|
13
|
+
type int_list = list[Integer] # List of Integer
|
14
|
+
type string_list = list[String] # List of String
|
15
|
+
```
|
16
|
+
|
17
|
+
You can find the detail in the [PR](https://github.com/ruby/rbs/pull/823).
|
18
|
+
|
19
|
+
### Signature updates
|
20
|
+
|
21
|
+
* `Date#+`, `Date#-` ([\#830](https://github.com/ruby/rbs/pull/830))
|
22
|
+
* `#include?`, `#member?`, `#delete`, `#count` ([\#835](https://github.com/ruby/rbs/pull/835))
|
23
|
+
|
24
|
+
### Language updates
|
25
|
+
|
26
|
+
* Generic type alias ([\#823](https://github.com/ruby/rbs/pull/823))
|
27
|
+
|
5
28
|
## 1.7.1 (2021-11-18)
|
6
29
|
|
7
30
|
### Signature updates
|
data/core/array.rbs
CHANGED
@@ -699,7 +699,7 @@ class Array[unchecked out Elem] < Object
|
|
699
699
|
# ary.count {|x| x%2 == 0} #=> 3
|
700
700
|
#
|
701
701
|
def count: () -> ::Integer
|
702
|
-
| (
|
702
|
+
| (Elem obj) -> ::Integer
|
703
703
|
| () { (Elem) -> boolish } -> ::Integer
|
704
704
|
|
705
705
|
# Calls the given block for each element `n` times or forever if `nil` is given.
|
@@ -733,7 +733,7 @@ class Array[unchecked out Elem] < Object
|
|
733
733
|
# a.delete("z") #=> nil
|
734
734
|
# a.delete("z") {"not found"} #=> "not found"
|
735
735
|
#
|
736
|
-
def delete: (
|
736
|
+
def delete: (Elem obj) -> Elem?
|
737
737
|
| [S, T] (S obj) { (S) -> T } -> (Elem | T)
|
738
738
|
|
739
739
|
# Deletes the element at the specified `index`, returning that element, or `nil`
|
@@ -1029,7 +1029,7 @@ class Array[unchecked out Elem] < Object
|
|
1029
1029
|
# a.include?("b") #=> true
|
1030
1030
|
# a.include?("z") #=> false
|
1031
1031
|
#
|
1032
|
-
def include?: (
|
1032
|
+
def include?: (Elem object) -> bool
|
1033
1033
|
|
1034
1034
|
# Returns the *index* of the first object in `ary` such that the object is `==`
|
1035
1035
|
# to `obj`.
|
data/core/builtin.rbs
CHANGED
data/core/enumerable.rbs
CHANGED
@@ -63,7 +63,7 @@ module Enumerable[unchecked out Elem]: _Each[Elem]
|
|
63
63
|
# ary.count{ |x| x%2==0 } #=> 3
|
64
64
|
# ```
|
65
65
|
def count: () -> Integer
|
66
|
-
| (
|
66
|
+
| (Elem) -> Integer
|
67
67
|
| () { (Elem) -> boolish } -> Integer
|
68
68
|
|
69
69
|
def cycle: (?Integer n) { (Elem arg0) -> untyped } -> NilClass
|
@@ -130,7 +130,7 @@ module Enumerable[unchecked out Elem]: _Each[Elem]
|
|
130
130
|
def group_by: [U] () { (Elem arg0) -> U } -> ::Hash[U, ::Array[Elem]]
|
131
131
|
| () -> ::Enumerator[Elem, ::Array[Elem]]
|
132
132
|
|
133
|
-
def `include?`: (
|
133
|
+
def `include?`: (Elem arg0) -> bool
|
134
134
|
|
135
135
|
def inject: (untyped init, Symbol method) -> untyped
|
136
136
|
| (Symbol method) -> untyped
|
@@ -341,7 +341,7 @@ module Enumerable[unchecked out Elem]: _Each[Elem]
|
|
341
341
|
def map: [U] () { (Elem arg0) -> U } -> ::Array[U]
|
342
342
|
| () -> ::Enumerator[Elem, ::Array[untyped]]
|
343
343
|
|
344
|
-
def member?: (
|
344
|
+
def member?: (Elem arg0) -> bool
|
345
345
|
|
346
346
|
alias reduce inject
|
347
347
|
|
data/docs/syntax.md
CHANGED
@@ -5,14 +5,14 @@
|
|
5
5
|
```markdown
|
6
6
|
_type_ ::= _class-name_ _type-arguments_ (Class instance type)
|
7
7
|
| _interface-name_ _type-arguments_ (Interface type)
|
8
|
+
| _alias-name_ _type-arguments_ (Alias type)
|
8
9
|
| `singleton(` _class-name_ `)` (Class singleton type)
|
9
|
-
| _alias-name_ (Alias type)
|
10
10
|
| _literal_ (Literal type)
|
11
11
|
| _type_ `|` _type_ (Union type)
|
12
12
|
| _type_ `&` _type_ (Intersection type)
|
13
13
|
| _type_ `?` (Optional type)
|
14
|
-
| `{` _record-name_ `:` _type_ `,` etc. `}`
|
15
|
-
| `[]` | `[` _type_ `,` etc. `]`
|
14
|
+
| `{` _record-name_ `:` _type_ `,` etc. `}` (Record type)
|
15
|
+
| `[]` | `[` _type_ `,` etc. `]` (Tuples)
|
16
16
|
| _type-variable_ (Type variables)
|
17
17
|
| `^(` _parameters_ `) ->` _type_ (Proc type)
|
18
18
|
| `self`
|
@@ -35,8 +35,8 @@ _namespace_ ::= (Empty namespace)
|
|
35
35
|
| `::` (Root)
|
36
36
|
| _namespace_ /[A-Z]\w*/ `::` (Namespace)
|
37
37
|
|
38
|
-
_type-arguments_ ::= (No
|
39
|
-
| `[` _type_ `,` etc. `]`
|
38
|
+
_type-arguments_ ::= (No type arguments)
|
39
|
+
| `[` _type_ `,` etc. `]` (Type arguments)
|
40
40
|
|
41
41
|
_literal_ ::= _string-literal_
|
42
42
|
| _symbol-literal_
|
@@ -64,25 +64,25 @@ _ToS # _ToS interface
|
|
64
64
|
::MyApp::_Each[String] # Interface name with namespace and type application
|
65
65
|
```
|
66
66
|
|
67
|
-
### Class singleton type
|
68
|
-
|
69
|
-
Class singleton type denotes _the type of a singleton object of a class_.
|
70
|
-
|
71
|
-
```
|
72
|
-
singleton(String)
|
73
|
-
singleton(::Hash) # Class singleton type cannot be parametrized.
|
74
|
-
```
|
75
|
-
|
76
67
|
### Alias type
|
77
68
|
|
78
69
|
Alias type denotes an alias declared with _alias declaration_.
|
79
70
|
|
80
71
|
The name of type aliases starts with lowercase `[a-z]`.
|
81
72
|
|
82
|
-
|
83
73
|
```
|
84
74
|
name
|
85
75
|
::JSON::t # Alias name with namespace
|
76
|
+
list[Integer] # Type alias can be generic
|
77
|
+
```
|
78
|
+
|
79
|
+
### Class singleton type
|
80
|
+
|
81
|
+
Class singleton type denotes _the type of a singleton object of a class_.
|
82
|
+
|
83
|
+
```
|
84
|
+
singleton(String)
|
85
|
+
singleton(::Hash) # Class singleton type cannot be parametrized.
|
86
86
|
```
|
87
87
|
|
88
88
|
### Literal type
|
@@ -155,7 +155,7 @@ Elem
|
|
155
155
|
```
|
156
156
|
|
157
157
|
Type variables cannot be distinguished from _class instance types_.
|
158
|
-
They are scoped in _class/module/interface declaration_ or _generic method types_.
|
158
|
+
They are scoped in _class/module/interface/alias declaration_ or _generic method types_.
|
159
159
|
|
160
160
|
```
|
161
161
|
class Ref[T] # Object is scoped in the class declaration.
|
@@ -414,7 +414,6 @@ These work only as _statements_, not per-method specifier.
|
|
414
414
|
_decl_ ::= _class-decl_ # Class declaration
|
415
415
|
| _module-decl_ # Module declaration
|
416
416
|
| _interface-decl_ # Interface declaration
|
417
|
-
| _extension-decl_ # Extension declaration
|
418
417
|
| _type-alias-decl_ # Type alias declaration
|
419
418
|
| _const-decl_ # Constant declaration
|
420
419
|
| _global-decl_ # Global declaration
|
@@ -434,9 +433,7 @@ _interface-members_ ::= _method-member_ # Method
|
|
434
433
|
| _include-member_ # Mixin (include)
|
435
434
|
| _alias-member_ # Alias
|
436
435
|
|
437
|
-
|
438
|
-
|
439
|
-
_type-alias-decl_ ::= `type` _alias-name_ `=` _type_
|
436
|
+
_type-alias-decl_ ::= `type` _alias-name_ _module-type-parameters_ `=` _type_
|
440
437
|
|
441
438
|
_const-decl_ ::= _const-name_ `:` _type_
|
442
439
|
|
@@ -536,6 +533,12 @@ type subject = Attendee | Speaker
|
|
536
533
|
type JSON::t = Integer | TrueClass | FalseClass | String | Hash[Symbol, t] | Array[t]
|
537
534
|
```
|
538
535
|
|
536
|
+
Type alias can be generic like class, module, and interface.
|
537
|
+
|
538
|
+
```
|
539
|
+
type list[out T] = [T, list[T]] | nil
|
540
|
+
```
|
541
|
+
|
539
542
|
### Constant type declaration
|
540
543
|
|
541
544
|
You can declare a constant.
|
data/ext/rbs_extension/parser.c
CHANGED
@@ -815,6 +815,8 @@ static VALUE parse_simple(parserstate *state) {
|
|
815
815
|
}
|
816
816
|
case tULIDENT:
|
817
817
|
// fallthrough
|
818
|
+
case tLIDENT:
|
819
|
+
// fallthrough
|
818
820
|
case pCOLON2: {
|
819
821
|
range name_range;
|
820
822
|
range args_range;
|
@@ -857,19 +859,11 @@ static VALUE parse_simple(parserstate *state) {
|
|
857
859
|
} else if (kind == INTERFACE_NAME) {
|
858
860
|
return rbs_interface(typename, types, location);
|
859
861
|
} else if (kind == ALIAS_NAME) {
|
860
|
-
return rbs_alias(typename, location);
|
862
|
+
return rbs_alias(typename, types, location);
|
861
863
|
} else {
|
862
864
|
return Qnil;
|
863
865
|
}
|
864
866
|
}
|
865
|
-
case tLIDENT: {
|
866
|
-
VALUE location = rbs_location_current_token(state);
|
867
|
-
rbs_loc *loc = rbs_check_location(location);
|
868
|
-
rbs_loc_add_required_child(loc, rb_intern("name"), state->current_token.range);
|
869
|
-
rbs_loc_add_optional_child(loc, rb_intern("args"), NULL_RANGE);
|
870
|
-
VALUE typename = parse_type_name(state, ALIAS_NAME, NULL);
|
871
|
-
return rbs_alias(typename, location);
|
872
|
-
}
|
873
867
|
case kSINGLETON: {
|
874
868
|
range name_range;
|
875
869
|
range type_range;
|
@@ -1093,12 +1087,98 @@ VALUE parse_const_decl(parserstate *state) {
|
|
1093
1087
|
return rbs_ast_decl_constant(typename, type, location, comment);
|
1094
1088
|
}
|
1095
1089
|
|
1090
|
+
/*
|
1091
|
+
module_type_params ::= {} `[` module_type_param `,` ... <`]`>
|
1092
|
+
| {<>}
|
1093
|
+
|
1094
|
+
module_type_param ::= kUNCHECKED? (kIN|kOUT|) tUIDENT
|
1095
|
+
*/
|
1096
|
+
VALUE parse_module_type_params(parserstate *state, range *rg) {
|
1097
|
+
VALUE params = rbs_ast_decl_module_type_params();
|
1098
|
+
|
1099
|
+
if (state->next_token.type == pLBRACKET) {
|
1100
|
+
parser_advance(state);
|
1101
|
+
|
1102
|
+
rg->start = state->current_token.range.start;
|
1103
|
+
|
1104
|
+
while (true) {
|
1105
|
+
VALUE name;
|
1106
|
+
VALUE unchecked = Qfalse;
|
1107
|
+
VALUE variance = ID2SYM(rb_intern("invariant"));
|
1108
|
+
|
1109
|
+
range param_range = NULL_RANGE;
|
1110
|
+
range name_range;
|
1111
|
+
range variance_range = NULL_RANGE;
|
1112
|
+
range unchecked_range = NULL_RANGE;
|
1113
|
+
|
1114
|
+
param_range.start = state->next_token.range.start;
|
1115
|
+
|
1116
|
+
if (state->next_token.type == kUNCHECKED) {
|
1117
|
+
unchecked = Qtrue;
|
1118
|
+
parser_advance(state);
|
1119
|
+
unchecked_range = state->current_token.range;
|
1120
|
+
}
|
1121
|
+
|
1122
|
+
if (state->next_token.type == kIN || state->next_token.type == kOUT) {
|
1123
|
+
switch (state->next_token.type) {
|
1124
|
+
case kIN:
|
1125
|
+
variance = ID2SYM(rb_intern("contravariant"));
|
1126
|
+
break;
|
1127
|
+
case kOUT:
|
1128
|
+
variance = ID2SYM(rb_intern("covariant"));
|
1129
|
+
break;
|
1130
|
+
default:
|
1131
|
+
rbs_abort();
|
1132
|
+
}
|
1133
|
+
|
1134
|
+
parser_advance(state);
|
1135
|
+
variance_range = state->current_token.range;
|
1136
|
+
}
|
1137
|
+
|
1138
|
+
parser_advance_assert(state, tUIDENT);
|
1139
|
+
name_range = state->current_token.range;
|
1140
|
+
param_range.end = state->current_token.range.end;
|
1141
|
+
|
1142
|
+
ID id = INTERN_TOKEN(state, state->current_token);
|
1143
|
+
name = ID2SYM(id);
|
1144
|
+
|
1145
|
+
parser_insert_typevar(state, id);
|
1146
|
+
|
1147
|
+
VALUE location = rbs_new_location(state->buffer, param_range);
|
1148
|
+
rbs_loc *loc = rbs_check_location(location);
|
1149
|
+
rbs_loc_add_required_child(loc, rb_intern("name"), name_range);
|
1150
|
+
rbs_loc_add_optional_child(loc, rb_intern("variance"), variance_range);
|
1151
|
+
rbs_loc_add_optional_child(loc, rb_intern("unchecked"), unchecked_range);
|
1152
|
+
|
1153
|
+
VALUE param = rbs_ast_decl_module_type_params_param(name, variance, unchecked, location);
|
1154
|
+
rb_funcall(params, rb_intern("add"), 1, param);
|
1155
|
+
|
1156
|
+
if (state->next_token.type == pCOMMA) {
|
1157
|
+
parser_advance(state);
|
1158
|
+
}
|
1159
|
+
|
1160
|
+
if (state->next_token.type == pRBRACKET) {
|
1161
|
+
break;
|
1162
|
+
}
|
1163
|
+
}
|
1164
|
+
|
1165
|
+
parser_advance_assert(state, pRBRACKET);
|
1166
|
+
rg->end = state->current_token.range.end;
|
1167
|
+
} else {
|
1168
|
+
*rg = NULL_RANGE;
|
1169
|
+
}
|
1170
|
+
|
1171
|
+
return params;
|
1172
|
+
}
|
1173
|
+
|
1096
1174
|
/*
|
1097
1175
|
type_decl ::= {kTYPE} alias_name `=` <type>
|
1098
1176
|
*/
|
1099
1177
|
VALUE parse_type_decl(parserstate *state, position comment_pos, VALUE annotations) {
|
1100
1178
|
range decl_range;
|
1101
|
-
range keyword_range, name_range, eq_range;
|
1179
|
+
range keyword_range, name_range, params_range, eq_range;
|
1180
|
+
|
1181
|
+
parser_push_typevar_table(state, true);
|
1102
1182
|
|
1103
1183
|
decl_range.start = state->current_token.range.start;
|
1104
1184
|
comment_pos = nonnull_pos_or(comment_pos, decl_range.start);
|
@@ -1108,6 +1188,8 @@ VALUE parse_type_decl(parserstate *state, position comment_pos, VALUE annotation
|
|
1108
1188
|
parser_advance(state);
|
1109
1189
|
VALUE typename = parse_type_name(state, ALIAS_NAME, &name_range);
|
1110
1190
|
|
1191
|
+
VALUE type_params = parse_module_type_params(state, ¶ms_range);
|
1192
|
+
|
1111
1193
|
parser_advance_assert(state, pEQ);
|
1112
1194
|
eq_range = state->current_token.range;
|
1113
1195
|
|
@@ -1118,10 +1200,14 @@ VALUE parse_type_decl(parserstate *state, position comment_pos, VALUE annotation
|
|
1118
1200
|
rbs_loc *loc = rbs_check_location(location);
|
1119
1201
|
rbs_loc_add_required_child(loc, rb_intern("keyword"), keyword_range);
|
1120
1202
|
rbs_loc_add_required_child(loc, rb_intern("name"), name_range);
|
1203
|
+
rbs_loc_add_optional_child(loc, rb_intern("type_params"), params_range);
|
1121
1204
|
rbs_loc_add_required_child(loc, rb_intern("eq"), eq_range);
|
1122
1205
|
|
1206
|
+
parser_pop_typevar_table(state);
|
1207
|
+
|
1123
1208
|
return rbs_ast_decl_alias(
|
1124
1209
|
typename,
|
1210
|
+
type_params,
|
1125
1211
|
type,
|
1126
1212
|
annotations,
|
1127
1213
|
location,
|
@@ -1184,90 +1270,6 @@ VALUE parse_annotation(parserstate *state) {
|
|
1184
1270
|
return rbs_ast_annotation(string, location);
|
1185
1271
|
}
|
1186
1272
|
|
1187
|
-
/*
|
1188
|
-
module_type_params ::= {} `[` module_type_param `,` ... <`]`>
|
1189
|
-
| {<>}
|
1190
|
-
|
1191
|
-
module_type_param ::= kUNCHECKED? (kIN|kOUT|) tUIDENT
|
1192
|
-
*/
|
1193
|
-
VALUE parse_module_type_params(parserstate *state, range *rg) {
|
1194
|
-
VALUE params = rbs_ast_decl_module_type_params();
|
1195
|
-
|
1196
|
-
if (state->next_token.type == pLBRACKET) {
|
1197
|
-
parser_advance(state);
|
1198
|
-
|
1199
|
-
rg->start = state->current_token.range.start;
|
1200
|
-
|
1201
|
-
while (true) {
|
1202
|
-
VALUE name;
|
1203
|
-
VALUE unchecked = Qfalse;
|
1204
|
-
VALUE variance = ID2SYM(rb_intern("invariant"));
|
1205
|
-
|
1206
|
-
range param_range = NULL_RANGE;
|
1207
|
-
range name_range;
|
1208
|
-
range variance_range = NULL_RANGE;
|
1209
|
-
range unchecked_range = NULL_RANGE;
|
1210
|
-
|
1211
|
-
param_range.start = state->next_token.range.start;
|
1212
|
-
|
1213
|
-
if (state->next_token.type == kUNCHECKED) {
|
1214
|
-
unchecked = Qtrue;
|
1215
|
-
parser_advance(state);
|
1216
|
-
unchecked_range = state->current_token.range;
|
1217
|
-
}
|
1218
|
-
|
1219
|
-
if (state->next_token.type == kIN || state->next_token.type == kOUT) {
|
1220
|
-
switch (state->next_token.type) {
|
1221
|
-
case kIN:
|
1222
|
-
variance = ID2SYM(rb_intern("contravariant"));
|
1223
|
-
break;
|
1224
|
-
case kOUT:
|
1225
|
-
variance = ID2SYM(rb_intern("covariant"));
|
1226
|
-
break;
|
1227
|
-
default:
|
1228
|
-
rbs_abort();
|
1229
|
-
}
|
1230
|
-
|
1231
|
-
parser_advance(state);
|
1232
|
-
variance_range = state->current_token.range;
|
1233
|
-
}
|
1234
|
-
|
1235
|
-
parser_advance_assert(state, tUIDENT);
|
1236
|
-
name_range = state->current_token.range;
|
1237
|
-
param_range.end = state->current_token.range.end;
|
1238
|
-
|
1239
|
-
ID id = INTERN_TOKEN(state, state->current_token);
|
1240
|
-
name = ID2SYM(id);
|
1241
|
-
|
1242
|
-
parser_insert_typevar(state, id);
|
1243
|
-
|
1244
|
-
VALUE location = rbs_new_location(state->buffer, param_range);
|
1245
|
-
rbs_loc *loc = rbs_check_location(location);
|
1246
|
-
rbs_loc_add_required_child(loc, rb_intern("name"), name_range);
|
1247
|
-
rbs_loc_add_optional_child(loc, rb_intern("variance"), variance_range);
|
1248
|
-
rbs_loc_add_optional_child(loc, rb_intern("unchecked"), unchecked_range);
|
1249
|
-
|
1250
|
-
VALUE param = rbs_ast_decl_module_type_params_param(name, variance, unchecked, location);
|
1251
|
-
rb_funcall(params, rb_intern("add"), 1, param);
|
1252
|
-
|
1253
|
-
if (state->next_token.type == pCOMMA) {
|
1254
|
-
parser_advance(state);
|
1255
|
-
}
|
1256
|
-
|
1257
|
-
if (state->next_token.type == pRBRACKET) {
|
1258
|
-
break;
|
1259
|
-
}
|
1260
|
-
}
|
1261
|
-
|
1262
|
-
parser_advance_assert(state, pRBRACKET);
|
1263
|
-
rg->end = state->current_token.range.end;
|
1264
|
-
} else {
|
1265
|
-
*rg = NULL_RANGE;
|
1266
|
-
}
|
1267
|
-
|
1268
|
-
return params;
|
1269
|
-
}
|
1270
|
-
|
1271
1273
|
/*
|
1272
1274
|
annotations ::= {} annotation ... <annotation>
|
1273
1275
|
| {<>}
|
@@ -70,15 +70,16 @@ VALUE rbs_class_singleton(VALUE typename, VALUE location) {
|
|
70
70
|
);
|
71
71
|
}
|
72
72
|
|
73
|
-
VALUE rbs_alias(VALUE typename, VALUE location) {
|
74
|
-
VALUE
|
75
|
-
rb_hash_aset(
|
76
|
-
rb_hash_aset(
|
73
|
+
VALUE rbs_alias(VALUE typename, VALUE args, VALUE location) {
|
74
|
+
VALUE kwargs = rb_hash_new();
|
75
|
+
rb_hash_aset(kwargs, ID2SYM(rb_intern("name")), typename);
|
76
|
+
rb_hash_aset(kwargs, ID2SYM(rb_intern("args")), args);
|
77
|
+
rb_hash_aset(kwargs, ID2SYM(rb_intern("location")), location);
|
77
78
|
|
78
79
|
return CLASS_NEW_INSTANCE(
|
79
80
|
RBS_Types_Alias,
|
80
81
|
1,
|
81
|
-
&
|
82
|
+
&kwargs
|
82
83
|
);
|
83
84
|
}
|
84
85
|
|
@@ -339,9 +340,10 @@ VALUE rbs_ast_decl_global(VALUE name, VALUE type, VALUE location, VALUE comment)
|
|
339
340
|
);
|
340
341
|
}
|
341
342
|
|
342
|
-
VALUE rbs_ast_decl_alias(VALUE name, VALUE type, VALUE annotations, VALUE location, VALUE comment) {
|
343
|
+
VALUE rbs_ast_decl_alias(VALUE name, VALUE type_params, VALUE type, VALUE annotations, VALUE location, VALUE comment) {
|
343
344
|
VALUE args = rb_hash_new();
|
344
345
|
rb_hash_aset(args, ID2SYM(rb_intern("name")), name);
|
346
|
+
rb_hash_aset(args, ID2SYM(rb_intern("type_params")), type_params);
|
345
347
|
rb_hash_aset(args, ID2SYM(rb_intern("type")), type);
|
346
348
|
rb_hash_aset(args, ID2SYM(rb_intern("annotations")), annotations);
|
347
349
|
rb_hash_aset(args, ID2SYM(rb_intern("location")), location);
|
@@ -3,10 +3,10 @@
|
|
3
3
|
|
4
4
|
#include "ruby.h"
|
5
5
|
|
6
|
-
VALUE rbs_alias(VALUE typename, VALUE location);
|
6
|
+
VALUE rbs_alias(VALUE typename, VALUE args, VALUE location);
|
7
7
|
VALUE rbs_ast_annotation(VALUE string, VALUE location);
|
8
8
|
VALUE rbs_ast_comment(VALUE string, VALUE location);
|
9
|
-
VALUE rbs_ast_decl_alias(VALUE name, VALUE type, VALUE annotations, VALUE location, VALUE comment);
|
9
|
+
VALUE rbs_ast_decl_alias(VALUE name, VALUE type_params, VALUE type, VALUE annotations, VALUE location, VALUE comment);
|
10
10
|
VALUE rbs_ast_decl_class_super(VALUE name, VALUE args, VALUE location);
|
11
11
|
VALUE rbs_ast_decl_class(VALUE name, VALUE type_params, VALUE super_class, VALUE members, VALUE annotations, VALUE location, VALUE comment);
|
12
12
|
VALUE rbs_ast_decl_constant(VALUE name, VALUE type, VALUE location, VALUE comment);
|
data/lib/rbs/ast/declarations.rb
CHANGED
@@ -362,13 +362,15 @@ module RBS
|
|
362
362
|
|
363
363
|
class Alias < Base
|
364
364
|
attr_reader :name
|
365
|
+
attr_reader :type_params
|
365
366
|
attr_reader :type
|
366
367
|
attr_reader :annotations
|
367
368
|
attr_reader :location
|
368
369
|
attr_reader :comment
|
369
370
|
|
370
|
-
def initialize(name:, type:, annotations:, location:, comment:)
|
371
|
+
def initialize(name:, type_params:, type:, annotations:, location:, comment:)
|
371
372
|
@name = name
|
373
|
+
@type_params = type_params
|
372
374
|
@type = type
|
373
375
|
@annotations = annotations
|
374
376
|
@location = location
|
@@ -378,19 +380,21 @@ module RBS
|
|
378
380
|
def ==(other)
|
379
381
|
other.is_a?(Alias) &&
|
380
382
|
other.name == name &&
|
383
|
+
other.type_params == type_params &&
|
381
384
|
other.type == type
|
382
385
|
end
|
383
386
|
|
384
387
|
alias eql? ==
|
385
388
|
|
386
389
|
def hash
|
387
|
-
self.class.hash ^ name.hash ^ type.hash
|
390
|
+
self.class.hash ^ name.hash ^ type_params.hash ^ type.hash
|
388
391
|
end
|
389
392
|
|
390
393
|
def to_json(state = _ = nil)
|
391
394
|
{
|
392
395
|
declaration: :alias,
|
393
396
|
name: name,
|
397
|
+
type_params: type_params,
|
394
398
|
type: type,
|
395
399
|
annotations: annotations,
|
396
400
|
location: location,
|
data/lib/rbs/cli.rb
CHANGED
@@ -460,7 +460,7 @@ EOU
|
|
460
460
|
|
461
461
|
env.alias_decls.each do |name, decl|
|
462
462
|
stdout.puts "Validating alias: `#{name}`..."
|
463
|
-
builder.
|
463
|
+
builder.expand_alias1(name).tap do |type|
|
464
464
|
validator.validate_type type, context: [Namespace.root]
|
465
465
|
end
|
466
466
|
validator.validate_type_alias(entry: decl)
|
@@ -781,9 +781,36 @@ module RBS
|
|
781
781
|
end
|
782
782
|
|
783
783
|
def expand_alias(type_name)
|
784
|
-
|
784
|
+
expand_alias2(type_name, [])
|
785
|
+
end
|
786
|
+
|
787
|
+
def expand_alias1(type_name)
|
788
|
+
entry = env.alias_decls[type_name] or raise "Unknown alias name: #{type_name}"
|
789
|
+
as = entry.decl.type_params.each.map { Types::Bases::Any.new(location: nil) }
|
790
|
+
expand_alias2(type_name, as)
|
791
|
+
end
|
792
|
+
|
793
|
+
def expand_alias2(type_name, args)
|
794
|
+
entry = env.alias_decls[type_name] or raise "Unknown alias name: #{type_name}"
|
795
|
+
|
785
796
|
ensure_namespace!(type_name.namespace, location: entry.decl.location)
|
786
|
-
entry.decl.
|
797
|
+
params = entry.decl.type_params.each.map(&:name)
|
798
|
+
|
799
|
+
unless params.size == args.size
|
800
|
+
as = "[#{args.join(", ")}]" unless args.empty?
|
801
|
+
ps = "[#{params.join(", ")}]" unless params.empty?
|
802
|
+
|
803
|
+
raise "Invalid type application: type = #{type_name}#{as}, decl = #{type_name}#{ps}"
|
804
|
+
end
|
805
|
+
|
806
|
+
type = entry.decl.type
|
807
|
+
|
808
|
+
unless params.empty?
|
809
|
+
subst = Substitution.build(params, args)
|
810
|
+
type = type.sub(subst)
|
811
|
+
end
|
812
|
+
|
813
|
+
type
|
787
814
|
end
|
788
815
|
|
789
816
|
def update(env:, except:, ancestor_builder:)
|
data/lib/rbs/environment.rb
CHANGED
@@ -319,6 +319,7 @@ module RBS
|
|
319
319
|
when AST::Declarations::Alias
|
320
320
|
AST::Declarations::Alias.new(
|
321
321
|
name: decl.name.with_prefix(prefix),
|
322
|
+
type_params: decl.type_params,
|
322
323
|
type: absolute_type(resolver, decl.type, context: context),
|
323
324
|
location: decl.location,
|
324
325
|
annotations: decl.annotations,
|
@@ -57,7 +57,7 @@ module RBS
|
|
57
57
|
end
|
58
58
|
end
|
59
59
|
when name.alias?
|
60
|
-
each_type_node builder.
|
60
|
+
each_type_node builder.expand_alias1(name), &block
|
61
61
|
else
|
62
62
|
raise "Unexpected TypeNameNode with type_name=#{name}"
|
63
63
|
end
|
@@ -126,6 +126,9 @@ module RBS
|
|
126
126
|
end
|
127
127
|
when RBS::Types::Alias
|
128
128
|
yield TypeNameNode.new(type_name: type.name)
|
129
|
+
type.args.each do |ty|
|
130
|
+
each_type_node(ty, &block)
|
131
|
+
end
|
129
132
|
when RBS::Types::Union, RBS::Types::Intersection, RBS::Types::Tuple
|
130
133
|
type.types.each do |ty|
|
131
134
|
each_type_node ty, &block
|
data/lib/rbs/errors.rb
CHANGED
@@ -431,4 +431,16 @@ module RBS
|
|
431
431
|
@alias_names.map(&:name).join(', ')
|
432
432
|
end
|
433
433
|
end
|
434
|
+
|
435
|
+
class NonregularTypeAliasError < LoadingError
|
436
|
+
attr_reader :diagnostic
|
437
|
+
attr_reader :location
|
438
|
+
|
439
|
+
def initialize(diagnostic:, location:)
|
440
|
+
@diagnostic = diagnostic
|
441
|
+
@location = location
|
442
|
+
|
443
|
+
super "#{Location.to_string location}: Nonregular generic type alias is prohibited: #{diagnostic.type_name}, #{diagnostic.nonregular_type}"
|
444
|
+
end
|
445
|
+
end
|
434
446
|
end
|