rbs 1.7.0 → 2.0.0.pre1

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.
Files changed (79) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +95 -3
  3. data/core/array.rbs +3 -3
  4. data/core/builtin.rbs +4 -0
  5. data/core/enumerable.rbs +3 -3
  6. data/core/thread.rbs +1 -1
  7. data/docs/collection.md +23 -1
  8. data/docs/syntax.md +117 -61
  9. data/ext/rbs_extension/constants.c +2 -6
  10. data/ext/rbs_extension/constants.h +1 -2
  11. data/ext/rbs_extension/parser.c +221 -185
  12. data/ext/rbs_extension/parserstate.c +6 -2
  13. data/ext/rbs_extension/parserstate.h +10 -0
  14. data/ext/rbs_extension/ruby_objs.c +17 -17
  15. data/ext/rbs_extension/ruby_objs.h +3 -4
  16. data/lib/rbs/ast/declarations.rb +6 -99
  17. data/lib/rbs/ast/type_param.rb +134 -0
  18. data/lib/rbs/cli.rb +33 -5
  19. data/lib/rbs/collection/config/lockfile_generator.rb +26 -18
  20. data/lib/rbs/collection/sources/git.rb +18 -7
  21. data/lib/rbs/collection/sources/rubygems.rb +7 -0
  22. data/lib/rbs/collection/sources/stdlib.rb +6 -0
  23. data/lib/rbs/definition.rb +9 -0
  24. data/lib/rbs/definition_builder.rb +78 -16
  25. data/lib/rbs/environment.rb +32 -8
  26. data/lib/rbs/environment_loader.rb +0 -2
  27. data/lib/rbs/environment_walker.rb +4 -1
  28. data/lib/rbs/errors.rb +31 -6
  29. data/lib/rbs/location_aux.rb +2 -0
  30. data/lib/rbs/method_type.rb +29 -6
  31. data/lib/rbs/prototype/rb.rb +3 -3
  32. data/lib/rbs/prototype/rbi.rb +8 -6
  33. data/lib/rbs/prototype/runtime.rb +4 -4
  34. data/lib/rbs/type_alias_regularity.rb +115 -0
  35. data/lib/rbs/types.rb +100 -23
  36. data/lib/rbs/validator.rb +99 -15
  37. data/lib/rbs/variance_calculator.rb +60 -31
  38. data/lib/rbs/version.rb +1 -1
  39. data/lib/rbs/writer.rb +2 -14
  40. data/lib/rbs.rb +2 -0
  41. data/schema/decls.json +19 -46
  42. data/schema/methodType.json +1 -1
  43. data/schema/typeParam.json +36 -0
  44. data/schema/types.json +8 -2
  45. data/sig/collection/collections.rbs +13 -2
  46. data/sig/collection/config.rbs +2 -2
  47. data/sig/declarations.rbs +15 -62
  48. data/sig/definition.rbs +11 -1
  49. data/sig/definition_builder.rbs +37 -1
  50. data/sig/environment.rbs +7 -1
  51. data/sig/environment_walker.rbs +26 -0
  52. data/sig/errors.rbs +28 -3
  53. data/sig/location.rbs +3 -1
  54. data/sig/locator.rbs +1 -1
  55. data/sig/method_types.rbs +25 -4
  56. data/sig/type_alias_regularity.rbs +92 -0
  57. data/sig/type_param.rbs +74 -0
  58. data/sig/types.rbs +37 -8
  59. data/sig/validator.rbs +38 -2
  60. data/sig/variance_calculator.rbs +50 -0
  61. data/sig/writer.rbs +1 -1
  62. data/stdlib/bigdecimal-math/0/manifest.yaml +2 -0
  63. data/stdlib/csv/0/manifest.yaml +2 -0
  64. data/stdlib/date/0/date.rbs +2 -2
  65. data/stdlib/logger/0/manifest.yaml +2 -0
  66. data/stdlib/net-http/0/manifest.yaml +2 -0
  67. data/stdlib/openssl/0/manifest.yaml +2 -0
  68. data/stdlib/prime/0/manifest.yaml +2 -0
  69. data/stdlib/resolv/0/manifest.yaml +3 -0
  70. data/stdlib/set/0/set.rbs +3 -3
  71. data/stdlib/uri/0/common.rbs +10 -5
  72. data/stdlib/uri/0/ftp.rbs +10 -0
  73. data/stdlib/uri/0/mailto.rbs +5 -0
  74. data/stdlib/uri/0/ws.rbs +10 -0
  75. data/stdlib/uri/0/wss.rbs +7 -0
  76. data/stdlib/yaml/0/manifest.yaml +3 -0
  77. data/steep/Gemfile.lock +10 -10
  78. metadata +21 -5
  79. data/lib/ruby/signature.rb +0 -7
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 0e6fc59a79d872f87e6e58e32c2c92d70ec59c0fad26d5a094a7a21d4b108e6c
4
- data.tar.gz: 950a60b79c02ebdd4d6dd39ff2fc0c7fef9a69843111bc7ed6640c732afd0d98
3
+ metadata.gz: df2f2f119ca85f630c640b201ebf9ce72322db96223de2fb1d4ba77df68aee59
4
+ data.tar.gz: 82943e12963a10f2a4dbd30096fe40fb90ee4b23d6239bd515526a39d2af3b97
5
5
  SHA512:
6
- metadata.gz: a59a9dbf9bbd5c85e3462fb5d0e1edf9a879b87db78cf409a5af921a40ce375f72a7475fe0c7eda0350ed604e876197262e0195a4812177410ff1b31edf41252
7
- data.tar.gz: b739f7415fefb9ed0cb5db63de98ab648dcd320ac98abd9211bb85448f3fbb14855fcb61715a6c6f4cf520308b2fa0a73c93217bd4e0dd8818d759446e3a6264
6
+ metadata.gz: 9dbd99091da5e5d116a5bb428383c3e63e8b8ee4207ea859e177577b33a1d1dc3d312bb31f03fcda61d90993b4a9ab1ccab69855e7ecb8e986f9696a638c618d
7
+ data.tar.gz: dc05caaa25da531bbe353eb0294fbe016a90039eef12a040f2c5b07f409683c9fbc6c3406beba8c8d76f25f5b0ed7bbc3501967cc84fcc000a2e49fda85e84a3
data/CHANGELOG.md CHANGED
@@ -2,12 +2,104 @@
2
2
 
3
3
  ## master
4
4
 
5
+ ## 2.0.0 (pre1)
6
+
7
+ ### Bounded Generics
8
+
9
+ RBS 2.0 ships with _bounded generics_, which improves the expressiveness of the language by adding new syntax to define the constraint on type parameters.
10
+
11
+ ```rbs
12
+ class PrettyPrint[T < _Output]
13
+ interface _Output
14
+ def <<: (String) -> void
15
+ end
16
+
17
+ attr_reader output: T
18
+
19
+ def initialize: (T output) -> void
20
+ end
21
+ ```
22
+
23
+ This is the motivating example I found in the [prettyprint library](https://github.com/ruby/prettyprint).
24
+ The `#initialize` receives a object of type `T` and it must have `#<<` method.
25
+ This is defined with `< _Output` syntax in the example.
26
+ It means _`T` has to be compatible with `_Output` interface._
27
+ `PrettyPrint[String]` is okay, but `PrettyPrint[Integer]` is a type error.
28
+
29
+ See [the PR for details](https://github.com/ruby/rbs/pull/844).
30
+
31
+ `manifest.yaml` allows declaring the dependencies from your gems to standard libraries explicitly.
32
+
33
+ This version contains a bug fix, which potentially breaks the compatibility with older versions.
34
+ The super class names in class definitions are now resolved in _outer_ context.
35
+ It was an incompatibility with Ruby and [this PR](https://github.com/ruby/rbs/pull/856) fixed the problem.
36
+
37
+ ### Signature updates
38
+
39
+ * uri ([\#846](https://github.com/ruby/rbs/pull/846), [\#852](https://github.com/ruby/rbs/pull/852), [\#851](https://github.com/ruby/rbs/pull/851), [\#850](https://github.com/ruby/rbs/pull/850))
40
+
41
+ ### Language updates
42
+
43
+ * Bounded generics ([\#844](https://github.com/ruby/rbs/pull/844))
44
+ * Resolve super type names in outer context ([\#856](https://github.com/ruby/rbs/pull/856))
45
+
46
+ ### Library changes
47
+
48
+ * Add `manifest.yaml` for collection to specify stdlib dependencies ([\#808](https://github.com/ruby/rbs/pull/808))
49
+ * Remove experimental warning of `rbs collection` ([\#855](https://github.com/ruby/rbs/pull/855))
50
+ * Add the utility `#map_type` methods ([\#841](https://github.com/ruby/rbs/pull/841))
51
+
52
+ ## 1.8.1 (2021-12-13)
53
+
54
+ ### Library changes
55
+
56
+ * Validate `extend` arguments ([\#840](https://github.com/ruby/rbs/pull/840))
57
+ * Allow a relative path as git remote in collection ([\#839](https://github.com/ruby/rbs/pull/839))
58
+
59
+ ## 1.8.0 (2021-12-02)
60
+
61
+ RBS 1.8.0 ships with a language feature enhancement, _generic type alias_.
62
+ You can define a type alias with type parameters now.
63
+
64
+ ```rbs
65
+ type list[T] = [T, list[T]] | nil # Defines a list of type T
66
+
67
+ type int_list = list[Integer] # List of Integer
68
+ type string_list = list[String] # List of String
69
+ ```
70
+
71
+ You can find the detail in the [PR](https://github.com/ruby/rbs/pull/823).
72
+
73
+ ### Signature updates
74
+
75
+ * `Date#+`, `Date#-` ([\#830](https://github.com/ruby/rbs/pull/830))
76
+ * `#include?`, `#member?`, `#delete`, `#count` ([\#835](https://github.com/ruby/rbs/pull/835))
77
+
78
+ ### Language updates
79
+
80
+ * Generic type alias ([\#823](https://github.com/ruby/rbs/pull/823))
81
+
82
+ ## 1.7.1 (2021-11-18)
83
+
84
+ ### Signature updates
85
+
86
+ * `Thread#value` ([\#824](https://github.com/ruby/rbs/pull/824/files))
87
+
88
+ ### Library changes
89
+
90
+ * Unquote parameter name ([\#827](https://github.com/ruby/rbs/pull/827))
91
+ * Remove `ruby/signature.rb` ([\#825](https://github.com/ruby/rbs/pull/825))
92
+
93
+ ### Miscellaneous
94
+
95
+ * Use `untyped` as an expectation of return value of `IO#ready?` in test ([\#828](https://github.com/ruby/rbs/pull/828/files))
96
+
5
97
  ## 1.7.0 (2021-11-11)
6
98
 
7
99
  This version replaces `RBS::Parser` implementation from pure Ruby code based on [Racc](https://github.com/ruby/racc) to C extension.
8
100
  It improves the RBS file parsing performance up to 5 times faster. :rocket:
9
101
 
10
- * There are some incompatibilties to drop obsolete syntax rules: `super` keyword and `any` type are no longer supported.
102
+ * There are some incompatibilities to drop obsolete syntax rules: `super` keyword and `any` type are no longer supported.
11
103
  * [re2c](https://github.com/skvadrik/re2c) is used to generate lexical generator.
12
104
 
13
105
  When you want to change the parser/lexer, change the files under `ext/rbs_extension` directory and run `rake compile` to compile the extension.
@@ -120,7 +212,7 @@ This release includes feature enhancements including recursive `type` definition
120
212
 
121
213
  ### Library changes
122
214
 
123
- * Add Recursiive type alias defnition validation ([\#719](https://github.com/ruby/rbs/pull/719))
215
+ * Add Recursive type alias definition validation ([\#719](https://github.com/ruby/rbs/pull/719))
124
216
  * Generate included modules with complete name ([\#731](https://github.com/ruby/rbs/pull/731))
125
217
  * Fix `rbs-prototype-rb` error when multi assign with const ([\#740](https://github.com/ruby/rbs/pull/740))
126
218
 
@@ -148,7 +240,7 @@ This release is to fix a bug introduced by parser update in 1.3.0.
148
240
 
149
241
  ### Summary
150
242
 
151
- RBS 1.3.0 includes bug fixees of the parser and class/module definition validations.
243
+ RBS 1.3.0 includes bug fixes of the parser and class/module definition validations.
152
244
 
153
245
  ### Signature updates
154
246
 
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/core/thread.rbs CHANGED
@@ -554,7 +554,7 @@ class Thread < Object
554
554
  # b = Thread.new { raise 'something went wrong' }
555
555
  # b.value #=> RuntimeError: something went wrong
556
556
  # ```
557
- def value: () -> Object
557
+ def value: () -> untyped
558
558
 
559
559
  # Marks a given thread as eligible for scheduling, however it may still
560
560
  # remain blocked on I/O.
data/docs/collection.md CHANGED
@@ -7,7 +7,6 @@
7
7
  * `git(1)`
8
8
  * `Gemfile.lock`
9
9
 
10
-
11
10
  ## Usage
12
11
 
13
12
  ### Setup
@@ -65,9 +64,13 @@ Finally the third party RBSs are available! `rbs` commands, such as `rbs validat
65
64
 
66
65
  ## Configuration
67
66
 
67
+ ### `rbs_collection.yaml`
68
+
68
69
  Configure `rbs collection` with editing `rbs_collection.yaml`.
69
70
 
70
71
  ```yaml
72
+ # rbs_collection.yaml
73
+
71
74
  # Download sources.
72
75
  # You can add own collection git repository.
73
76
  sources:
@@ -92,6 +95,25 @@ gems:
92
95
  ignore: true
93
96
  ```
94
97
 
98
+ ### `manifest.yaml`
99
+
100
+ If you are a gem maintainer, you can write `manifest.yaml`.
101
+ You need to put the file if the gem has implicit dependencies, which don't appear in `Gemfile.lock`. You have to write standard libraries' dependencies in most cases.
102
+ For example:
103
+
104
+ ```yaml
105
+ # manifest.yaml
106
+
107
+ dependencies:
108
+ # If your gem depends on pathname but the gemspec doesn't include pathname,
109
+ # you need to write the following.
110
+ - name: pathname
111
+ ```
112
+
113
+ If the gem's RBS is managed with [ruby/gem_rbs_collection](https://github.com/ruby/gem_rbs_collection), put it as `gems/GEM_NAME/VERSION/manifest.yaml`. For example, `gems/activesupport/6.0/manifest.yaml`.
114
+ If the gem's RBS is included in the gem package, put it as `sig/manifest.yaml`.
115
+
116
+
95
117
  ## Files / Directories
96
118
 
97
119
  * `rbs_collection.yaml`
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.
@@ -288,12 +288,12 @@ _method-member_ ::= `def` _method-name_ `:` _method-types_ # Instance
288
288
  | `def self.` _method-name_ `:` _method-types_ # Singleton method
289
289
  | `def self?.` _method-name_ `:` _method-types_ # Singleton and instance method
290
290
 
291
- _method-types_ ::= # Empty
292
- | _type-parameters_ _method-type_ `|` _method-types_ # Overloading types
293
- | `...` # Overloading for duplicate definitions
291
+ _method-types_ ::= _method-type-parameters_ _method-type_ # Single method type
292
+ | _method-type-parameters_ _method-type_ `|` _method-types_ # Overloading types
293
+ | `...` # Overloading for duplicate definitions
294
294
 
295
- _type-parameters_ ::= # Empty
296
- | `[` _type-variable_ `,` etc. `]`
295
+ _method-type-parameters_ ::= # Empty
296
+ | `[` _type-variable_ `,` ... `]`
297
297
 
298
298
  _attribute-member_ ::= _attribute-type_ _method-name_ `:` _type_ # Attribute
299
299
  | _attribute-type_ _method-name_ `(` _ivar-name_ `) :` _type_ # Attribute with variable name specification
@@ -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
 
@@ -446,48 +443,13 @@ _const-name_ ::= _namespace_ /[A-Z]\w*/
446
443
  _global-name_ ::= /$[a-zA-Z]\w+/ | ...
447
444
 
448
445
  _module-type-parameters_ ::= # Empty
449
- | `[` _module-type-parameter_ `,` etc. `]`
450
-
451
- _module-type-parameter_ ::= _check_ _variance_ _type-variable_
452
- _variance_ ::= `out` | `in`
453
- _check_ ::= # Empty
454
- | `unchecked`
446
+ | `[` _module-type-parameter_ `,` ... `]`
455
447
  ```
456
448
 
457
449
  ### Class declaration
458
450
 
459
451
  Class declaration can have type parameters and superclass. When you omit superclass, `::Object` is assumed.
460
452
 
461
- ```
462
- class Ref[A] < Object
463
- attr_reader value: A
464
- def initialize: (value: A) -> void
465
- end
466
- ```
467
-
468
- For classes with type parameters, you may specify if they are "invariant" (default), "covariant" (`out`) or "contravariant" (`in`). See [this definition of covariance and contravariance](https://en.wikipedia.org/wiki/Covariance_and_contravariance_(computer_science)).
469
-
470
- For example, an `Array` of `String` can almost be considered to be an `Array` of `Object`, but not the reverse, so we can think of:
471
-
472
- ```
473
- class Array[out T]
474
- # etc.
475
- end
476
- ```
477
-
478
- There's a limitation with this is for mutable objects (like arrays): a mutation could invalidate this.
479
- If an array of String is passed to a method as an array of Objects, and that method adds an Integer to the array, the promise is broken.
480
-
481
- In those cases, one must use the `unchecked` keyword:
482
-
483
- ```
484
- class Array[unchecked out T]
485
- # etc.
486
- end
487
- ```
488
-
489
- This is how `Array` is actually defined in RBS.
490
-
491
453
  ### Module declaration
492
454
 
493
455
  Module declaration takes optional _self type_ parameter, which defines a constraint about a class when the module is mixed.
@@ -536,6 +498,12 @@ type subject = Attendee | Speaker
536
498
  type JSON::t = Integer | TrueClass | FalseClass | String | Hash[Symbol, t] | Array[t]
537
499
  ```
538
500
 
501
+ Type alias can be generic like class, module, and interface.
502
+
503
+ ```
504
+ type list[out T] = [T, list[T]] | nil
505
+ ```
506
+
539
507
  ### Constant type declaration
540
508
 
541
509
  You can declare a constant.
@@ -552,6 +520,94 @@ You can declare a global variable.
552
520
  $LOAD_PATH: Array[String]
553
521
  ```
554
522
 
523
+ ### Generics
524
+
525
+ ```md
526
+ _module-type-parameter_ ::= _generics-unchecked_ _generics-variance_ _type-variable_ _generics-bound_
527
+
528
+ _method-type-param_ ::= _type-variable_ _generics-bound_
529
+
530
+ _generics-bound_ ::= (No type bound)
531
+ | `<` _bound-type_ (The generics parameter is bounded)
532
+
533
+ _bound-type_ ::= _class-name_ _type-arguments_ (Class instance type)
534
+ | _interface-name_ _type-arguments_ (Interface type)
535
+ | `singleton(` _class-name_ `)` (Class singleton type)
536
+
537
+ _generics-variance_ ::= (Invariant)
538
+ | `out` (Covariant)
539
+ | `in` (Contravariant)
540
+
541
+ _generics-unchecked_ ::= (Empty)
542
+ | `unchecked` (Skips variance annotation validation)
543
+ ```
544
+
545
+ RBS allows class/module/interface/type alias definitions and methods to be generic.
546
+
547
+ ```rbs
548
+ # Simple generic class definition
549
+ class Stack[T]
550
+ def push: (T) -> void
551
+
552
+ def pop: () -> T
553
+ end
554
+ ```
555
+
556
+ For classes with type parameters, you may specify if they are "invariant" (default), "covariant" (`out`) or "contravariant" (`in`). See [this definition of covariance and contravariance](https://en.wikipedia.org/wiki/Covariance_and_contravariance_(computer_science)).
557
+
558
+ For example, an `Array` of `String` can almost be considered to be an `Array` of `Object`, but not the reverse, so we can think of:
559
+
560
+ ```
561
+ # The `T` type parameter is covariant.
562
+ class Array[out T]
563
+ # etc.
564
+ end
565
+ ```
566
+
567
+ There's a limitation with this is for mutable objects (like arrays): a mutation could invalidate this.
568
+ If an array of `String` is passed to a method as an array of `Objects`, and that method adds an Integer to the array, the promise is broken.
569
+
570
+ In those cases, one must use the `unchecked` keyword:
571
+
572
+ ```rbs
573
+ # Skips the validation of variance of the type parameter `T`.
574
+ # The type safety prohibits `out` type parameters to appear at _negative_ position (== method parameter), but we want `Array` to have it.
575
+ class Array[unchecked out T]
576
+ def include?: (T) -> bool
577
+ end
578
+ ```
579
+
580
+ This is how `Array` is actually defined in RBS.
581
+
582
+ Note that RBS doesn't allow specifying variance related annotations to generic method types.
583
+
584
+ ```rbs
585
+ class Foo
586
+ def bar: [out T] () -> T # Syntax error
587
+ end
588
+ ```
589
+
590
+ You can also specify the _upper bound_ of the type parameter.
591
+
592
+ ```rbs
593
+ class PrettyPrint[T < _Output]
594
+ interface _Output
595
+ def <<: (String) -> void
596
+ end
597
+
598
+ attr_reader output: T
599
+ end
600
+ ```
601
+
602
+ If a type parameter has an upper bound, the type parameter must be instantiated with types that is a subclass of the upper bound.
603
+
604
+ ```rbs
605
+ type str_printer = PrettyPrint[String] # OK
606
+ type int_printer = PrettyPrint[Integer] # Type error
607
+ ```
608
+
609
+ The upper bound must be one of a class instance type, interface type, or class singleton type.
610
+
555
611
  ### Comments
556
612
 
557
613
  You can write single line comments. Comments must be on their own line. Comments can lead with whitespace.
@@ -6,12 +6,10 @@ VALUE RBS;
6
6
  VALUE RBS_AST;
7
7
  VALUE RBS_AST_Comment;
8
8
  VALUE RBS_AST_Annotation;
9
+ VALUE RBS_AST_TypeParam;
9
10
 
10
11
  VALUE RBS_AST_Declarations;
11
12
 
12
- VALUE RBS_AST_Declarations_ModuleTypeParams;
13
- VALUE RBS_AST_Declarations_ModuleTypeParams_TypeParam;
14
-
15
13
  VALUE RBS_AST_Declarations_Alias;
16
14
  VALUE RBS_AST_Declarations_Constant;
17
15
  VALUE RBS_AST_Declarations_Global;
@@ -77,12 +75,10 @@ void rbs__init_constants() {
77
75
  RBS_AST = rb_const_get(RBS, rb_intern("AST"));
78
76
  RBS_AST_Comment = rb_const_get(RBS_AST, rb_intern("Comment"));
79
77
  RBS_AST_Annotation = rb_const_get(RBS_AST, rb_intern("Annotation"));
78
+ RBS_AST_TypeParam = rb_const_get(RBS_AST, rb_intern("TypeParam"));
80
79
 
81
80
  RBS_AST_Declarations = rb_const_get(RBS_AST, rb_intern("Declarations"));
82
81
 
83
- RBS_AST_Declarations_ModuleTypeParams = rb_const_get(RBS_AST_Declarations, rb_intern("ModuleTypeParams"));
84
- RBS_AST_Declarations_ModuleTypeParams_TypeParam = rb_const_get(RBS_AST_Declarations_ModuleTypeParams, rb_intern("TypeParam"));
85
-
86
82
  RBS_AST_Declarations_Alias = rb_const_get(RBS_AST_Declarations, rb_intern("Alias"));
87
83
  RBS_AST_Declarations_Constant = rb_const_get(RBS_AST_Declarations, rb_intern("Constant"));
88
84
  RBS_AST_Declarations_Global = rb_const_get(RBS_AST_Declarations, rb_intern("Global"));
@@ -6,6 +6,7 @@ extern VALUE RBS;
6
6
  extern VALUE RBS_AST;
7
7
  extern VALUE RBS_AST_Annotation;
8
8
  extern VALUE RBS_AST_Comment;
9
+ extern VALUE RBS_AST_TypeParam;
9
10
 
10
11
  extern VALUE RBS_AST_Declarations;
11
12
  extern VALUE RBS_AST_Declarations_Alias;
@@ -16,8 +17,6 @@ extern VALUE RBS_AST_Declarations_Global;
16
17
  extern VALUE RBS_AST_Declarations_Interface;
17
18
  extern VALUE RBS_AST_Declarations_Module_Self;
18
19
  extern VALUE RBS_AST_Declarations_Module;
19
- extern VALUE RBS_AST_Declarations_ModuleTypeParams_TypeParam;
20
- extern VALUE RBS_AST_Declarations_ModuleTypeParams;
21
20
 
22
21
  extern VALUE RBS_AST_Members;
23
22
  extern VALUE RBS_AST_Members_Alias;