rbs 1.7.1 → 2.0.0.pre2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (78) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +104 -3
  3. data/core/array.rbs +3 -3
  4. data/core/builtin.rbs +4 -0
  5. data/core/enumerable.rbs +3 -3
  6. data/docs/collection.md +23 -1
  7. data/docs/syntax.md +117 -61
  8. data/ext/rbs_extension/constants.c +2 -6
  9. data/ext/rbs_extension/constants.h +1 -2
  10. data/ext/rbs_extension/parser.c +220 -184
  11. data/ext/rbs_extension/parserstate.c +6 -2
  12. data/ext/rbs_extension/parserstate.h +10 -0
  13. data/ext/rbs_extension/ruby_objs.c +17 -17
  14. data/ext/rbs_extension/ruby_objs.h +3 -4
  15. data/lib/rbs/ast/declarations.rb +6 -99
  16. data/lib/rbs/ast/type_param.rb +134 -0
  17. data/lib/rbs/cli.rb +33 -5
  18. data/lib/rbs/collection/config/lockfile_generator.rb +26 -18
  19. data/lib/rbs/collection/sources/git.rb +18 -7
  20. data/lib/rbs/collection/sources/rubygems.rb +7 -0
  21. data/lib/rbs/collection/sources/stdlib.rb +6 -0
  22. data/lib/rbs/definition.rb +9 -0
  23. data/lib/rbs/definition_builder.rb +78 -16
  24. data/lib/rbs/environment.rb +32 -8
  25. data/lib/rbs/environment_loader.rb +0 -2
  26. data/lib/rbs/environment_walker.rb +4 -1
  27. data/lib/rbs/errors.rb +31 -6
  28. data/lib/rbs/location_aux.rb +2 -0
  29. data/lib/rbs/method_type.rb +29 -6
  30. data/lib/rbs/prototype/rb.rb +3 -3
  31. data/lib/rbs/prototype/rbi.rb +8 -6
  32. data/lib/rbs/prototype/runtime.rb +4 -4
  33. data/lib/rbs/type_alias_regularity.rb +115 -0
  34. data/lib/rbs/types.rb +99 -22
  35. data/lib/rbs/validator.rb +99 -15
  36. data/lib/rbs/variance_calculator.rb +60 -31
  37. data/lib/rbs/version.rb +1 -1
  38. data/lib/rbs/writer.rb +2 -14
  39. data/lib/rbs.rb +2 -0
  40. data/schema/decls.json +19 -46
  41. data/schema/methodType.json +1 -1
  42. data/schema/typeParam.json +36 -0
  43. data/schema/types.json +8 -2
  44. data/sig/collection/collections.rbs +11 -2
  45. data/sig/collection/config.rbs +2 -2
  46. data/sig/declarations.rbs +15 -62
  47. data/sig/definition.rbs +11 -1
  48. data/sig/definition_builder.rbs +37 -1
  49. data/sig/environment.rbs +7 -1
  50. data/sig/environment_walker.rbs +26 -0
  51. data/sig/errors.rbs +28 -3
  52. data/sig/location.rbs +3 -1
  53. data/sig/locator.rbs +1 -1
  54. data/sig/method_types.rbs +25 -4
  55. data/sig/type_alias_regularity.rbs +92 -0
  56. data/sig/type_param.rbs +74 -0
  57. data/sig/types.rbs +37 -8
  58. data/sig/validator.rbs +38 -2
  59. data/sig/variance_calculator.rbs +50 -0
  60. data/sig/writer.rbs +1 -1
  61. data/stdlib/bigdecimal-math/0/manifest.yaml +2 -0
  62. data/stdlib/csv/0/manifest.yaml +2 -0
  63. data/stdlib/date/0/date.rbs +2 -2
  64. data/stdlib/logger/0/manifest.yaml +2 -0
  65. data/stdlib/net-http/0/manifest.yaml +2 -0
  66. data/stdlib/openssl/0/manifest.yaml +2 -0
  67. data/stdlib/prime/0/manifest.yaml +2 -0
  68. data/stdlib/resolv/0/manifest.yaml +3 -0
  69. data/stdlib/set/0/set.rbs +3 -3
  70. data/stdlib/uri/0/common.rbs +10 -5
  71. data/stdlib/uri/0/ftp.rbs +10 -0
  72. data/stdlib/uri/0/generic.rbs +34 -34
  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 -4
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d93b02ff74da3638b4aee35967e4ccc34460c1103ceb51ecfd5406d39e732f21
4
- data.tar.gz: b11beb145022527d5d16e2c6545fcc4aa847790e3502b6054f77785685b7fe6c
3
+ metadata.gz: d69ba0591c817c21a42f8bcd95f993fda8574e753f48bf05fd03f34dfa77b65b
4
+ data.tar.gz: 07dfb19e31c6d275bf51ce0391d161befde331dcdbc071bf8455239b94be9aaf
5
5
  SHA512:
6
- metadata.gz: 689cdd0da1b18d8d0d6c9cde454cd3a2de0d44f66e19d52400734bb13001770b44bf0f66a87db403d31fb91ddccdefee87a056686055165d1935ade8fd376ff6
7
- data.tar.gz: 488b07051aea9edb7c3c32e9fafc8b1bfcd16f38b8dc492aa4656a0a15a1577615522a15f22c3e900acb458f0bce4620998c2dfc79b17638dd64f025bd0ff29c
6
+ metadata.gz: 4c5efd986d31b8fbcbc0c50b7625fc743dbf3de0f82ef955909644653d6ec41ca9208fb89f5e0d2359a76f82f15aa627aeccc6ac43a62d9589c818a5d38fa12e
7
+ data.tar.gz: de8bab99ebb3a68ed3d61e261900d822e5f1fee8c5678bea38fd3e2e180138909181da2a769b147497e069c6c6b813edb24eef83f1a433cffc3c6ed79beeee23
data/CHANGELOG.md CHANGED
@@ -2,6 +2,107 @@
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 a new syntax to define constraints 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
+ ### RBS Collection manager
32
+
33
+ RBS Collection feature is generally available on RBS 2.0. In short, it is Bundler for RBS. You can manage RBSs of standard libraries and third party gems with `rbs collection` subcommand.
34
+
35
+ ```bash
36
+ $ rbs collection init
37
+ created: rbs_collection.yaml
38
+
39
+ # The `install` command set up RBS files and creates `rbs_collection.lock.yaml` file
40
+ $ rbs collection install
41
+ Installing actionpack:6.0 (actionpack@ce6664cec73)
42
+ (...snip...)
43
+ Using tsort:0 (/path/to/rbs-2.0.0/stdlib/tsort/0)
44
+ It's done! 21 gems' RBSs now installed.
45
+
46
+ # Now you can use `rbs`, `typeprof` and `steep` commands with the dependencies out of the box!
47
+ $ rbs validate
48
+ $ typeprof app.rb
49
+ $ steep check
50
+ ```
51
+
52
+ RBS 2.0 also introduces `manifest.yaml` to declare the dependencies from your gems to standard libraries explicitly.
53
+ See [the documentation](https://github.com/ruby/rbs/blob/master/docs/collection.md) for more information.
54
+
55
+ ### Breaking changes
56
+
57
+ This version contains a bug fix, which potentially breaks the compatibility with older versions.
58
+ The super class names in class definitions are now resolved in _outer_ context.
59
+ It was an incompatibility with Ruby and [this PR](https://github.com/ruby/rbs/pull/856) fixed the problem.
60
+
61
+ ### Signature updates
62
+
63
+ * 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))
64
+
65
+ ### Language updates
66
+
67
+ * Bounded generics ([\#844](https://github.com/ruby/rbs/pull/844))
68
+ * Resolve super type names in outer context ([\#856](https://github.com/ruby/rbs/pull/856))
69
+
70
+ ### Library changes
71
+
72
+ * Add `manifest.yaml` for collection to specify stdlib dependencies ([\#808](https://github.com/ruby/rbs/pull/808))
73
+ * Remove experimental warning of `rbs collection` ([\#855](https://github.com/ruby/rbs/pull/855))
74
+ * Add the utility `#map_type` methods ([\#841](https://github.com/ruby/rbs/pull/841))
75
+
76
+ ## 1.8.1 (2021-12-13)
77
+
78
+ ### Library changes
79
+
80
+ * Validate `extend` arguments ([\#840](https://github.com/ruby/rbs/pull/840))
81
+ * Allow a relative path as git remote in collection ([\#839](https://github.com/ruby/rbs/pull/839))
82
+
83
+ ## 1.8.0 (2021-12-02)
84
+
85
+ RBS 1.8.0 ships with a language feature enhancement, _generic type alias_.
86
+ You can define a type alias with type parameters now.
87
+
88
+ ```rbs
89
+ type list[T] = [T, list[T]] | nil # Defines a list of type T
90
+
91
+ type int_list = list[Integer] # List of Integer
92
+ type string_list = list[String] # List of String
93
+ ```
94
+
95
+ You can find the detail in the [PR](https://github.com/ruby/rbs/pull/823).
96
+
97
+ ### Signature updates
98
+
99
+ * `Date#+`, `Date#-` ([\#830](https://github.com/ruby/rbs/pull/830))
100
+ * `#include?`, `#member?`, `#delete`, `#count` ([\#835](https://github.com/ruby/rbs/pull/835))
101
+
102
+ ### Language updates
103
+
104
+ * Generic type alias ([\#823](https://github.com/ruby/rbs/pull/823))
105
+
5
106
  ## 1.7.1 (2021-11-18)
6
107
 
7
108
  ### Signature updates
@@ -22,7 +123,7 @@
22
123
  This version replaces `RBS::Parser` implementation from pure Ruby code based on [Racc](https://github.com/ruby/racc) to C extension.
23
124
  It improves the RBS file parsing performance up to 5 times faster. :rocket:
24
125
 
25
- * There are some incompatibilties to drop obsolete syntax rules: `super` keyword and `any` type are no longer supported.
126
+ * There are some incompatibilities to drop obsolete syntax rules: `super` keyword and `any` type are no longer supported.
26
127
  * [re2c](https://github.com/skvadrik/re2c) is used to generate lexical generator.
27
128
 
28
129
  When you want to change the parser/lexer, change the files under `ext/rbs_extension` directory and run `rake compile` to compile the extension.
@@ -135,7 +236,7 @@ This release includes feature enhancements including recursive `type` definition
135
236
 
136
237
  ### Library changes
137
238
 
138
- * Add Recursiive type alias defnition validation ([\#719](https://github.com/ruby/rbs/pull/719))
239
+ * Add Recursive type alias definition validation ([\#719](https://github.com/ruby/rbs/pull/719))
139
240
  * Generate included modules with complete name ([\#731](https://github.com/ruby/rbs/pull/731))
140
241
  * Fix `rbs-prototype-rb` error when multi assign with const ([\#740](https://github.com/ruby/rbs/pull/740))
141
242
 
@@ -163,7 +264,7 @@ This release is to fix a bug introduced by parser update in 1.3.0.
163
264
 
164
265
  ### Summary
165
266
 
166
- RBS 1.3.0 includes bug fixees of the parser and class/module definition validations.
267
+ RBS 1.3.0 includes bug fixes of the parser and class/module definition validations.
167
268
 
168
269
  ### Signature updates
169
270
 
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/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;