rbs 1.7.1 → 2.0.0.pre2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +104 -3
- data/core/array.rbs +3 -3
- data/core/builtin.rbs +4 -0
- data/core/enumerable.rbs +3 -3
- 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 +220 -184
- 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 +99 -22
- 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 +11 -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/generic.rbs +34 -34
- 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 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d69ba0591c817c21a42f8bcd95f993fda8574e753f48bf05fd03f34dfa77b65b
|
4
|
+
data.tar.gz: 07dfb19e31c6d275bf51ce0391d161befde331dcdbc071bf8455239b94be9aaf
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
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
|
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
|
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
|
-
| (
|
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/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;
|