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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d93b02ff74da3638b4aee35967e4ccc34460c1103ceb51ecfd5406d39e732f21
4
- data.tar.gz: b11beb145022527d5d16e2c6545fcc4aa847790e3502b6054f77785685b7fe6c
3
+ metadata.gz: 9b12d92ea4eeeb5dbd6de6c5d58351b0306bdcd017d0f1e51a36599766bfded3
4
+ data.tar.gz: d60cfb836027441a5bb3f85fbebb0e2ab9bc03c49a21f00c3f10d4ab8dd1de65
5
5
  SHA512:
6
- metadata.gz: 689cdd0da1b18d8d0d6c9cde454cd3a2de0d44f66e19d52400734bb13001770b44bf0f66a87db403d31fb91ddccdefee87a056686055165d1935ade8fd376ff6
7
- data.tar.gz: 488b07051aea9edb7c3c32e9fafc8b1bfcd16f38b8dc492aa4656a0a15a1577615522a15f22c3e900acb458f0bce4620998c2dfc79b17638dd64f025bd0ff29c
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
- | (untyped obj) -> ::Integer
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: (untyped obj) -> Elem?
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?: (untyped object) -> bool
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
@@ -6,6 +6,10 @@ interface _ToInt
6
6
  def to_int: -> Integer
7
7
  end
8
8
 
9
+ interface _ToR
10
+ def to_r: () -> Rational
11
+ end
12
+
9
13
  interface _ToS
10
14
  def to_s: -> String
11
15
  end
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
- | (?untyped) -> Integer
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?`: (untyped arg0) -> bool
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?: (untyped arg0) -> bool
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. `}` (Record type)
15
- | `[]` | `[` _type_ `,` etc. `]` (Tuples)
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 application)
39
- | `[` _type_ `,` etc. `]` (Type application)
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
- _extension-decl_ ::= `extension` _class-name_ _type-parameters_ `(` _extension-name_ `)` _members_ `end`
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.
@@ -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, &params_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 args = rb_hash_new();
75
- rb_hash_aset(args, ID2SYM(rb_intern("name")), typename);
76
- rb_hash_aset(args, ID2SYM(rb_intern("location")), location);
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
- &args
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);
@@ -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.expand_alias(name).tap do |type|
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
- entry = env.alias_decls[type_name] or raise "Unknown name for expand_alias: #{type_name}"
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.type
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:)
@@ -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.expand_alias(name), &block
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