rbs 1.7.0 → 2.0.0.pre1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +95 -3
- data/core/array.rbs +3 -3
- data/core/builtin.rbs +4 -0
- data/core/enumerable.rbs +3 -3
- data/core/thread.rbs +1 -1
- data/docs/collection.md +23 -1
- data/docs/syntax.md +117 -61
- data/ext/rbs_extension/constants.c +2 -6
- data/ext/rbs_extension/constants.h +1 -2
- data/ext/rbs_extension/parser.c +221 -185
- data/ext/rbs_extension/parserstate.c +6 -2
- data/ext/rbs_extension/parserstate.h +10 -0
- data/ext/rbs_extension/ruby_objs.c +17 -17
- data/ext/rbs_extension/ruby_objs.h +3 -4
- data/lib/rbs/ast/declarations.rb +6 -99
- data/lib/rbs/ast/type_param.rb +134 -0
- data/lib/rbs/cli.rb +33 -5
- data/lib/rbs/collection/config/lockfile_generator.rb +26 -18
- data/lib/rbs/collection/sources/git.rb +18 -7
- data/lib/rbs/collection/sources/rubygems.rb +7 -0
- data/lib/rbs/collection/sources/stdlib.rb +6 -0
- data/lib/rbs/definition.rb +9 -0
- data/lib/rbs/definition_builder.rb +78 -16
- data/lib/rbs/environment.rb +32 -8
- data/lib/rbs/environment_loader.rb +0 -2
- data/lib/rbs/environment_walker.rb +4 -1
- data/lib/rbs/errors.rb +31 -6
- data/lib/rbs/location_aux.rb +2 -0
- data/lib/rbs/method_type.rb +29 -6
- data/lib/rbs/prototype/rb.rb +3 -3
- data/lib/rbs/prototype/rbi.rb +8 -6
- data/lib/rbs/prototype/runtime.rb +4 -4
- data/lib/rbs/type_alias_regularity.rb +115 -0
- data/lib/rbs/types.rb +100 -23
- data/lib/rbs/validator.rb +99 -15
- data/lib/rbs/variance_calculator.rb +60 -31
- data/lib/rbs/version.rb +1 -1
- data/lib/rbs/writer.rb +2 -14
- data/lib/rbs.rb +2 -0
- data/schema/decls.json +19 -46
- data/schema/methodType.json +1 -1
- data/schema/typeParam.json +36 -0
- data/schema/types.json +8 -2
- data/sig/collection/collections.rbs +13 -2
- data/sig/collection/config.rbs +2 -2
- data/sig/declarations.rbs +15 -62
- data/sig/definition.rbs +11 -1
- data/sig/definition_builder.rbs +37 -1
- data/sig/environment.rbs +7 -1
- data/sig/environment_walker.rbs +26 -0
- data/sig/errors.rbs +28 -3
- data/sig/location.rbs +3 -1
- data/sig/locator.rbs +1 -1
- data/sig/method_types.rbs +25 -4
- data/sig/type_alias_regularity.rbs +92 -0
- data/sig/type_param.rbs +74 -0
- data/sig/types.rbs +37 -8
- data/sig/validator.rbs +38 -2
- data/sig/variance_calculator.rbs +50 -0
- data/sig/writer.rbs +1 -1
- data/stdlib/bigdecimal-math/0/manifest.yaml +2 -0
- data/stdlib/csv/0/manifest.yaml +2 -0
- data/stdlib/date/0/date.rbs +2 -2
- data/stdlib/logger/0/manifest.yaml +2 -0
- data/stdlib/net-http/0/manifest.yaml +2 -0
- data/stdlib/openssl/0/manifest.yaml +2 -0
- data/stdlib/prime/0/manifest.yaml +2 -0
- data/stdlib/resolv/0/manifest.yaml +3 -0
- data/stdlib/set/0/set.rbs +3 -3
- data/stdlib/uri/0/common.rbs +10 -5
- data/stdlib/uri/0/ftp.rbs +10 -0
- data/stdlib/uri/0/mailto.rbs +5 -0
- data/stdlib/uri/0/ws.rbs +10 -0
- data/stdlib/uri/0/wss.rbs +7 -0
- data/stdlib/yaml/0/manifest.yaml +3 -0
- data/steep/Gemfile.lock +10 -10
- metadata +21 -5
- data/lib/ruby/signature.rb +0 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: df2f2f119ca85f630c640b201ebf9ce72322db96223de2fb1d4ba77df68aee59
|
4
|
+
data.tar.gz: 82943e12963a10f2a4dbd30096fe40fb90ee4b23d6239bd515526a39d2af3b97
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
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
|
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
|
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
|
-
| (
|
702
|
+
| (Elem obj) -> ::Integer
|
703
703
|
| () { (Elem) -> boolish } -> ::Integer
|
704
704
|
|
705
705
|
# Calls the given block for each element `n` times or forever if `nil` is given.
|
@@ -733,7 +733,7 @@ class Array[unchecked out Elem] < Object
|
|
733
733
|
# a.delete("z") #=> nil
|
734
734
|
# a.delete("z") {"not found"} #=> "not found"
|
735
735
|
#
|
736
|
-
def delete: (
|
736
|
+
def delete: (Elem obj) -> Elem?
|
737
737
|
| [S, T] (S obj) { (S) -> T } -> (Elem | T)
|
738
738
|
|
739
739
|
# Deletes the element at the specified `index`, returning that element, or `nil`
|
@@ -1029,7 +1029,7 @@ class Array[unchecked out Elem] < Object
|
|
1029
1029
|
# a.include?("b") #=> true
|
1030
1030
|
# a.include?("z") #=> false
|
1031
1031
|
#
|
1032
|
-
def include?: (
|
1032
|
+
def include?: (Elem object) -> bool
|
1033
1033
|
|
1034
1034
|
# Returns the *index* of the first object in `ary` such that the object is `==`
|
1035
1035
|
# to `obj`.
|
data/core/builtin.rbs
CHANGED
data/core/enumerable.rbs
CHANGED
@@ -63,7 +63,7 @@ module Enumerable[unchecked out Elem]: _Each[Elem]
|
|
63
63
|
# ary.count{ |x| x%2==0 } #=> 3
|
64
64
|
# ```
|
65
65
|
def count: () -> Integer
|
66
|
-
| (
|
66
|
+
| (Elem) -> Integer
|
67
67
|
| () { (Elem) -> boolish } -> Integer
|
68
68
|
|
69
69
|
def cycle: (?Integer n) { (Elem arg0) -> untyped } -> NilClass
|
@@ -130,7 +130,7 @@ module Enumerable[unchecked out Elem]: _Each[Elem]
|
|
130
130
|
def group_by: [U] () { (Elem arg0) -> U } -> ::Hash[U, ::Array[Elem]]
|
131
131
|
| () -> ::Enumerator[Elem, ::Array[Elem]]
|
132
132
|
|
133
|
-
def `include?`: (
|
133
|
+
def `include?`: (Elem arg0) -> bool
|
134
134
|
|
135
135
|
def inject: (untyped init, Symbol method) -> untyped
|
136
136
|
| (Symbol method) -> untyped
|
@@ -341,7 +341,7 @@ module Enumerable[unchecked out Elem]: _Each[Elem]
|
|
341
341
|
def map: [U] () { (Elem arg0) -> U } -> ::Array[U]
|
342
342
|
| () -> ::Enumerator[Elem, ::Array[untyped]]
|
343
343
|
|
344
|
-
def member?: (
|
344
|
+
def member?: (Elem arg0) -> bool
|
345
345
|
|
346
346
|
alias reduce inject
|
347
347
|
|
data/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: () ->
|
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. `}`
|
15
|
-
| `[]` | `[` _type_ `,` etc. `]`
|
14
|
+
| `{` _record-name_ `:` _type_ `,` etc. `}` (Record type)
|
15
|
+
| `[]` | `[` _type_ `,` etc. `]` (Tuples)
|
16
16
|
| _type-variable_ (Type variables)
|
17
17
|
| `^(` _parameters_ `) ->` _type_ (Proc type)
|
18
18
|
| `self`
|
@@ -35,8 +35,8 @@ _namespace_ ::= (Empty namespace)
|
|
35
35
|
| `::` (Root)
|
36
36
|
| _namespace_ /[A-Z]\w*/ `::` (Namespace)
|
37
37
|
|
38
|
-
_type-arguments_ ::= (No
|
39
|
-
| `[` _type_ `,` etc. `]`
|
38
|
+
_type-arguments_ ::= (No type arguments)
|
39
|
+
| `[` _type_ `,` etc. `]` (Type arguments)
|
40
40
|
|
41
41
|
_literal_ ::= _string-literal_
|
42
42
|
| _symbol-literal_
|
@@ -64,25 +64,25 @@ _ToS # _ToS interface
|
|
64
64
|
::MyApp::_Each[String] # Interface name with namespace and type application
|
65
65
|
```
|
66
66
|
|
67
|
-
### Class singleton type
|
68
|
-
|
69
|
-
Class singleton type denotes _the type of a singleton object of a class_.
|
70
|
-
|
71
|
-
```
|
72
|
-
singleton(String)
|
73
|
-
singleton(::Hash) # Class singleton type cannot be parametrized.
|
74
|
-
```
|
75
|
-
|
76
67
|
### Alias type
|
77
68
|
|
78
69
|
Alias type denotes an alias declared with _alias declaration_.
|
79
70
|
|
80
71
|
The name of type aliases starts with lowercase `[a-z]`.
|
81
72
|
|
82
|
-
|
83
73
|
```
|
84
74
|
name
|
85
75
|
::JSON::t # Alias name with namespace
|
76
|
+
list[Integer] # Type alias can be generic
|
77
|
+
```
|
78
|
+
|
79
|
+
### Class singleton type
|
80
|
+
|
81
|
+
Class singleton type denotes _the type of a singleton object of a class_.
|
82
|
+
|
83
|
+
```
|
84
|
+
singleton(String)
|
85
|
+
singleton(::Hash) # Class singleton type cannot be parametrized.
|
86
86
|
```
|
87
87
|
|
88
88
|
### Literal type
|
@@ -155,7 +155,7 @@ Elem
|
|
155
155
|
```
|
156
156
|
|
157
157
|
Type variables cannot be distinguished from _class instance types_.
|
158
|
-
They are scoped in _class/module/interface declaration_ or _generic method types_.
|
158
|
+
They are scoped in _class/module/interface/alias declaration_ or _generic method types_.
|
159
159
|
|
160
160
|
```
|
161
161
|
class Ref[T] # Object is scoped in the class declaration.
|
@@ -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_ ::=
|
292
|
-
|
|
293
|
-
| `...`
|
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
|
-
|
296
|
-
|
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
|
-
|
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_ `,`
|
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;
|