rbs 0.15.0 → 0.16.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/ruby.yml +7 -3
- data/CHANGELOG.md +7 -1
- data/Gemfile +1 -0
- data/Rakefile +8 -1
- data/Steepfile +0 -1
- data/bin/test_runner.rb +15 -1
- data/{stdlib/builtin → core}/array.rbs +0 -0
- data/{stdlib/builtin → core}/basic_object.rbs +0 -0
- data/{stdlib/builtin → core}/binding.rbs +0 -0
- data/{stdlib/builtin → core}/builtin.rbs +0 -0
- data/{stdlib/builtin → core}/class.rbs +0 -0
- data/{stdlib/builtin → core}/comparable.rbs +0 -0
- data/{stdlib/builtin → core}/complex.rbs +0 -0
- data/{stdlib/builtin → core}/constants.rbs +0 -0
- data/{stdlib/builtin → core}/data.rbs +0 -0
- data/{stdlib/builtin → core}/deprecated.rbs +0 -0
- data/{stdlib/builtin → core}/dir.rbs +0 -0
- data/{stdlib/builtin → core}/encoding.rbs +0 -0
- data/{stdlib/builtin → core}/enumerable.rbs +0 -0
- data/{stdlib/builtin → core}/enumerator.rbs +0 -0
- data/{stdlib/builtin → core}/errno.rbs +0 -0
- data/{stdlib/builtin → core}/errors.rbs +0 -0
- data/{stdlib/builtin → core}/exception.rbs +0 -0
- data/{stdlib/builtin → core}/false_class.rbs +0 -0
- data/{stdlib/builtin → core}/fiber.rbs +0 -0
- data/{stdlib/builtin → core}/fiber_error.rbs +0 -0
- data/{stdlib/builtin → core}/file.rbs +0 -0
- data/{stdlib/builtin → core}/file_test.rbs +0 -0
- data/{stdlib/builtin → core}/float.rbs +0 -0
- data/{stdlib/builtin → core}/gc.rbs +0 -0
- data/{stdlib/builtin → core}/hash.rbs +0 -0
- data/{stdlib/builtin → core}/integer.rbs +0 -0
- data/{stdlib/builtin → core}/io.rbs +0 -0
- data/{stdlib/builtin → core}/kernel.rbs +0 -0
- data/{stdlib/builtin → core}/marshal.rbs +0 -0
- data/{stdlib/builtin → core}/match_data.rbs +0 -0
- data/{stdlib/builtin → core}/math.rbs +0 -0
- data/{stdlib/builtin → core}/method.rbs +0 -0
- data/{stdlib/builtin → core}/module.rbs +0 -0
- data/{stdlib/builtin → core}/nil_class.rbs +0 -0
- data/{stdlib/builtin → core}/numeric.rbs +0 -0
- data/{stdlib/builtin → core}/object.rbs +0 -0
- data/{stdlib/builtin → core}/proc.rbs +0 -0
- data/{stdlib/builtin → core}/process.rbs +0 -0
- data/{stdlib/builtin → core}/random.rbs +0 -0
- data/{stdlib/builtin → core}/range.rbs +0 -0
- data/{stdlib/builtin → core}/rational.rbs +0 -0
- data/{stdlib/builtin → core}/rb_config.rbs +0 -0
- data/{stdlib/builtin → core}/regexp.rbs +0 -0
- data/{stdlib/builtin → core}/ruby_vm.rbs +0 -0
- data/{stdlib/builtin → core}/signal.rbs +0 -0
- data/{stdlib/builtin → core}/string.rbs +0 -0
- data/{stdlib/builtin → core}/string_io.rbs +0 -0
- data/{stdlib/builtin → core}/struct.rbs +0 -0
- data/{stdlib/builtin → core}/symbol.rbs +0 -0
- data/{stdlib/builtin → core}/thread.rbs +0 -0
- data/{stdlib/builtin → core}/thread_group.rbs +0 -0
- data/{stdlib/builtin → core}/time.rbs +0 -0
- data/{stdlib/builtin → core}/trace_point.rbs +0 -0
- data/{stdlib/builtin → core}/true_class.rbs +0 -0
- data/{stdlib/builtin → core}/unbound_method.rbs +0 -0
- data/{stdlib/builtin → core}/warning.rbs +0 -0
- data/docs/repo.md +125 -0
- data/lib/rbs.rb +1 -0
- data/lib/rbs/cli.rb +105 -103
- data/lib/rbs/environment_loader.rb +79 -105
- data/lib/rbs/repository.rb +121 -0
- data/lib/rbs/test/setup.rb +5 -3
- data/lib/rbs/type_name.rb +2 -1
- data/lib/rbs/vendorer.rb +38 -16
- data/lib/rbs/version.rb +1 -1
- data/sig/cli.rbs +58 -0
- data/sig/definition_builder.rbs +2 -0
- data/sig/environment_loader.rbs +92 -46
- data/sig/polyfill.rbs +42 -0
- data/sig/rbs.rbs +8 -0
- data/sig/repository.rbs +79 -0
- data/sig/vendorer.rbs +44 -0
- data/stdlib/abbrev/{abbrev.rbs → 0/abbrev.rbs} +0 -0
- data/stdlib/base64/{base64.rbs → 0/base64.rbs} +0 -0
- data/stdlib/benchmark/{benchmark.rbs → 0/benchmark.rbs} +0 -0
- data/stdlib/{bigdecimal/math → bigdecimal-math/0}/big_math.rbs +0 -0
- data/stdlib/bigdecimal/{big_decimal.rbs → 0/big_decimal.rbs} +0 -0
- data/stdlib/coverage/{coverage.rbs → 0/coverage.rbs} +0 -0
- data/stdlib/csv/{csv.rbs → 0/csv.rbs} +0 -0
- data/stdlib/date/{date.rbs → 0/date.rbs} +0 -0
- data/stdlib/date/{date_time.rbs → 0/date_time.rbs} +0 -0
- data/stdlib/dbm/0/dbm.rbs +277 -0
- data/stdlib/erb/{erb.rbs → 0/erb.rbs} +0 -0
- data/stdlib/fiber/{fiber.rbs → 0/fiber.rbs} +0 -0
- data/stdlib/find/{find.rbs → 0/find.rbs} +0 -0
- data/stdlib/forwardable/{forwardable.rbs → 0/forwardable.rbs} +0 -0
- data/stdlib/ipaddr/{ipaddr.rbs → 0/ipaddr.rbs} +0 -0
- data/stdlib/json/{json.rbs → 0/json.rbs} +0 -0
- data/stdlib/logger/{formatter.rbs → 0/formatter.rbs} +0 -0
- data/stdlib/logger/{log_device.rbs → 0/log_device.rbs} +0 -0
- data/stdlib/logger/{logger.rbs → 0/logger.rbs} +0 -0
- data/stdlib/logger/{period.rbs → 0/period.rbs} +0 -0
- data/stdlib/logger/{severity.rbs → 0/severity.rbs} +0 -0
- data/stdlib/mutex_m/{mutex_m.rbs → 0/mutex_m.rbs} +0 -0
- data/stdlib/pathname/{pathname.rbs → 0/pathname.rbs} +0 -0
- data/stdlib/prime/{integer-extension.rbs → 0/integer-extension.rbs} +0 -0
- data/stdlib/prime/{prime.rbs → 0/prime.rbs} +0 -0
- data/stdlib/pstore/{pstore.rbs → 0/pstore.rbs} +0 -0
- data/stdlib/pty/{pty.rbs → 0/pty.rbs} +0 -0
- data/stdlib/securerandom/{securerandom.rbs → 0/securerandom.rbs} +0 -0
- data/stdlib/set/{set.rbs → 0/set.rbs} +0 -0
- data/stdlib/tmpdir/{tmpdir.rbs → 0/tmpdir.rbs} +0 -0
- data/stdlib/uri/{file.rbs → 0/file.rbs} +0 -0
- data/stdlib/uri/{generic.rbs → 0/generic.rbs} +0 -0
- data/stdlib/uri/{http.rbs → 0/http.rbs} +0 -0
- data/stdlib/uri/{https.rbs → 0/https.rbs} +0 -0
- data/stdlib/uri/{ldap.rbs → 0/ldap.rbs} +0 -0
- data/stdlib/uri/{ldaps.rbs → 0/ldaps.rbs} +0 -0
- data/stdlib/zlib/{zlib.rbs → 0/zlib.rbs} +0 -0
- metadata +100 -94
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5062396fb965f4d6f07ceee4f6b82ef22a12c20897d82c6615d6765d5bf43b7f
|
4
|
+
data.tar.gz: 8b30dd2d71e12d56501bafc2ab4ca1d604befbc3ef797f02234b6d6acc95ac71
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ec6b6090f0a93cbfbe2f4ffe5f5bbce253425f3f85a55dcabec2943f724a81c637c441820236aa1dcbff6104d1fe7d215e4cb38ac76c5f827677167e437761f5
|
7
|
+
data.tar.gz: 301d1c5a305dce97dfdd6d89c39a4deafcedc405535b13b1846b3d03af83a87747cc44ade7a0148b96af7d07d7a53b4eb7c8954344ae11d574f69ca81c3eb7a8
|
data/.github/workflows/ruby.yml
CHANGED
@@ -13,8 +13,8 @@ jobs:
|
|
13
13
|
matrix:
|
14
14
|
container_tag:
|
15
15
|
- master-nightly-bionic
|
16
|
-
- 2.6
|
17
|
-
- 2.7
|
16
|
+
- 2.6-bionic
|
17
|
+
- 2.7-bionic
|
18
18
|
job:
|
19
19
|
- test
|
20
20
|
- stdlib_test
|
@@ -23,6 +23,10 @@ jobs:
|
|
23
23
|
image: rubylang/ruby:${{ matrix.container_tag }}
|
24
24
|
steps:
|
25
25
|
- uses: actions/checkout@v1
|
26
|
+
- name: Install dependencies
|
27
|
+
run: |
|
28
|
+
apt-get update
|
29
|
+
apt-get install -y libdb-dev
|
26
30
|
- name: Install
|
27
31
|
run: |
|
28
32
|
ruby -v
|
@@ -31,4 +35,4 @@ jobs:
|
|
31
35
|
- name: Run test
|
32
36
|
run: |
|
33
37
|
bundle exec rake ${{ matrix.job }}
|
34
|
-
if: "!(matrix.job == 'stdlib_test' && contains(matrix.container_tag, '2.6
|
38
|
+
if: "!(matrix.job == 'stdlib_test' && contains(matrix.container_tag, '2.6'))"
|
data/CHANGELOG.md
CHANGED
@@ -2,7 +2,13 @@
|
|
2
2
|
|
3
3
|
## master
|
4
4
|
|
5
|
-
## 0.
|
5
|
+
## 0.16.0 (2020-11-05)
|
6
|
+
|
7
|
+
* Signature update for `DBM` ([#441](https://github.com/ruby/rbs/pull/441))
|
8
|
+
* RBS repository ([#405](https://github.com/ruby/rbs/pull/405))
|
9
|
+
* Support `alias` in `rbs prototype rb` ([#457](https://github.com/ruby/rbs/pull/457))
|
10
|
+
|
11
|
+
## 0.15.0 (2020-11-02)
|
6
12
|
|
7
13
|
* Signature updates for `Kernel`, `PStore`, `Enumerable`, and `Array` ([#450](https://github.com/ruby/rbs/pull/450), [#443](https://github.com/ruby/rbs/pull/443), [#438](https://github.com/ruby/rbs/pull/438), [#437](https://github.com/ruby/rbs/pull/437), [#433](https://github.com/ruby/rbs/pull/433), [#432](https://github.com/ruby/rbs/pull/432))
|
8
14
|
* Add helper interfaces ([#434](https://github.com/ruby/rbs/pull/434), [#428](https://github.com/ruby/rbs/pull/428))
|
data/Gemfile
CHANGED
data/Rakefile
CHANGED
@@ -29,7 +29,14 @@ task :validate => :parser do
|
|
29
29
|
|
30
30
|
FileList["stdlib/*"].each do |path|
|
31
31
|
next if path =~ %r{stdlib/builtin}
|
32
|
-
|
32
|
+
|
33
|
+
lib = [File.basename(path).to_s]
|
34
|
+
|
35
|
+
if lib == ["bigdecimal-math"]
|
36
|
+
lib << "bigdecimal"
|
37
|
+
end
|
38
|
+
|
39
|
+
sh "#{ruby} #{rbs} #{lib.map {|l| "-r #{l}"}.join(" ")} validate --silent"
|
33
40
|
end
|
34
41
|
end
|
35
42
|
|
data/Steepfile
CHANGED
data/bin/test_runner.rb
CHANGED
@@ -2,6 +2,8 @@
|
|
2
2
|
|
3
3
|
$LOAD_PATH << File.join(__dir__, "../lib")
|
4
4
|
|
5
|
+
require "set"
|
6
|
+
|
5
7
|
IS_RUBY_27 = Gem::Version.new(RUBY_VERSION).yield_self do |ruby_version|
|
6
8
|
Gem::Version.new('2.7.0') <= ruby_version &&
|
7
9
|
ruby_version <= Gem::Version.new('2.8.0')
|
@@ -11,6 +13,18 @@ unless IS_RUBY_27
|
|
11
13
|
STDERR.puts "⚠️⚠️⚠️⚠️ stdlib test assumes Ruby 2.7 but RUBY_VERSION==#{RUBY_VERSION} ⚠️⚠️⚠️⚠️"
|
12
14
|
end
|
13
15
|
|
16
|
+
KNOWN_FAILS = %w(dbm).map do |lib|
|
17
|
+
/cannot load such file -- #{lib}/
|
18
|
+
end
|
19
|
+
|
14
20
|
ARGV.each do |arg|
|
15
|
-
|
21
|
+
begin
|
22
|
+
load arg
|
23
|
+
rescue LoadError => exn
|
24
|
+
if KNOWN_FAILS.any? {|pat| pat =~ exn.message }
|
25
|
+
STDERR.puts "Loading #{arg} failed, ignoring it: #{exn.inspect}"
|
26
|
+
else
|
27
|
+
raise
|
28
|
+
end
|
29
|
+
end
|
16
30
|
end
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
data/docs/repo.md
ADDED
@@ -0,0 +1,125 @@
|
|
1
|
+
# Third-party RBS Repository
|
2
|
+
|
3
|
+
This is the spec of the directory structure for RBS files of gems without RBS files. It allows distributing RBS type definitions of gems separately from the `.gemspec` files so that the Ruby developers can type check their Ruby programs even if the dependent gems don't ship with their type definitions.
|
4
|
+
|
5
|
+
The spec includes:
|
6
|
+
|
7
|
+
* The directory structure, and
|
8
|
+
* The RBS file lookup rules given _repository root_, gem name, and version.
|
9
|
+
|
10
|
+
## Motivating Example
|
11
|
+
|
12
|
+
Assume there is a rubygem called `bug-free-doodle` and our application depends on the library. We are trying to type check our application and we need RBS files of `bug-free-doodle`. The problem is that the `bug-free-doodle` gem doesn't ship with RBS files. The type checkers cannot resolve the type of constant `Bug::Free::Doodle` and its methods.
|
13
|
+
|
14
|
+
One workaround is to add type definitions of the library in the application signatures.
|
15
|
+
|
16
|
+
```
|
17
|
+
# sig/polyfill/bug-free-doodle.rbs
|
18
|
+
|
19
|
+
module Bug
|
20
|
+
module Free
|
21
|
+
class Doodle
|
22
|
+
attr_reader name: Symbol
|
23
|
+
attr_reader strokes: Array[Stroke]
|
24
|
+
|
25
|
+
def initialize: (name: Symbol) -> void
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
```
|
30
|
+
|
31
|
+
You may want to distribute the RBS file to anyone who needs it. Which version do we support? Testing it? How to load the RBS files? This is the spec you need!
|
32
|
+
|
33
|
+
### Third-party RBS repository
|
34
|
+
|
35
|
+
Make a directory (or you may want to `git init`) to put your _third party RBSs_.
|
36
|
+
|
37
|
+
```sh
|
38
|
+
$ make my-rbs # Or you may want a git repository: git init my-rbs
|
39
|
+
$ cd my-rbs
|
40
|
+
$ mkdir gems
|
41
|
+
```
|
42
|
+
|
43
|
+
We call the `my-rbs/gems` directory _repository root_. Note that it is different from the root of the git repository. The RBS repository root is the directory that contains directories of gem names.
|
44
|
+
|
45
|
+
Make a directory for the gem and the version.
|
46
|
+
|
47
|
+
```sh
|
48
|
+
$ mkdir gems/bug-free-doodle
|
49
|
+
$ mkdir gems/bug-free-doodle/1.2.3
|
50
|
+
```
|
51
|
+
|
52
|
+
And copy the RBS file in it.
|
53
|
+
|
54
|
+
```sh
|
55
|
+
$ cp your-app/sig/polyfill/bug-free-doodle.rbs gems/bug-free-doodle/1.2.3
|
56
|
+
```
|
57
|
+
|
58
|
+
### Reading Third-party RBS
|
59
|
+
|
60
|
+
`rbs` command accepts `--repo` option which points to a _repository root_. You can specify `-r` option to let the command know which gems you want to load.
|
61
|
+
|
62
|
+
In this case, the _repository root_ is `./gems` and we are trying to load `bug-free-doodle` gem.
|
63
|
+
|
64
|
+
```sh
|
65
|
+
$ rbs --repo=gems -r bug-free-doodle paths
|
66
|
+
```
|
67
|
+
|
68
|
+
The `-r` option also accepts gem name with version.
|
69
|
+
|
70
|
+
```sh
|
71
|
+
$ rbs --repo=gems -r bug-free-doodle:1.2.3 paths
|
72
|
+
```
|
73
|
+
|
74
|
+
Note that the version resolution is not compatible with semantic versioning. It is optimistic. It resolves to some version unless no version for the gem is available.
|
75
|
+
|
76
|
+
## Directory Structure
|
77
|
+
|
78
|
+
There are directories for each gem under _repository root_. We also have directories for each version of each gem.
|
79
|
+
|
80
|
+
- $REPO_ROOT/bug-free-doodle/0.2.0
|
81
|
+
- $REPO_ROOT/bug-free-doodle/1.0
|
82
|
+
- $REPO_ROOT/bug-free-doodle/1.2.3
|
83
|
+
- $REPO_ROOT/bug-free-doodle/2.0
|
84
|
+
|
85
|
+
Note that we assume that we have git repositories for each RBS repository, and we have a directory at the root of the git repository for _repository root_.
|
86
|
+
|
87
|
+
So the git repository structure would be something like the following:
|
88
|
+
|
89
|
+
- /Gemfile
|
90
|
+
- /Gemfile.lock
|
91
|
+
- /README.md
|
92
|
+
- /LICENSE
|
93
|
+
- /gems/bug-free-doodle/1.2.3/bug-free-doodle.rbs
|
94
|
+
|
95
|
+
You should have `Gemfile` and `Gemfile.lock` to manage dependencies, `README.md` and `LICENSE` to documentation, and `gems` directory as _repository root_.
|
96
|
+
|
97
|
+
(We call _repository root_ `gems` in this doc, but the name can be anything you like.)
|
98
|
+
|
99
|
+
## Version Resolution
|
100
|
+
|
101
|
+
The version resolution in RBS is optimistic. We don't block loading RBS files for _incompatible_ version in terms of semantic versioning.
|
102
|
+
|
103
|
+
It tries to resolve version _n_ as follows:
|
104
|
+
|
105
|
+
1. It resolves to _m_ such that _m_ is the latest version available and _m_ <= _n_ holds.
|
106
|
+
2. It resolves to the oldest version when rule 1 cannot find version _m_.
|
107
|
+
|
108
|
+
If two versions, `0.4.0`, `1.0.0` are available for a gem:
|
109
|
+
|
110
|
+
| Requested version | Resolved version |
|
111
|
+
|-------------------|------------------|
|
112
|
+
| `0.3.0` | `0.4.0` (Rule 2) |
|
113
|
+
| `0.4.0` | `0.4.0` |
|
114
|
+
| `0.5.0` | `0.4.0` |
|
115
|
+
| `1.0.0` | `1.0.0` |
|
116
|
+
| `2.0.0` | `1.0.0` |
|
117
|
+
|
118
|
+
This is not compatible with the concept of semantic versioning. We don't want to block users to load RBS even for incompatible versions of gems.
|
119
|
+
|
120
|
+
We believe this makes more sense because:
|
121
|
+
|
122
|
+
* Using (potentially) incompatible type definitions are better than no type definition.
|
123
|
+
* Users can stop loading RBS if incompatibility causes an issue and falling back to hand-written polyfills.
|
124
|
+
|
125
|
+
|
data/lib/rbs.rb
CHANGED
data/lib/rbs/cli.rb
CHANGED
@@ -5,29 +5,59 @@ require "shellwords"
|
|
5
5
|
module RBS
|
6
6
|
class CLI
|
7
7
|
class LibraryOptions
|
8
|
+
attr_accessor :core_root
|
9
|
+
attr_reader :repos
|
8
10
|
attr_reader :libs
|
9
11
|
attr_reader :dirs
|
10
|
-
attr_accessor :no_stdlib
|
11
12
|
|
12
13
|
def initialize()
|
14
|
+
@core_root = EnvironmentLoader::DEFAULT_CORE_ROOT
|
15
|
+
@repos = []
|
16
|
+
|
13
17
|
@libs = []
|
14
18
|
@dirs = []
|
15
|
-
@no_stdlib = false
|
16
19
|
end
|
17
20
|
|
18
|
-
def
|
19
|
-
|
20
|
-
|
21
|
+
def loader
|
22
|
+
repository = Repository.new(no_stdlib: core_root.nil?)
|
23
|
+
repos.each do |repo|
|
24
|
+
repository.add(Pathname(repo))
|
21
25
|
end
|
22
26
|
|
27
|
+
loader = EnvironmentLoader.new(core_root: core_root, repository: repository)
|
28
|
+
|
23
29
|
dirs.each do |dir|
|
24
30
|
loader.add(path: Pathname(dir))
|
25
31
|
end
|
26
32
|
|
27
|
-
|
33
|
+
libs.each do |lib|
|
34
|
+
name, version = lib.split(/:/, 2)
|
35
|
+
next unless name
|
36
|
+
loader.add(library: name, version: version)
|
37
|
+
end
|
28
38
|
|
29
39
|
loader
|
30
40
|
end
|
41
|
+
|
42
|
+
def setup_library_options(opts)
|
43
|
+
opts.on("-r LIBRARY", "Load RBS files of the library") do |lib|
|
44
|
+
libs << lib
|
45
|
+
end
|
46
|
+
|
47
|
+
opts.on("-I DIR", "Load RBS files from the directory") do |dir|
|
48
|
+
dirs << dir
|
49
|
+
end
|
50
|
+
|
51
|
+
opts.on("--no-stdlib", "Skip loading standard library signatures") do
|
52
|
+
self.core_root = nil
|
53
|
+
end
|
54
|
+
|
55
|
+
opts.on("--repo DIR", "Add RBS repository") do |dir|
|
56
|
+
repos << dir
|
57
|
+
end
|
58
|
+
|
59
|
+
opts
|
60
|
+
end
|
31
61
|
end
|
32
62
|
|
33
63
|
attr_reader :stdout
|
@@ -40,29 +70,14 @@ module RBS
|
|
40
70
|
|
41
71
|
COMMANDS = [:ast, :list, :ancestors, :methods, :method, :validate, :constant, :paths, :prototype, :vendor, :parse, :test]
|
42
72
|
|
43
|
-
def library_parse(opts, options:)
|
44
|
-
opts.on("-r LIBRARY", "Load RBS files of the library") do |lib|
|
45
|
-
options.libs << lib
|
46
|
-
end
|
47
|
-
|
48
|
-
opts.on("-I DIR", "Load RBS files from the directory") do |dir|
|
49
|
-
options.dirs << dir
|
50
|
-
end
|
51
|
-
|
52
|
-
opts.on("--no-stdlib", "Skip loading standard library signatures") do
|
53
|
-
options.no_stdlib = true
|
54
|
-
end
|
55
|
-
|
56
|
-
opts
|
57
|
-
end
|
58
|
-
|
59
73
|
def parse_logging_options(opts)
|
60
74
|
opts.on("--log-level LEVEL", "Specify log level (defaults to `warn`)") do |level|
|
61
75
|
RBS.logger_level = level
|
62
76
|
end
|
63
77
|
|
64
78
|
opts.on("--log-output OUTPUT", "Specify the file to output log (defaults to stderr)") do |output|
|
65
|
-
|
79
|
+
io = File.open(output, "a") or raise
|
80
|
+
RBS.logger_output = io
|
66
81
|
end
|
67
82
|
|
68
83
|
opts
|
@@ -83,7 +98,7 @@ module RBS
|
|
83
98
|
|
84
99
|
Options:
|
85
100
|
USAGE
|
86
|
-
|
101
|
+
options.setup_library_options(opts)
|
87
102
|
parse_logging_options(opts)
|
88
103
|
opts.version = RBS::VERSION
|
89
104
|
|
@@ -129,13 +144,14 @@ EOB
|
|
129
144
|
end
|
130
145
|
end
|
131
146
|
|
132
|
-
loader =
|
133
|
-
options.setup(loader)
|
147
|
+
loader = options.loader()
|
134
148
|
|
135
149
|
env = Environment.from_loader(loader).resolve_type_names
|
136
150
|
|
137
151
|
decls = env.declarations.select do |decl|
|
138
|
-
|
152
|
+
loc = decl.location or raise
|
153
|
+
# @type var name: String
|
154
|
+
name = loc.buffer.name
|
139
155
|
|
140
156
|
patterns.empty? || patterns.any? do |pat|
|
141
157
|
case pat
|
@@ -152,6 +168,7 @@ EOB
|
|
152
168
|
end
|
153
169
|
|
154
170
|
def run_list(args, options)
|
171
|
+
# @type var list: Set[:class | :module | :interface]
|
155
172
|
list = Set[]
|
156
173
|
|
157
174
|
OptionParser.new do |opts|
|
@@ -172,10 +189,9 @@ EOB
|
|
172
189
|
opts.on("--interface", "List interfaces") { list << :interface }
|
173
190
|
end.order!(args)
|
174
191
|
|
175
|
-
list.merge([:class, :module, :interface]) if list.empty?
|
192
|
+
list.merge(_ = [:class, :module, :interface]) if list.empty?
|
176
193
|
|
177
|
-
loader =
|
178
|
-
options.setup(loader)
|
194
|
+
loader = options.loader()
|
179
195
|
|
180
196
|
env = Environment.from_loader(loader).resolve_type_names
|
181
197
|
|
@@ -202,6 +218,7 @@ EOB
|
|
202
218
|
end
|
203
219
|
|
204
220
|
def run_ancestors(args, options)
|
221
|
+
# @type var kind: :instance | :singleton
|
205
222
|
kind = :instance
|
206
223
|
|
207
224
|
OptionParser.new do |opts|
|
@@ -221,13 +238,12 @@ EOU
|
|
221
238
|
opts.on("--singleton", "Ancestors of singleton of the given type_name") { kind = :singleton }
|
222
239
|
end.order!(args)
|
223
240
|
|
224
|
-
loader =
|
225
|
-
options.setup(loader)
|
241
|
+
loader = options.loader()
|
226
242
|
|
227
243
|
env = Environment.from_loader(loader).resolve_type_names
|
228
244
|
|
229
245
|
builder = DefinitionBuilder.new(env: env)
|
230
|
-
type_name =
|
246
|
+
type_name = TypeName(args[0]).absolute!
|
231
247
|
|
232
248
|
if env.class_decls.key?(type_name)
|
233
249
|
ancestors = case kind
|
@@ -235,6 +251,8 @@ EOU
|
|
235
251
|
builder.instance_ancestors(type_name)
|
236
252
|
when :singleton
|
237
253
|
builder.singleton_ancestors(type_name)
|
254
|
+
else
|
255
|
+
raise
|
238
256
|
end
|
239
257
|
|
240
258
|
ancestors.ancestors.each do |ancestor|
|
@@ -255,6 +273,7 @@ EOU
|
|
255
273
|
end
|
256
274
|
|
257
275
|
def run_methods(args, options)
|
276
|
+
# @type var kind: :instance | :singleton
|
258
277
|
kind = :instance
|
259
278
|
inherit = true
|
260
279
|
|
@@ -281,13 +300,12 @@ EOU
|
|
281
300
|
return
|
282
301
|
end
|
283
302
|
|
284
|
-
loader =
|
285
|
-
options.setup(loader)
|
303
|
+
loader = options.loader()
|
286
304
|
|
287
305
|
env = Environment.from_loader(loader).resolve_type_names
|
288
306
|
|
289
307
|
builder = DefinitionBuilder.new(env: env)
|
290
|
-
type_name =
|
308
|
+
type_name = TypeName(args[0]).absolute!
|
291
309
|
|
292
310
|
if env.class_decls.key?(type_name)
|
293
311
|
definition = case kind
|
@@ -295,6 +313,8 @@ EOU
|
|
295
313
|
builder.build_instance(type_name)
|
296
314
|
when :singleton
|
297
315
|
builder.build_singleton(type_name)
|
316
|
+
else
|
317
|
+
raise
|
298
318
|
end
|
299
319
|
|
300
320
|
definition.methods.keys.sort.each do |name|
|
@@ -309,6 +329,7 @@ EOU
|
|
309
329
|
end
|
310
330
|
|
311
331
|
def run_method(args, options)
|
332
|
+
# @type var kind: :instance | :singleton
|
312
333
|
kind = :instance
|
313
334
|
|
314
335
|
OptionParser.new do |opts|
|
@@ -333,13 +354,11 @@ EOU
|
|
333
354
|
return
|
334
355
|
end
|
335
356
|
|
336
|
-
loader =
|
337
|
-
options.setup(loader)
|
338
|
-
|
357
|
+
loader = options.loader()
|
339
358
|
env = Environment.from_loader(loader).resolve_type_names
|
340
359
|
|
341
360
|
builder = DefinitionBuilder.new(env: env)
|
342
|
-
type_name =
|
361
|
+
type_name = TypeName(args[0]).absolute!
|
343
362
|
method_name = args[1].to_sym
|
344
363
|
|
345
364
|
unless env.class_decls.key?(type_name)
|
@@ -352,6 +371,8 @@ EOU
|
|
352
371
|
builder.build_instance(type_name)
|
353
372
|
when :singleton
|
354
373
|
builder.build_singleton(type_name)
|
374
|
+
else
|
375
|
+
raise
|
355
376
|
end
|
356
377
|
|
357
378
|
method = definition.methods[method_name]
|
@@ -391,10 +412,7 @@ EOU
|
|
391
412
|
end
|
392
413
|
end.parse!(args)
|
393
414
|
|
394
|
-
loader =
|
395
|
-
|
396
|
-
options.setup(loader)
|
397
|
-
|
415
|
+
loader = options.loader()
|
398
416
|
env = Environment.from_loader(loader).resolve_type_names
|
399
417
|
|
400
418
|
builder = DefinitionBuilder.new(env: env)
|
@@ -437,6 +455,7 @@ EOU
|
|
437
455
|
end
|
438
456
|
|
439
457
|
def run_constant(args, options)
|
458
|
+
# @type var context: String?
|
440
459
|
context = nil
|
441
460
|
|
442
461
|
OptionParser.new do |opts|
|
@@ -461,10 +480,7 @@ EOU
|
|
461
480
|
return
|
462
481
|
end
|
463
482
|
|
464
|
-
loader =
|
465
|
-
|
466
|
-
options.setup(loader)
|
467
|
-
|
483
|
+
loader = options.loader()
|
468
484
|
env = Environment.from_loader(loader).resolve_type_names
|
469
485
|
|
470
486
|
builder = DefinitionBuilder.new(env: env)
|
@@ -498,11 +514,10 @@ Examples:
|
|
498
514
|
EOU
|
499
515
|
end.parse!(args)
|
500
516
|
|
501
|
-
loader =
|
502
|
-
|
503
|
-
options.setup(loader)
|
517
|
+
loader = options.loader()
|
504
518
|
|
505
519
|
kind_of = -> (path) {
|
520
|
+
# @type var path: Pathname
|
506
521
|
case
|
507
522
|
when path.file?
|
508
523
|
"file"
|
@@ -515,19 +530,14 @@ EOU
|
|
515
530
|
end
|
516
531
|
}
|
517
532
|
|
518
|
-
|
519
|
-
|
520
|
-
|
521
|
-
|
522
|
-
|
523
|
-
loader.paths.each do |path|
|
524
|
-
case path
|
533
|
+
loader.each_dir do |source, dir|
|
534
|
+
case source
|
535
|
+
when :core
|
536
|
+
stdout.puts "#{dir} (#{kind_of[dir]}, core)"
|
525
537
|
when Pathname
|
526
|
-
stdout.puts "#{
|
527
|
-
when EnvironmentLoader::
|
528
|
-
stdout.puts "#{
|
529
|
-
when EnvironmentLoader::LibraryPath
|
530
|
-
stdout.puts "#{path.path} (#{kind_of[path.path]}, library, name=#{path.name})"
|
538
|
+
stdout.puts "#{dir} (#{kind_of[dir]})"
|
539
|
+
when EnvironmentLoader::Library
|
540
|
+
stdout.puts "#{dir} (#{kind_of[dir]}, library, name=#{source.name})"
|
531
541
|
end
|
532
542
|
end
|
533
543
|
end
|
@@ -573,10 +583,7 @@ EOU
|
|
573
583
|
end
|
574
584
|
end.parse!(args)
|
575
585
|
|
576
|
-
loader =
|
577
|
-
|
578
|
-
options.setup(loader)
|
579
|
-
|
586
|
+
loader = options.loader()
|
580
587
|
env = Environment.from_loader(loader).resolve_type_names
|
581
588
|
|
582
589
|
require_libs.each do |lib|
|
@@ -659,7 +666,6 @@ EOU
|
|
659
666
|
|
660
667
|
def run_vendor(args, options)
|
661
668
|
clean = false
|
662
|
-
vendor_stdlib = false
|
663
669
|
vendor_dir = Pathname("vendor/sigs")
|
664
670
|
|
665
671
|
OptionParser.new do |opts|
|
@@ -682,10 +688,6 @@ Options:
|
|
682
688
|
clean = v
|
683
689
|
end
|
684
690
|
|
685
|
-
opts.on("--[no-]stdlib", "Vendor stdlib signatures or not (default: no)") do |v|
|
686
|
-
vendor_stdlib = v
|
687
|
-
end
|
688
|
-
|
689
691
|
opts.on("--vendor-dir [DIR]", "Specify the directory for vendored signatures (default: vendor/sigs)") do |path|
|
690
692
|
vendor_dir = Pathname(path)
|
691
693
|
end
|
@@ -693,28 +695,26 @@ Options:
|
|
693
695
|
|
694
696
|
stdout.puts "Vendoring signatures to #{vendor_dir}..."
|
695
697
|
|
696
|
-
|
698
|
+
loader = options.loader()
|
697
699
|
|
698
|
-
|
699
|
-
|
700
|
-
|
701
|
-
|
700
|
+
args.each do |gem|
|
701
|
+
name, version = gem.split(/:/, 2)
|
702
|
+
|
703
|
+
next unless name
|
702
704
|
|
703
|
-
|
704
|
-
|
705
|
-
vendorer.stdlib!
|
705
|
+
stdout.puts " Loading library: #{name}, version=#{version}..."
|
706
|
+
loader.add(library: name, version: version)
|
706
707
|
end
|
707
708
|
|
708
|
-
|
709
|
-
name, version = EnvironmentLoader.parse_library(gem)
|
709
|
+
vendorer = Vendorer.new(vendor_dir: vendor_dir, loader: loader)
|
710
710
|
|
711
|
-
|
712
|
-
|
713
|
-
|
714
|
-
stdout.puts " Vendoring gem: name=#{name}, version=#{version}..."
|
715
|
-
vendorer.gem!(name, version)
|
716
|
-
end
|
711
|
+
if clean
|
712
|
+
stdout.puts " Deleting #{vendor_dir}..."
|
713
|
+
vendorer.clean!
|
717
714
|
end
|
715
|
+
|
716
|
+
stdout.puts " Copying RBS files..."
|
717
|
+
vendorer.copy!
|
718
718
|
end
|
719
719
|
|
720
720
|
def run_parse(args, options)
|
@@ -730,20 +730,20 @@ Examples:
|
|
730
730
|
EOB
|
731
731
|
end.parse!(args)
|
732
732
|
|
733
|
-
loader =
|
733
|
+
loader = options.loader()
|
734
734
|
|
735
735
|
syntax_error = false
|
736
736
|
args.each do |path|
|
737
737
|
path = Pathname(path)
|
738
|
-
loader.
|
739
|
-
Parser.parse_signature(
|
738
|
+
loader.each_file(path, skip_hidden: false, immediate: true) do |file_path|
|
739
|
+
Parser.parse_signature(file_path.read)
|
740
740
|
rescue RBS::Parser::SyntaxError => ex
|
741
741
|
loc = ex.error_value.location
|
742
|
-
stdout.puts "#{
|
742
|
+
stdout.puts "#{file_path}:#{loc.start_line}:#{loc.start_column}: parse error on value: (#{ex.token_str})"
|
743
743
|
syntax_error = true
|
744
744
|
rescue RBS::Parser::SemanticsError => ex
|
745
745
|
loc = ex.location
|
746
|
-
stdout.puts "#{
|
746
|
+
stdout.puts "#{file_path}:#{loc.start_line}:#{loc.start_column}: #{ex.original_message}"
|
747
747
|
syntax_error = true
|
748
748
|
end
|
749
749
|
end
|
@@ -751,22 +751,24 @@ Examples:
|
|
751
751
|
exit 1 if syntax_error
|
752
752
|
end
|
753
753
|
|
754
|
-
def parse_type_name(string)
|
755
|
-
Namespace.parse(string).yield_self do |namespace|
|
756
|
-
last = namespace.path.last
|
757
|
-
TypeName.new(name: last, namespace: namespace.parent)
|
758
|
-
end
|
759
|
-
end
|
760
|
-
|
761
754
|
def test_opt options
|
762
|
-
|
763
|
-
|
755
|
+
opts = []
|
756
|
+
|
757
|
+
opts.push(*options.repos.map {|dir| "--repo #{Shellwords.escape(dir)}"})
|
758
|
+
opts.push(*options.dirs.map {|dir| "-I #{Shellwords.escape(dir)}"})
|
759
|
+
opts.push(*options.libs.map {|lib| "-r#{Shellwords.escape(lib)}"})
|
760
|
+
|
761
|
+
opts.empty? ? nil : opts.join(" ")
|
764
762
|
end
|
765
763
|
|
766
764
|
def run_test(args, options)
|
765
|
+
# @type var unchecked_classes: Array[String]
|
767
766
|
unchecked_classes = []
|
767
|
+
# @type var targets: Array[String]
|
768
768
|
targets = []
|
769
|
+
# @type var sample_size: String?
|
769
770
|
sample_size = nil
|
771
|
+
# @type var double_suite: String?
|
770
772
|
double_suite = nil
|
771
773
|
|
772
774
|
(opts = OptionParser.new do |opts|
|
@@ -796,7 +798,6 @@ EOB
|
|
796
798
|
opts.on("--double-suite DOUBLE_SUITE", "Sets the double suite in use (currently supported: rspec | minitest)") do |suite|
|
797
799
|
double_suite = suite
|
798
800
|
end
|
799
|
-
|
800
801
|
end).order!(args)
|
801
802
|
|
802
803
|
if args.length.zero?
|
@@ -804,6 +805,7 @@ EOB
|
|
804
805
|
exit 1
|
805
806
|
end
|
806
807
|
|
808
|
+
# @type var env_hash: Hash[String, String?]
|
807
809
|
env_hash = {
|
808
810
|
'RUBYOPT' => "#{ENV['RUBYOPT']} -rrbs/test/setup",
|
809
811
|
'RBS_TEST_OPT' => test_opt(options),
|