rbs 4.0.0.dev.4 → 4.0.0
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/.github/dependabot.yml +14 -14
- data/.github/workflows/bundle-update.yml +60 -0
- data/.github/workflows/c-check.yml +18 -11
- data/.github/workflows/comments.yml +5 -3
- data/.github/workflows/dependabot.yml +2 -2
- data/.github/workflows/ruby.yml +27 -34
- data/.github/workflows/rust.yml +95 -0
- data/.github/workflows/typecheck.yml +2 -2
- data/.github/workflows/windows.yml +2 -2
- data/.rubocop.yml +1 -1
- data/CHANGELOG.md +323 -0
- data/README.md +1 -1
- data/Rakefile +43 -33
- data/Steepfile +1 -0
- data/config.yml +426 -24
- data/core/array.rbs +307 -227
- data/core/basic_object.rbs +9 -8
- data/core/binding.rbs +0 -2
- data/core/builtin.rbs +2 -2
- data/core/class.rbs +6 -5
- data/core/comparable.rbs +55 -34
- data/core/complex.rbs +104 -78
- data/core/dir.rbs +61 -49
- data/core/encoding.rbs +12 -15
- data/core/enumerable.rbs +179 -87
- data/core/enumerator/arithmetic_sequence.rbs +70 -0
- data/core/enumerator.rbs +65 -2
- data/core/errno.rbs +11 -2
- data/core/errors.rbs +58 -29
- data/core/exception.rbs +13 -13
- data/core/fiber.rbs +74 -54
- data/core/file.rbs +280 -177
- data/core/file_test.rbs +3 -3
- data/core/float.rbs +257 -92
- data/core/gc.rbs +425 -281
- data/core/hash.rbs +1045 -739
- data/core/integer.rbs +135 -137
- data/core/io/buffer.rbs +53 -42
- data/core/io/wait.rbs +13 -35
- data/core/io.rbs +192 -144
- data/core/kernel.rbs +216 -155
- data/core/marshal.rbs +4 -4
- data/core/match_data.rbs +15 -13
- data/core/math.rbs +107 -66
- data/core/method.rbs +69 -33
- data/core/module.rbs +244 -106
- data/core/nil_class.rbs +7 -6
- data/core/numeric.rbs +74 -63
- data/core/object.rbs +9 -11
- data/core/object_space.rbs +30 -23
- data/core/pathname.rbs +1322 -0
- data/core/proc.rbs +95 -58
- data/core/process.rbs +222 -202
- data/core/ractor.rbs +371 -515
- data/core/random.rbs +21 -3
- data/core/range.rbs +159 -57
- data/core/rational.rbs +60 -89
- data/core/rbs/unnamed/argf.rbs +60 -53
- data/core/rbs/unnamed/env_class.rbs +19 -14
- data/core/rbs/unnamed/main_class.rbs +123 -0
- data/core/rbs/unnamed/random.rbs +11 -118
- data/core/regexp.rbs +258 -214
- data/core/ruby.rbs +53 -0
- data/core/ruby_vm.rbs +38 -34
- data/core/rubygems/config_file.rbs +5 -5
- data/core/rubygems/errors.rbs +4 -71
- data/core/rubygems/requirement.rbs +5 -5
- data/core/rubygems/rubygems.rbs +16 -82
- data/core/rubygems/version.rbs +2 -3
- data/core/set.rbs +490 -360
- data/core/signal.rbs +26 -16
- data/core/string.rbs +3234 -1285
- data/core/struct.rbs +27 -26
- data/core/symbol.rbs +41 -34
- data/core/thread.rbs +135 -67
- data/core/time.rbs +81 -50
- data/core/trace_point.rbs +41 -35
- data/core/true_class.rbs +2 -2
- data/core/unbound_method.rbs +24 -16
- data/core/warning.rbs +7 -7
- data/docs/aliases.md +79 -0
- data/docs/collection.md +3 -3
- data/docs/config.md +171 -0
- data/docs/encoding.md +56 -0
- data/docs/gem.md +0 -1
- data/docs/inline.md +576 -0
- data/docs/sigs.md +3 -3
- data/docs/syntax.md +46 -16
- data/docs/type_fingerprint.md +21 -0
- data/exe/rbs +1 -1
- data/ext/rbs_extension/ast_translation.c +544 -116
- data/ext/rbs_extension/ast_translation.h +3 -0
- data/ext/rbs_extension/class_constants.c +16 -2
- data/ext/rbs_extension/class_constants.h +8 -0
- data/ext/rbs_extension/extconf.rb +5 -1
- data/ext/rbs_extension/legacy_location.c +33 -56
- data/ext/rbs_extension/legacy_location.h +37 -0
- data/ext/rbs_extension/main.c +44 -35
- data/include/rbs/ast.h +448 -173
- data/include/rbs/defines.h +27 -0
- data/include/rbs/lexer.h +30 -11
- data/include/rbs/location.h +25 -44
- data/include/rbs/parser.h +6 -6
- data/include/rbs/string.h +0 -2
- data/include/rbs/util/rbs_allocator.h +34 -13
- data/include/rbs/util/rbs_assert.h +12 -1
- data/include/rbs/util/rbs_constant_pool.h +0 -3
- data/include/rbs/util/rbs_encoding.h +2 -0
- data/include/rbs/util/rbs_unescape.h +2 -1
- data/include/rbs.h +8 -0
- data/lib/rbs/ast/annotation.rb +1 -1
- data/lib/rbs/ast/comment.rb +1 -1
- data/lib/rbs/ast/declarations.rb +10 -10
- data/lib/rbs/ast/members.rb +14 -14
- data/lib/rbs/ast/ruby/annotations.rb +293 -3
- data/lib/rbs/ast/ruby/comment_block.rb +24 -0
- data/lib/rbs/ast/ruby/declarations.rb +198 -3
- data/lib/rbs/ast/ruby/helpers/constant_helper.rb +4 -0
- data/lib/rbs/ast/ruby/members.rb +532 -22
- data/lib/rbs/ast/type_param.rb +24 -4
- data/lib/rbs/buffer.rb +20 -15
- data/lib/rbs/cli/diff.rb +16 -15
- data/lib/rbs/cli/validate.rb +38 -106
- data/lib/rbs/cli.rb +52 -19
- data/lib/rbs/collection/config/lockfile_generator.rb +14 -2
- data/lib/rbs/collection/sources/git.rb +1 -0
- data/lib/rbs/definition.rb +1 -1
- data/lib/rbs/definition_builder/ancestor_builder.rb +62 -9
- data/lib/rbs/definition_builder/method_builder.rb +20 -0
- data/lib/rbs/definition_builder.rb +147 -25
- data/lib/rbs/diff.rb +7 -1
- data/lib/rbs/environment.rb +227 -74
- data/lib/rbs/environment_loader.rb +0 -6
- data/lib/rbs/errors.rb +27 -18
- data/lib/rbs/inline_parser.rb +342 -6
- data/lib/rbs/location_aux.rb +1 -1
- data/lib/rbs/locator.rb +5 -1
- data/lib/rbs/method_type.rb +5 -3
- data/lib/rbs/parser_aux.rb +20 -7
- data/lib/rbs/prototype/helpers.rb +57 -0
- data/lib/rbs/prototype/rb.rb +3 -28
- data/lib/rbs/prototype/rbi.rb +3 -20
- data/lib/rbs/prototype/runtime.rb +8 -0
- data/lib/rbs/resolver/constant_resolver.rb +2 -2
- data/lib/rbs/resolver/type_name_resolver.rb +116 -38
- data/lib/rbs/subtractor.rb +3 -1
- data/lib/rbs/test/type_check.rb +19 -2
- data/lib/rbs/type_name.rb +1 -1
- data/lib/rbs/types.rb +88 -78
- data/lib/rbs/unit_test/type_assertions.rb +35 -8
- data/lib/rbs/validator.rb +2 -2
- data/lib/rbs/version.rb +1 -1
- data/lib/rbs.rb +1 -2
- data/lib/rdoc/discover.rb +1 -1
- data/lib/rdoc_plugin/parser.rb +1 -1
- data/rbs.gemspec +4 -3
- data/rust/.gitignore +1 -0
- data/rust/Cargo.lock +378 -0
- data/rust/Cargo.toml +7 -0
- data/rust/ruby-rbs/Cargo.toml +22 -0
- data/rust/ruby-rbs/build.rs +764 -0
- data/rust/ruby-rbs/examples/locations.rs +60 -0
- data/rust/ruby-rbs/src/lib.rs +1 -0
- data/rust/ruby-rbs/src/node/mod.rs +742 -0
- data/rust/ruby-rbs/tests/sanity.rs +47 -0
- data/rust/ruby-rbs/vendor/rbs/config.yml +1 -0
- data/rust/ruby-rbs-sys/Cargo.toml +23 -0
- data/rust/ruby-rbs-sys/build.rs +204 -0
- data/rust/ruby-rbs-sys/src/lib.rs +50 -0
- data/rust/ruby-rbs-sys/vendor/rbs/include +1 -0
- data/rust/ruby-rbs-sys/vendor/rbs/src +1 -0
- data/rust/ruby-rbs-sys/wrapper.h +1 -0
- data/schema/typeParam.json +17 -1
- data/sig/ast/ruby/annotations.rbs +315 -4
- data/sig/ast/ruby/comment_block.rbs +8 -0
- data/sig/ast/ruby/declarations.rbs +102 -4
- data/sig/ast/ruby/members.rbs +108 -2
- data/sig/cli/diff.rbs +5 -11
- data/sig/cli/validate.rbs +12 -8
- data/sig/cli.rbs +18 -18
- data/sig/definition.rbs +6 -1
- data/sig/definition_builder.rbs +2 -0
- data/sig/environment.rbs +70 -12
- data/sig/errors.rbs +13 -14
- data/sig/inline_parser.rbs +39 -2
- data/sig/locator.rbs +0 -2
- data/sig/manifest.yaml +0 -1
- data/sig/method_builder.rbs +3 -1
- data/sig/parser.rbs +31 -13
- data/sig/prototype/helpers.rbs +2 -0
- data/sig/resolver/type_name_resolver.rbs +35 -7
- data/sig/source.rbs +3 -3
- data/sig/type_param.rbs +13 -8
- data/sig/types.rbs +6 -7
- data/sig/unit_test/spy.rbs +0 -8
- data/sig/unit_test/type_assertions.rbs +11 -0
- data/src/ast.c +410 -153
- data/src/lexer.c +1392 -1313
- data/src/lexer.re +3 -0
- data/src/lexstate.c +58 -37
- data/src/location.c +8 -48
- data/src/parser.c +977 -516
- data/src/string.c +0 -48
- data/src/util/rbs_allocator.c +89 -71
- data/src/util/rbs_assert.c +1 -1
- data/src/util/rbs_buffer.c +2 -2
- data/src/util/rbs_constant_pool.c +10 -14
- data/src/util/rbs_encoding.c +4 -8
- data/src/util/rbs_unescape.c +56 -20
- data/stdlib/bigdecimal/0/big_decimal.rbs +116 -98
- data/stdlib/bigdecimal-math/0/big_math.rbs +169 -8
- data/stdlib/cgi/0/core.rbs +9 -393
- data/stdlib/cgi/0/manifest.yaml +1 -0
- data/stdlib/cgi-escape/0/escape.rbs +171 -0
- data/stdlib/coverage/0/coverage.rbs +7 -4
- data/stdlib/date/0/date.rbs +92 -79
- data/stdlib/date/0/date_time.rbs +25 -24
- data/stdlib/delegate/0/delegator.rbs +10 -7
- data/stdlib/did_you_mean/0/did_you_mean.rbs +17 -16
- data/stdlib/digest/0/digest.rbs +110 -0
- data/stdlib/erb/0/erb.rbs +748 -347
- data/stdlib/etc/0/etc.rbs +55 -50
- data/stdlib/fileutils/0/fileutils.rbs +158 -139
- data/stdlib/forwardable/0/forwardable.rbs +13 -10
- data/stdlib/io-console/0/io-console.rbs +2 -2
- data/stdlib/json/0/json.rbs +217 -136
- data/stdlib/monitor/0/monitor.rbs +3 -3
- data/stdlib/net-http/0/net-http.rbs +162 -134
- data/stdlib/objspace/0/objspace.rbs +17 -34
- data/stdlib/open-uri/0/open-uri.rbs +48 -8
- data/stdlib/open3/0/open3.rbs +469 -10
- data/stdlib/openssl/0/openssl.rbs +475 -357
- data/stdlib/optparse/0/optparse.rbs +26 -17
- data/stdlib/pathname/0/pathname.rbs +11 -1381
- data/stdlib/pp/0/pp.rbs +9 -8
- data/stdlib/prettyprint/0/prettyprint.rbs +7 -7
- data/stdlib/pstore/0/pstore.rbs +35 -30
- data/stdlib/psych/0/psych.rbs +65 -12
- data/stdlib/psych/0/store.rbs +2 -4
- data/stdlib/pty/0/pty.rbs +9 -6
- data/stdlib/random-formatter/0/random-formatter.rbs +277 -0
- data/stdlib/rdoc/0/code_object.rbs +2 -1
- data/stdlib/rdoc/0/parser.rbs +1 -1
- data/stdlib/rdoc/0/rdoc.rbs +1 -1
- data/stdlib/rdoc/0/store.rbs +1 -1
- data/stdlib/resolv/0/resolv.rbs +25 -68
- data/stdlib/ripper/0/ripper.rbs +22 -19
- data/stdlib/securerandom/0/manifest.yaml +2 -0
- data/stdlib/securerandom/0/securerandom.rbs +7 -20
- data/stdlib/shellwords/0/shellwords.rbs +2 -2
- data/stdlib/singleton/0/singleton.rbs +3 -0
- data/stdlib/socket/0/addrinfo.rbs +7 -7
- data/stdlib/socket/0/basic_socket.rbs +3 -3
- data/stdlib/socket/0/ip_socket.rbs +10 -8
- data/stdlib/socket/0/socket.rbs +23 -10
- data/stdlib/socket/0/tcp_server.rbs +1 -1
- data/stdlib/socket/0/tcp_socket.rbs +11 -3
- data/stdlib/socket/0/udp_socket.rbs +1 -1
- data/stdlib/socket/0/unix_server.rbs +1 -1
- data/stdlib/stringio/0/stringio.rbs +1177 -85
- data/stdlib/strscan/0/string_scanner.rbs +27 -25
- data/stdlib/tempfile/0/tempfile.rbs +25 -21
- data/stdlib/time/0/time.rbs +8 -6
- data/stdlib/timeout/0/timeout.rbs +63 -7
- data/stdlib/tsort/0/cyclic.rbs +3 -0
- data/stdlib/tsort/0/tsort.rbs +7 -6
- data/stdlib/uri/0/common.rbs +42 -20
- data/stdlib/uri/0/file.rbs +3 -3
- data/stdlib/uri/0/generic.rbs +26 -18
- data/stdlib/uri/0/http.rbs +2 -2
- data/stdlib/uri/0/ldap.rbs +2 -2
- data/stdlib/uri/0/mailto.rbs +3 -3
- data/stdlib/uri/0/rfc2396_parser.rbs +12 -12
- data/stdlib/zlib/0/deflate.rbs +4 -3
- data/stdlib/zlib/0/gzip_reader.rbs +6 -6
- data/stdlib/zlib/0/gzip_writer.rbs +14 -12
- data/stdlib/zlib/0/inflate.rbs +1 -1
- data/stdlib/zlib/0/need_dict.rbs +1 -1
- data/stdlib/zlib/0/zstream.rbs +1 -0
- metadata +50 -6
data/docs/aliases.md
ADDED
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
# Aliases
|
|
2
|
+
|
|
3
|
+
This document explains module/class aliases and type aliases.
|
|
4
|
+
|
|
5
|
+
## Module/class alias
|
|
6
|
+
|
|
7
|
+
Module/class aliases give another name to a module/class.
|
|
8
|
+
This is useful for some syntaxes that has lexical constraints.
|
|
9
|
+
|
|
10
|
+
```rbs
|
|
11
|
+
class C
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
class D = C # ::D is an alias for ::C
|
|
15
|
+
|
|
16
|
+
class E < D # ::E inherits from ::D, which is actually ::C
|
|
17
|
+
end
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
Note that module/class aliases cannot be recursive.
|
|
21
|
+
|
|
22
|
+
So, we can define a *normalization* of aliased module/class names.
|
|
23
|
+
Normalization follows the chain of alias definitions and resolves them to the original module/class defined with `module`/`class` syntax.
|
|
24
|
+
|
|
25
|
+
```rbs
|
|
26
|
+
class C
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
class D = C
|
|
30
|
+
class E = D
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
`::E` is defined as an alias, and it can be normalized to `::C`.
|
|
34
|
+
|
|
35
|
+
## Type alias
|
|
36
|
+
|
|
37
|
+
The biggest difference from module/class alias is that type alias can be recursive.
|
|
38
|
+
|
|
39
|
+
```rbs
|
|
40
|
+
# cons_cell type is defined recursively
|
|
41
|
+
type cons_cell = nil
|
|
42
|
+
| [Integer, cons_cell]
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
This means type aliases *cannot be* normalized generally.
|
|
46
|
+
So, we provide another operation for type alias, `DefinitionBuilder#expand_alias` and its family.
|
|
47
|
+
It substitutes with the immediate right hand side of a type alias.
|
|
48
|
+
|
|
49
|
+
```
|
|
50
|
+
cons_cell ===> nil | [Integer, cons_cell] (expand 1 step)
|
|
51
|
+
===> nil | [Integer, nil | [Integer, cons_cell]] (expand 2 steps)
|
|
52
|
+
===> ... (expand will go infinitely)
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
Note that the namespace of a type alias *can be* normalized, because they are module names.
|
|
56
|
+
|
|
57
|
+
```rbs
|
|
58
|
+
module M
|
|
59
|
+
type t = String
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
module N = M
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
With the type definition above, a type `::N::t` can be normalized to `::M::t`.
|
|
66
|
+
And then it can be expanded to `::String`.
|
|
67
|
+
|
|
68
|
+
> [!NOTE]
|
|
69
|
+
> This is something like an *unfold* operation in type theory.
|
|
70
|
+
|
|
71
|
+
## Type name resolution
|
|
72
|
+
|
|
73
|
+
Type name resolution in RBS usually rewrites *relative* type names to *absolute* type names.
|
|
74
|
+
`Environment#resolve_type_names` converts all type names in the RBS type definitions, and returns a new `Environment` object.
|
|
75
|
+
|
|
76
|
+
It also *normalizes* modules names in type names.
|
|
77
|
+
|
|
78
|
+
- If the type name can be resolved and normalized successfully, the AST has *absolute* type names.
|
|
79
|
+
- If the type name resolution/normalization fails, the AST has *relative* type names.
|
data/docs/collection.md
CHANGED
|
@@ -159,9 +159,9 @@ For example:
|
|
|
159
159
|
# manifest.yaml
|
|
160
160
|
|
|
161
161
|
dependencies:
|
|
162
|
-
# If your gem depends on
|
|
162
|
+
# If your gem depends on logger but the gemspec doesn't include logger,
|
|
163
163
|
# you need to write the following.
|
|
164
|
-
- name:
|
|
164
|
+
- name: logger
|
|
165
165
|
```
|
|
166
166
|
|
|
167
167
|
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`.
|
|
@@ -189,4 +189,4 @@ If the gem's RBS is included in the gem package, put it as `sig/manifest.yaml`.
|
|
|
189
189
|
## How it works
|
|
190
190
|
|
|
191
191
|
`rbs collection` is integrated with Bundler.
|
|
192
|
-
`rbs collection install` command generates `
|
|
192
|
+
`rbs collection install` command generates `rbs_collection.lock.yaml` from `rbs_collection.yaml` and `Gemfile.lock`. It uses `Gemfile.lock` to detects dependencies.
|
data/docs/config.md
ADDED
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
# config.yml
|
|
2
|
+
|
|
3
|
+
`config.yml` is the definition of data structure for parser results -- AST.
|
|
4
|
+
|
|
5
|
+
It defines the data structure for the parser implementation in C and Rust `node` modules.
|
|
6
|
+
|
|
7
|
+
## C parser code
|
|
8
|
+
|
|
9
|
+
```sh
|
|
10
|
+
$ rake templates
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
Our C parser consists of two components:
|
|
14
|
+
|
|
15
|
+
1. Pure C Parser
|
|
16
|
+
2. Translator from the pure C AST to Ruby object
|
|
17
|
+
|
|
18
|
+
`config.yml` defines the AST for pure C parser in `ast.h`/`ast.c` and translator from the C AST to Ruby objects in `ast_translation.h`/`ast_translation.c`.
|
|
19
|
+
|
|
20
|
+
## `ruby-rbs` crate
|
|
21
|
+
|
|
22
|
+
```sh
|
|
23
|
+
$ cd rust; cargo build
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
The `build.rs` in `ruby-rbs` crate defines the data structure derived from `config.yml` definitions under `node` module.
|
|
27
|
+
|
|
28
|
+
## nodes
|
|
29
|
+
|
|
30
|
+
`nodes` defines *node* data types in C or Rust.
|
|
31
|
+
|
|
32
|
+
```yaml
|
|
33
|
+
nodes:
|
|
34
|
+
- name: RBS::AST::Declarations::Class
|
|
35
|
+
rust_name: ClassNode
|
|
36
|
+
fields:
|
|
37
|
+
- name: name
|
|
38
|
+
c_type: rbs_type_name
|
|
39
|
+
- name: type_params
|
|
40
|
+
c_type: rbs_node_list
|
|
41
|
+
- name: super_class
|
|
42
|
+
c_type: rbs_ast_declarations_class_super
|
|
43
|
+
optional: true # NULL when no superclass (e.g., `class Foo end` vs `class Foo < Bar end`)
|
|
44
|
+
- name: members
|
|
45
|
+
c_type: rbs_node_list
|
|
46
|
+
- name: annotations
|
|
47
|
+
c_type: rbs_node_list
|
|
48
|
+
- name: comment
|
|
49
|
+
c_type: rbs_ast_comment
|
|
50
|
+
optional: true # NULL when no comment precedes the declaration
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
This defines `rbs_ast_declarations_class` struct so that the parser constructs the AST using the structs.
|
|
54
|
+
|
|
55
|
+
```c
|
|
56
|
+
typedef struct rbs_ast_declarations_class {
|
|
57
|
+
rbs_node_t base;
|
|
58
|
+
|
|
59
|
+
struct rbs_type_name *name;
|
|
60
|
+
struct rbs_node_list *type_params;
|
|
61
|
+
struct rbs_ast_declarations_class_super *super_class; /* Optional */
|
|
62
|
+
struct rbs_node_list *members;
|
|
63
|
+
struct rbs_node_list *annotations;
|
|
64
|
+
struct rbs_ast_comment *comment; /* Optional */
|
|
65
|
+
|
|
66
|
+
rbs_location_range keyword_range; /* Required */
|
|
67
|
+
rbs_location_range name_range; /* Required */
|
|
68
|
+
rbs_location_range end_range; /* Required */
|
|
69
|
+
rbs_location_range type_params_range; /* Optional */
|
|
70
|
+
rbs_location_range lt_range; /* Optional */
|
|
71
|
+
} rbs_ast_declarations_class_t;
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
The `rbs_ast_declarations_class` struct is a pure C AST, and `ast_translation.c` defines translation into a Ruby object of `RBS::AST::Declarations::Class` class.
|
|
75
|
+
|
|
76
|
+
```c
|
|
77
|
+
case RBS_AST_DECLARATIONS_CLASS: {
|
|
78
|
+
rbs_ast_declarations_class_t *node = (rbs_ast_declarations_class_t *) instance;
|
|
79
|
+
|
|
80
|
+
VALUE h = rb_hash_new();
|
|
81
|
+
VALUE location = rbs_location_range_to_ruby_location(ctx, node->base.location);
|
|
82
|
+
rbs_loc *loc = rbs_check_location(location);
|
|
83
|
+
rbs_loc_legacy_alloc_children(loc, 5);
|
|
84
|
+
rbs_loc_legacy_add_required_child(loc, rb_intern("keyword"), (rbs_loc_range) { .start = node->keyword_range.start_char, .end = node->keyword_range.end_char });
|
|
85
|
+
rbs_loc_legacy_add_required_child(loc, rb_intern("name"), (rbs_loc_range) { .start = node->name_range.start_char, .end = node->name_range.end_char });
|
|
86
|
+
rbs_loc_legacy_add_required_child(loc, rb_intern("end"), (rbs_loc_range) { .start = node->end_range.start_char, .end = node->end_range.end_char });
|
|
87
|
+
rbs_loc_legacy_add_optional_child(loc, rb_intern("type_params"), (rbs_loc_range) { .start = node->type_params_range.start_char, .end = node->type_params_range.end_char });
|
|
88
|
+
rbs_loc_legacy_add_optional_child(loc, rb_intern("lt"), (rbs_loc_range) { .start = node->lt_range.start_char, .end = node->lt_range.end_char });
|
|
89
|
+
rb_hash_aset(h, ID2SYM(rb_intern("location")), location);
|
|
90
|
+
rb_hash_aset(h, ID2SYM(rb_intern("name")), rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->name)); // rbs_type_name
|
|
91
|
+
rb_hash_aset(h, ID2SYM(rb_intern("type_params")), rbs_node_list_to_ruby_array(ctx, node->type_params));
|
|
92
|
+
rb_hash_aset(h, ID2SYM(rb_intern("super_class")), rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->super_class)); // rbs_ast_declarations_class_super
|
|
93
|
+
rb_hash_aset(h, ID2SYM(rb_intern("members")), rbs_node_list_to_ruby_array(ctx, node->members));
|
|
94
|
+
rb_hash_aset(h, ID2SYM(rb_intern("annotations")), rbs_node_list_to_ruby_array(ctx, node->annotations));
|
|
95
|
+
rb_hash_aset(h, ID2SYM(rb_intern("comment")), rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->comment)); // rbs_ast_comment
|
|
96
|
+
|
|
97
|
+
rb_funcall(
|
|
98
|
+
RBS_AST_TypeParam,
|
|
99
|
+
rb_intern("resolve_variables"),
|
|
100
|
+
1,
|
|
101
|
+
rb_hash_lookup(h, ID2SYM(rb_intern("type_params")))
|
|
102
|
+
);
|
|
103
|
+
return CLASS_NEW_INSTANCE(
|
|
104
|
+
RBS_AST_Declarations_Class,
|
|
105
|
+
1,
|
|
106
|
+
&h
|
|
107
|
+
);
|
|
108
|
+
}
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
## enums
|
|
112
|
+
|
|
113
|
+
`enums` defines *enum* data types in C or Rust.
|
|
114
|
+
|
|
115
|
+
```yaml
|
|
116
|
+
enums:
|
|
117
|
+
attribute_visibility:
|
|
118
|
+
optional: true
|
|
119
|
+
symbols:
|
|
120
|
+
- unspecified
|
|
121
|
+
- public
|
|
122
|
+
- private
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
For example, the `attribute_visibility` enum is a data type for `visibility` attribute of `attr_reader`, `attr_writer`, and `attr_accessor` definitions.
|
|
126
|
+
The `visibility` attribute can be one of `unspecified`, `public`, and `private`.
|
|
127
|
+
|
|
128
|
+
### Symbol enums
|
|
129
|
+
|
|
130
|
+
Enum definition with `symbols:` attribute defines *enum* data that is mapped to Ruby symbols.
|
|
131
|
+
|
|
132
|
+
```yaml
|
|
133
|
+
enums:
|
|
134
|
+
attribute_visibility:
|
|
135
|
+
optional: true
|
|
136
|
+
symbols:
|
|
137
|
+
- unspecified
|
|
138
|
+
- public
|
|
139
|
+
- private
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
It defines an `enum` in C AST definition.
|
|
143
|
+
|
|
144
|
+
```c
|
|
145
|
+
enum RBS_ATTRIBUTE_VISIBILITY_TAG {
|
|
146
|
+
RBS_ATTRIBUTE_VISIBILITY_TAG_UNSPECIFIED,
|
|
147
|
+
RBS_ATTRIBUTE_VISIBILITY_TAG_PUBLIC,
|
|
148
|
+
RBS_ATTRIBUTE_VISIBILITY_TAG_PRIVATE,
|
|
149
|
+
};
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
The C extension also defines a translation:
|
|
153
|
+
|
|
154
|
+
```c
|
|
155
|
+
VALUE rbs_attribute_visibility_to_ruby(enum rbs_attribute_visibility value) {
|
|
156
|
+
switch (value) {
|
|
157
|
+
case RBS_ATTRIBUTE_VISIBILITY_UNSPECIFIED:
|
|
158
|
+
return Qnil;
|
|
159
|
+
case RBS_ATTRIBUTE_VISIBILITY_PUBLIC:
|
|
160
|
+
return rb_id2sym(rb_intern("public"));
|
|
161
|
+
case RBS_ATTRIBUTE_VISIBILITY_PRIVATE:
|
|
162
|
+
return rb_id2sym(rb_intern("private"));
|
|
163
|
+
default:
|
|
164
|
+
rb_fatal("unknown enum rbs_attribute_visibility value: %d", value);
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
`RBS_ATTRIBUTE_VISIBILITY_PUBLIC` and `RBS_ATTRIBUTE_VISIBILITY_PRIVATE` are translated to Ruby symbols `:public` and `:private` respectively.
|
|
170
|
+
|
|
171
|
+
Note that the first `RBS_ATTRIBUTE_VISIBILITY_UNSPECIFIED` is translated to `nil` in Ruby. This is specified by the `optional: true` attribute in YAML. When `optional: true` is set, the first enum value is translated to `nil`.
|
data/docs/encoding.md
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
# RBS File Encoding
|
|
2
|
+
|
|
3
|
+
## Best Practice
|
|
4
|
+
|
|
5
|
+
**Use UTF-8** for both file encoding and your system locale.
|
|
6
|
+
|
|
7
|
+
## Supported Encodings
|
|
8
|
+
|
|
9
|
+
RBS parser supports ASCII-compatible encodings (similar to Ruby's script encoding support).
|
|
10
|
+
|
|
11
|
+
**Examples**: UTF-8, US-ASCII, Shift JIS, EUC-JP, ...
|
|
12
|
+
|
|
13
|
+
## Unicode Codepoint Symbols
|
|
14
|
+
|
|
15
|
+
String literal types in RBS can contain Unicode codepoint escape sequences (`\uXXXX`).
|
|
16
|
+
|
|
17
|
+
When the file encoding is UTF-8, the parser translates Unicode codepoint symbols:
|
|
18
|
+
|
|
19
|
+
```rbs
|
|
20
|
+
# In UTF-8 encoded files
|
|
21
|
+
|
|
22
|
+
type t = "\u0123" # Translated to the actual Unicode character ģ
|
|
23
|
+
type s = "\u3042" # Translated to the actual Unicode character あ
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
When the file encoding is not UTF-8, Unicode escape sequences are interpreted literally as the string `\uXXXX`:
|
|
27
|
+
|
|
28
|
+
```rbs
|
|
29
|
+
# In non-UTF-8 encoded files
|
|
30
|
+
|
|
31
|
+
type t = "\u0123" # Remains as the literal string "\u0123"
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## Implementation
|
|
35
|
+
|
|
36
|
+
RBS gem currently doesn't do anything for file encoding. It relies on Ruby's encoding handling, specifically `Encoding.default_external` and `Encoding.default_internal`.
|
|
37
|
+
|
|
38
|
+
`Encoding.default_external` is the encoding Ruby assumes when it reads external resources like files. The Ruby interpreter sets it based on the locale. `Encoding.default_internal` is the encoding Ruby converts the external resources to. The default is `nil` (no conversion.)
|
|
39
|
+
|
|
40
|
+
When your locale is set to use `UTF-8` encoding, `default_external` is `Encoding::UTF_8`. So the RBS file content read from the disk will have UTF-8 encoding.
|
|
41
|
+
|
|
42
|
+
### Parsing non UTF-8 RBS source text
|
|
43
|
+
|
|
44
|
+
If you want to work with another encoding, ensure the source string has ASCII compatible encoding.
|
|
45
|
+
|
|
46
|
+
```ruby
|
|
47
|
+
source = '"日本語"'
|
|
48
|
+
RBS::Parser.parse_type(source.encode(Encoding::EUC_JP)) # => Parses successfully
|
|
49
|
+
RBS::Parser.parse_type(source.encode(Encoding::UTF_32)) # => Returns `nil` since UTF-32 is not ASCII compatible
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
### Specifying file encoding
|
|
53
|
+
|
|
54
|
+
Currently, RBS doesn't support specifying file encoding directly.
|
|
55
|
+
|
|
56
|
+
You can use `Encoding.default_external` while the gem loads RBS files from the storage.
|