rbs 1.7.1 → 1.8.0

Sign up to get free protection for your applications and to get access to all the features.
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