rbs_rails 0.8.2 → 0.10.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.dependabot/config.yml +0 -3
- data/.github/workflows/ci.yml +2 -4
- data/.gitignore +1 -1
- data/CHANGELOG.md +34 -0
- data/DESIGN.md +36 -0
- data/Gemfile +5 -2
- data/Gemfile.lock +140 -24
- data/README.md +12 -24
- data/Rakefile +4 -2
- data/Steepfile +1 -17
- data/bin/setup +1 -1
- data/lib/rbs_rails/active_record.rb +209 -28
- data/lib/rbs_rails/dependency_builder.rb +2 -2
- data/lib/rbs_rails/rake_task.rb +1 -0
- data/lib/rbs_rails/version.rb +1 -1
- data/rbs_collection.lock.yaml +144 -0
- data/rbs_collection.yaml +36 -0
- data/sig/rbs_rails/active_record.rbs +13 -0
- data/sig/rbs_rails/dependency_builder.rbs +1 -0
- metadata +6 -5
- data/bin/gem_rbs +0 -94
- data/bin/rbs +0 -30
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 16dd1379f4621410d78e352c8fdc8750d3fb469d8c395aee77de85d2f8570279
|
4
|
+
data.tar.gz: e50b75cc1e64a8630c1508805d146d2cf5edad065cdcab502f910fcb84bc51ef
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 12136882eeebf0e2219af85c6393f6b8a74c4bc6f268b57d5b9c931a99fa42ee81ed9deb9885d4209f28dbf43d9d57563641379031c199397cf520a7dc417f10
|
7
|
+
data.tar.gz: 40ffd8a1525501f736f759769a95183e3933da0c1063e5e939b6c4ccf23ae9d98731ef782c23f6c7eb6b7280b2c39f535379886edeb3abeb423810cf2ead58ac
|
data/.dependabot/config.yml
CHANGED
data/.github/workflows/ci.yml
CHANGED
@@ -15,7 +15,7 @@ jobs:
|
|
15
15
|
strategy:
|
16
16
|
fail-fast: false
|
17
17
|
matrix:
|
18
|
-
ruby: [2.6, 2.7, '3.0', head]
|
18
|
+
ruby: [2.6, 2.7, '3.0', 3.1, head]
|
19
19
|
runs-on: ubuntu-latest
|
20
20
|
steps:
|
21
21
|
- uses: actions/checkout@v2
|
@@ -23,7 +23,5 @@ jobs:
|
|
23
23
|
with:
|
24
24
|
ruby-version: ${{ matrix.ruby }}
|
25
25
|
bundler-cache: true # runs 'bundle install' and caches installed gems automatically
|
26
|
-
-
|
27
|
-
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
28
|
-
run: bin/gem_rbs
|
26
|
+
- run: bin/setup
|
29
27
|
- run: bundle exec rake
|
data/.gitignore
CHANGED
data/CHANGELOG.md
CHANGED
@@ -2,6 +2,40 @@
|
|
2
2
|
|
3
3
|
## master (unreleased)
|
4
4
|
|
5
|
+
## 0.10.1 (2022-03-23)
|
6
|
+
|
7
|
+
### Bug Fixes
|
8
|
+
|
9
|
+
* Generate dependency types of relations. [#216](https://github.com/pocke/rbs_rails/pull/216)
|
10
|
+
|
11
|
+
## 0.10.0 (2022-03-18)
|
12
|
+
|
13
|
+
### New Features
|
14
|
+
|
15
|
+
* Support `has_secure_password`. [#193](https://github.com/pocke/rbs_rails/pull/193)
|
16
|
+
* Support Active Storage. [#195](https://github.com/pocke/rbs_rails/pull/195)
|
17
|
+
|
18
|
+
### Bug Fixes
|
19
|
+
|
20
|
+
* Use absolute path for class names to avoid using incorrect class. [#201](https://github.com/pocke/rbs_rails/pull/201)
|
21
|
+
* Fix NoMethodError on enum with `_default` option. [#208](https://github.com/pocke/rbs_rails/pull/208)
|
22
|
+
|
23
|
+
## 0.9.0 (2021-09-18)
|
24
|
+
|
25
|
+
### New Features
|
26
|
+
|
27
|
+
* Support delegated_type association. [#181](https://github.com/pocke/rbs_rails/pull/181)
|
28
|
+
|
29
|
+
### Bug Fixes
|
30
|
+
|
31
|
+
* Fix error on a table that doesn't have the PK. [#121](https://github.com/pocke/rbs_rails/pull/121)
|
32
|
+
* Quote variable names to avoid syntax errors. [#178](https://github.com/pocke/rbs_rails/pull/178)
|
33
|
+
* Add scope methods to `ActiveRecord_Associations_CollectionProxy`. [#182](https://github.com/pocke/rbs_rails/pull/182)
|
34
|
+
* Make `has_one` association optional. [#180](https://github.com/pocke/rbs_rails/pull/180)
|
35
|
+
* Omit some methods for polymorphic associations. [#184](https://github.com/pocke/rbs_rails/pull/184)
|
36
|
+
* Include enum methods to GeneratedRelationMethods. [#183](https://github.com/pocke/rbs_rails/pull/183)
|
37
|
+
* Include `_ActiveRecord_Relation` to `CollectionProxy`. [#189](https://github.com/pocke/rbs_rails/pull/189)
|
38
|
+
|
5
39
|
## 0.8.2 (2021-02-20)
|
6
40
|
|
7
41
|
* Add ActiveRecord::AttributeMethods::Dirty methods [#104](https://github.com/pocke/rbs_rails/pull/104)
|
data/DESIGN.md
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
# RBS Generator for Active Record models
|
2
|
+
|
3
|
+
The RBS generator for Active Record models focus on generating methods that are generated by Active Record.
|
4
|
+
For example, it generates the following things.
|
5
|
+
|
6
|
+
* Classes which inherit `ActiveRecord::Base`
|
7
|
+
* Generated methods by Active Record
|
8
|
+
* Column methods. e.g. `name` and `name=` methods for `name` column.
|
9
|
+
* Relation methods. e.g. `users` and `users=` methods for `has_many :users`.
|
10
|
+
* And so on.
|
11
|
+
|
12
|
+
I designed it generates "valid" RBSs. "valid" means the generated RBSs pass `rbs validate` only with `rbs collection`.
|
13
|
+
So if you need to do something to pass `rbs validate`, it's a bug. For example, if you see `RBS::NoSuperclassFoundError` for the generated RBS, it is a bug.
|
14
|
+
|
15
|
+
RBS Rails focuses on generating "generated" methods. It means it doesn't generate methods that are defined by the user.
|
16
|
+
For example:
|
17
|
+
|
18
|
+
```ruby
|
19
|
+
class User < ApplicationRecord
|
20
|
+
# RBS Rails generates articles methods and so on
|
21
|
+
# becasue they are generated by Active Record.
|
22
|
+
has_many :articles
|
23
|
+
|
24
|
+
# RBS Rails does NOT generate full_name method
|
25
|
+
# because the user defines it.
|
26
|
+
def full_name
|
27
|
+
first_name + last_name
|
28
|
+
end
|
29
|
+
end
|
30
|
+
```
|
31
|
+
|
32
|
+
You can use `rbs prototype rb`, `rbs prototype runtime` and `typeprof` commands to generate them.
|
33
|
+
|
34
|
+
# RBS Generator for the path helper
|
35
|
+
|
36
|
+
TODO
|
data/Gemfile
CHANGED
@@ -1,9 +1,12 @@
|
|
1
1
|
source "https://rubygems.org"
|
2
2
|
|
3
|
+
git_source(:github) { |repo_name| "https://github.com/#{repo_name}" }
|
4
|
+
|
3
5
|
# Specify your gem's dependencies in rbs_rails.gemspec
|
4
6
|
gemspec
|
5
7
|
|
6
8
|
gem "rake", "~> 13.0"
|
7
|
-
gem '
|
8
|
-
gem '
|
9
|
+
gem 'rails', '< 7', '>= 6.0'
|
10
|
+
gem 'rbs', '>= 2'
|
11
|
+
gem 'steep'
|
9
12
|
gem 'minitest'
|
data/Gemfile.lock
CHANGED
@@ -1,50 +1,165 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
rbs_rails (0.
|
4
|
+
rbs_rails (0.10.1)
|
5
5
|
parser
|
6
6
|
rbs (>= 1)
|
7
7
|
|
8
8
|
GEM
|
9
9
|
remote: https://rubygems.org/
|
10
10
|
specs:
|
11
|
-
|
11
|
+
actioncable (6.1.5)
|
12
|
+
actionpack (= 6.1.5)
|
13
|
+
activesupport (= 6.1.5)
|
14
|
+
nio4r (~> 2.0)
|
15
|
+
websocket-driver (>= 0.6.1)
|
16
|
+
actionmailbox (6.1.5)
|
17
|
+
actionpack (= 6.1.5)
|
18
|
+
activejob (= 6.1.5)
|
19
|
+
activerecord (= 6.1.5)
|
20
|
+
activestorage (= 6.1.5)
|
21
|
+
activesupport (= 6.1.5)
|
22
|
+
mail (>= 2.7.1)
|
23
|
+
actionmailer (6.1.5)
|
24
|
+
actionpack (= 6.1.5)
|
25
|
+
actionview (= 6.1.5)
|
26
|
+
activejob (= 6.1.5)
|
27
|
+
activesupport (= 6.1.5)
|
28
|
+
mail (~> 2.5, >= 2.5.4)
|
29
|
+
rails-dom-testing (~> 2.0)
|
30
|
+
actionpack (6.1.5)
|
31
|
+
actionview (= 6.1.5)
|
32
|
+
activesupport (= 6.1.5)
|
33
|
+
rack (~> 2.0, >= 2.0.9)
|
34
|
+
rack-test (>= 0.6.3)
|
35
|
+
rails-dom-testing (~> 2.0)
|
36
|
+
rails-html-sanitizer (~> 1.0, >= 1.2.0)
|
37
|
+
actiontext (6.1.5)
|
38
|
+
actionpack (= 6.1.5)
|
39
|
+
activerecord (= 6.1.5)
|
40
|
+
activestorage (= 6.1.5)
|
41
|
+
activesupport (= 6.1.5)
|
42
|
+
nokogiri (>= 1.8.5)
|
43
|
+
actionview (6.1.5)
|
44
|
+
activesupport (= 6.1.5)
|
45
|
+
builder (~> 3.1)
|
46
|
+
erubi (~> 1.4)
|
47
|
+
rails-dom-testing (~> 2.0)
|
48
|
+
rails-html-sanitizer (~> 1.1, >= 1.2.0)
|
49
|
+
activejob (6.1.5)
|
50
|
+
activesupport (= 6.1.5)
|
51
|
+
globalid (>= 0.3.6)
|
52
|
+
activemodel (6.1.5)
|
53
|
+
activesupport (= 6.1.5)
|
54
|
+
activerecord (6.1.5)
|
55
|
+
activemodel (= 6.1.5)
|
56
|
+
activesupport (= 6.1.5)
|
57
|
+
activestorage (6.1.5)
|
58
|
+
actionpack (= 6.1.5)
|
59
|
+
activejob (= 6.1.5)
|
60
|
+
activerecord (= 6.1.5)
|
61
|
+
activesupport (= 6.1.5)
|
62
|
+
marcel (~> 1.0)
|
63
|
+
mini_mime (>= 1.1.0)
|
64
|
+
activesupport (6.1.5)
|
12
65
|
concurrent-ruby (~> 1.0, >= 1.0.2)
|
13
66
|
i18n (>= 1.6, < 2)
|
14
67
|
minitest (>= 5.1)
|
15
68
|
tzinfo (~> 2.0)
|
16
69
|
zeitwerk (~> 2.3)
|
17
70
|
ast (2.4.2)
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
71
|
+
builder (3.2.4)
|
72
|
+
concurrent-ruby (1.1.9)
|
73
|
+
crass (1.0.6)
|
74
|
+
erubi (1.10.0)
|
75
|
+
ffi (1.15.5)
|
76
|
+
globalid (1.0.0)
|
77
|
+
activesupport (>= 5.0)
|
78
|
+
i18n (1.10.0)
|
23
79
|
concurrent-ruby (~> 1.0)
|
24
|
-
language_server-protocol (3.
|
25
|
-
listen (3.
|
80
|
+
language_server-protocol (3.16.0.3)
|
81
|
+
listen (3.7.1)
|
26
82
|
rb-fsevent (~> 0.10, >= 0.10.3)
|
27
83
|
rb-inotify (~> 0.9, >= 0.9.10)
|
28
|
-
|
29
|
-
|
84
|
+
loofah (2.15.0)
|
85
|
+
crass (~> 1.0.2)
|
86
|
+
nokogiri (>= 1.5.9)
|
87
|
+
mail (2.7.1)
|
88
|
+
mini_mime (>= 0.1.1)
|
89
|
+
marcel (1.0.2)
|
90
|
+
method_source (1.0.0)
|
91
|
+
mini_mime (1.1.2)
|
92
|
+
mini_portile2 (2.8.0)
|
93
|
+
minitest (5.15.0)
|
94
|
+
nio4r (2.5.8)
|
95
|
+
nokogiri (1.13.3)
|
96
|
+
mini_portile2 (~> 2.8.0)
|
97
|
+
racc (~> 1.4)
|
98
|
+
parallel (1.21.0)
|
99
|
+
parser (3.1.1.0)
|
30
100
|
ast (~> 2.4.1)
|
31
|
-
|
32
|
-
|
33
|
-
|
101
|
+
racc (1.6.0)
|
102
|
+
rack (2.2.3)
|
103
|
+
rack-test (1.1.0)
|
104
|
+
rack (>= 1.0, < 3)
|
105
|
+
rails (6.1.5)
|
106
|
+
actioncable (= 6.1.5)
|
107
|
+
actionmailbox (= 6.1.5)
|
108
|
+
actionmailer (= 6.1.5)
|
109
|
+
actionpack (= 6.1.5)
|
110
|
+
actiontext (= 6.1.5)
|
111
|
+
actionview (= 6.1.5)
|
112
|
+
activejob (= 6.1.5)
|
113
|
+
activemodel (= 6.1.5)
|
114
|
+
activerecord (= 6.1.5)
|
115
|
+
activestorage (= 6.1.5)
|
116
|
+
activesupport (= 6.1.5)
|
117
|
+
bundler (>= 1.15.0)
|
118
|
+
railties (= 6.1.5)
|
119
|
+
sprockets-rails (>= 2.0.0)
|
120
|
+
rails-dom-testing (2.0.3)
|
121
|
+
activesupport (>= 4.2.0)
|
122
|
+
nokogiri (>= 1.6)
|
123
|
+
rails-html-sanitizer (1.4.2)
|
124
|
+
loofah (~> 2.3)
|
125
|
+
railties (6.1.5)
|
126
|
+
actionpack (= 6.1.5)
|
127
|
+
activesupport (= 6.1.5)
|
128
|
+
method_source
|
129
|
+
rake (>= 12.2)
|
130
|
+
thor (~> 1.0)
|
131
|
+
rainbow (3.1.1)
|
132
|
+
rake (13.0.6)
|
133
|
+
rb-fsevent (0.11.1)
|
34
134
|
rb-inotify (0.10.1)
|
35
135
|
ffi (~> 1.0)
|
36
|
-
rbs (
|
37
|
-
|
136
|
+
rbs (2.2.2)
|
137
|
+
sprockets (4.0.3)
|
138
|
+
concurrent-ruby (~> 1.0)
|
139
|
+
rack (> 1, < 3)
|
140
|
+
sprockets-rails (3.4.2)
|
141
|
+
actionpack (>= 5.2)
|
142
|
+
activesupport (>= 5.2)
|
143
|
+
sprockets (>= 3.0.0)
|
144
|
+
steep (0.49.1)
|
38
145
|
activesupport (>= 5.1)
|
39
|
-
|
40
|
-
language_server-protocol (~> 3.15.0.1)
|
146
|
+
language_server-protocol (>= 3.15, < 4.0)
|
41
147
|
listen (~> 3.0)
|
42
|
-
|
148
|
+
parallel (>= 1.0.0)
|
149
|
+
parser (>= 3.0)
|
43
150
|
rainbow (>= 2.2.2, < 4.0)
|
44
|
-
rbs (
|
151
|
+
rbs (>= 2.2.0)
|
152
|
+
terminal-table (>= 2, < 4)
|
153
|
+
terminal-table (3.0.2)
|
154
|
+
unicode-display_width (>= 1.1.1, < 3)
|
155
|
+
thor (1.2.1)
|
45
156
|
tzinfo (2.0.4)
|
46
157
|
concurrent-ruby (~> 1.0)
|
47
|
-
|
158
|
+
unicode-display_width (2.1.0)
|
159
|
+
websocket-driver (0.7.5)
|
160
|
+
websocket-extensions (>= 0.1.0)
|
161
|
+
websocket-extensions (0.1.5)
|
162
|
+
zeitwerk (2.5.4)
|
48
163
|
|
49
164
|
PLATFORMS
|
50
165
|
ruby
|
@@ -52,10 +167,11 @@ PLATFORMS
|
|
52
167
|
|
53
168
|
DEPENDENCIES
|
54
169
|
minitest
|
170
|
+
rails (>= 6.0, < 7)
|
55
171
|
rake (~> 13.0)
|
56
|
-
rbs (>=
|
172
|
+
rbs (>= 2)
|
57
173
|
rbs_rails!
|
58
|
-
steep
|
174
|
+
steep
|
59
175
|
|
60
176
|
BUNDLED WITH
|
61
|
-
2.
|
177
|
+
2.3.9
|
data/README.md
CHANGED
@@ -35,46 +35,34 @@ Then, the following three tasks are available.
|
|
35
35
|
* `rbs_rails:all`: Execute all tasks of RBS Rails
|
36
36
|
|
37
37
|
|
38
|
+
### Install RBS for `rails` gem
|
38
39
|
|
40
|
+
You need to install `rails` gem's RBS files. I highly recommend using `rbs collection`.
|
41
|
+
|
42
|
+
1. Add `gem 'rails'` to your `Gemfile`.
|
43
|
+
1. Then execute the following commands
|
44
|
+
```console
|
45
|
+
$ bundle install
|
46
|
+
$ bundle exec rbs collection install
|
47
|
+
```
|
39
48
|
|
40
49
|
### Steep integration
|
41
50
|
|
42
|
-
|
51
|
+
Put the following code as `Steepfile`.
|
43
52
|
|
44
53
|
```ruby
|
45
|
-
# Steepfile
|
46
|
-
|
47
54
|
target :app do
|
48
55
|
signature 'sig'
|
49
56
|
|
50
57
|
check 'app'
|
51
|
-
|
52
|
-
repo_path "path/to/rbs_repo"
|
53
|
-
|
54
|
-
library 'pathname'
|
55
|
-
library 'logger'
|
56
|
-
library 'mutex_m'
|
57
|
-
library 'date'
|
58
|
-
library 'monitor'
|
59
|
-
library 'singleton'
|
60
|
-
library 'tsort'
|
61
|
-
|
62
|
-
library 'activesupport'
|
63
|
-
library 'actionpack'
|
64
|
-
library 'activejob'
|
65
|
-
library 'activemodel'
|
66
|
-
library 'actionview'
|
67
|
-
library 'activerecord'
|
68
|
-
library 'railties'
|
69
58
|
end
|
70
59
|
```
|
71
60
|
|
72
|
-
|
61
|
+
That's all! Now you can check your Rails app statically with `steep check` command.
|
73
62
|
|
74
63
|
## Development
|
75
64
|
|
76
|
-
After checking out the repo, run `
|
77
|
-
`GITHUB_TOKEN` environment variable is required to fetch RBS from [ruby/gem_rbs](https://github.com/ruby/gem_rbs) repository.
|
65
|
+
After checking out the repo, run `bin/setup` to install dependencies.
|
78
66
|
|
79
67
|
You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
80
68
|
|
data/Rakefile
CHANGED
@@ -9,8 +9,10 @@ task :steep do
|
|
9
9
|
end
|
10
10
|
|
11
11
|
task :rbs_validate do
|
12
|
-
|
13
|
-
|
12
|
+
repo = ENV['RBS_REPO_DIR']&.then do |env|
|
13
|
+
"--repo=#{env}"
|
14
|
+
end
|
15
|
+
sh "rbs #{repo} validate --silent"
|
14
16
|
end
|
15
17
|
|
16
18
|
Rake::TestTask.new do |test|
|
data/Steepfile
CHANGED
@@ -3,21 +3,5 @@ target :lib do
|
|
3
3
|
signature 'assets/sig'
|
4
4
|
|
5
5
|
check "lib" # Directory name
|
6
|
-
repo_path ENV['RBS_REPO_DIR']
|
7
|
-
|
8
|
-
library "pathname"
|
9
|
-
library "logger"
|
10
|
-
library "mutex_m"
|
11
|
-
library "date"
|
12
|
-
library 'monitor'
|
13
|
-
library 'singleton'
|
14
|
-
library 'tsort'
|
15
|
-
|
16
|
-
library 'activesupport'
|
17
|
-
library 'actionpack'
|
18
|
-
library 'activejob'
|
19
|
-
library 'activemodel'
|
20
|
-
library 'actionview'
|
21
|
-
library 'activerecord'
|
22
|
-
library 'railties'
|
6
|
+
repo_path ENV['RBS_REPO_DIR'] if ENV['RBS_REPO_DIR']
|
23
7
|
end
|
data/bin/setup
CHANGED
@@ -32,10 +32,16 @@ module RbsRails
|
|
32
32
|
|
33
33
|
#{columns}
|
34
34
|
#{associations}
|
35
|
+
#{generated_association_methods}
|
36
|
+
#{has_secure_password}
|
37
|
+
#{delegated_type_instance}
|
38
|
+
#{delegated_type_scope(singleton: true)}
|
35
39
|
#{enum_instance_methods}
|
36
40
|
#{enum_scope_methods(singleton: true)}
|
37
41
|
#{scopes(singleton: true)}
|
38
42
|
|
43
|
+
#{generated_relation_methods_decl}
|
44
|
+
|
39
45
|
#{relation_decl}
|
40
46
|
|
41
47
|
#{collection_proxy_decl}
|
@@ -46,25 +52,37 @@ module RbsRails
|
|
46
52
|
|
47
53
|
private def pk_type
|
48
54
|
pk = klass.primary_key
|
55
|
+
return 'top' unless pk
|
56
|
+
|
49
57
|
col = klass.columns.find {|col| col.name == pk }
|
50
58
|
sql_type_to_class(col.type)
|
51
59
|
end
|
52
60
|
|
61
|
+
private def generated_relation_methods_decl
|
62
|
+
<<~RBS
|
63
|
+
module GeneratedRelationMethods
|
64
|
+
#{enum_scope_methods(singleton: false)}
|
65
|
+
#{scopes(singleton: false)}
|
66
|
+
#{delegated_type_scope(singleton: false)}
|
67
|
+
end
|
68
|
+
RBS
|
69
|
+
end
|
70
|
+
|
53
71
|
private def relation_decl
|
54
72
|
<<~RBS
|
55
|
-
class #{relation_class_name} < ActiveRecord::Relation
|
73
|
+
class #{relation_class_name} < ::ActiveRecord::Relation
|
74
|
+
include GeneratedRelationMethods
|
56
75
|
include _ActiveRecord_Relation[#{klass_name}, #{pk_type}]
|
57
76
|
include Enumerable[#{klass_name}]
|
58
|
-
|
59
|
-
#{enum_scope_methods(singleton: false)}
|
60
|
-
#{scopes(singleton: false)}
|
61
77
|
end
|
62
78
|
RBS
|
63
79
|
end
|
64
80
|
|
65
81
|
private def collection_proxy_decl
|
66
82
|
<<~RBS
|
67
|
-
class ActiveRecord_Associations_CollectionProxy < ActiveRecord::Associations::CollectionProxy
|
83
|
+
class ActiveRecord_Associations_CollectionProxy < ::ActiveRecord::Associations::CollectionProxy
|
84
|
+
include GeneratedRelationMethods
|
85
|
+
include _ActiveRecord_Relation[#{klass_name}, #{pk_type}]
|
68
86
|
end
|
69
87
|
RBS
|
70
88
|
end
|
@@ -81,7 +99,7 @@ module RbsRails
|
|
81
99
|
superclass_name = Util.module_name(superclass)
|
82
100
|
@dependencies << superclass_name
|
83
101
|
|
84
|
-
"class #{mod_name} <
|
102
|
+
"class #{mod_name} < ::#{superclass_name}"
|
85
103
|
when Module
|
86
104
|
"module #{mod_name}"
|
87
105
|
else
|
@@ -104,9 +122,13 @@ module RbsRails
|
|
104
122
|
|
105
123
|
private def has_many
|
106
124
|
klass.reflect_on_all_associations(:has_many).map do |a|
|
125
|
+
@dependencies << a.klass.name
|
126
|
+
|
107
127
|
singular_name = a.name.to_s.singularize
|
108
128
|
type = Util.module_name(a.klass)
|
109
129
|
collection_type = "#{type}::ActiveRecord_Associations_CollectionProxy"
|
130
|
+
@dependencies << collection_type
|
131
|
+
|
110
132
|
<<~RUBY.chomp
|
111
133
|
def #{a.name}: () -> #{collection_type}
|
112
134
|
def #{a.name}=: (#{collection_type} | Array[#{type}]) -> (#{collection_type} | Array[#{type}])
|
@@ -118,10 +140,12 @@ module RbsRails
|
|
118
140
|
|
119
141
|
private def has_one
|
120
142
|
klass.reflect_on_all_associations(:has_one).map do |a|
|
143
|
+
@dependencies << a.klass.name unless a.polymorphic?
|
144
|
+
|
121
145
|
type = a.polymorphic? ? 'untyped' : Util.module_name(a.klass)
|
122
146
|
type_optional = optional(type)
|
123
147
|
<<~RUBY.chomp
|
124
|
-
def #{a.name}: () -> #{
|
148
|
+
def #{a.name}: () -> #{type_optional}
|
125
149
|
def #{a.name}=: (#{type_optional}) -> #{type_optional}
|
126
150
|
def build_#{a.name}: (untyped) -> #{type}
|
127
151
|
def create_#{a.name}: (untyped) -> #{type}
|
@@ -133,25 +157,166 @@ module RbsRails
|
|
133
157
|
|
134
158
|
private def belongs_to
|
135
159
|
klass.reflect_on_all_associations(:belongs_to).map do |a|
|
160
|
+
@dependencies << a.klass.name unless a.polymorphic?
|
161
|
+
|
136
162
|
type = a.polymorphic? ? 'untyped' : Util.module_name(a.klass)
|
137
163
|
type_optional = optional(type)
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
def
|
145
|
-
|
164
|
+
# @type var methods: Array[String]
|
165
|
+
methods = []
|
166
|
+
methods << "def #{a.name}: () -> #{type}"
|
167
|
+
methods << "def #{a.name}=: (#{type_optional}) -> #{type_optional}"
|
168
|
+
methods << "def reload_#{a.name}: () -> #{type_optional}"
|
169
|
+
if !a.polymorphic?
|
170
|
+
methods << "def build_#{a.name}: (untyped) -> #{type}"
|
171
|
+
methods << "def create_#{a.name}: (untyped) -> #{type}"
|
172
|
+
methods << "def create_#{a.name}!: (untyped) -> #{type}"
|
173
|
+
end
|
174
|
+
methods.join("\n")
|
146
175
|
end.join("\n")
|
147
176
|
end
|
148
177
|
|
178
|
+
private def generated_association_methods
|
179
|
+
# @type var sigs: Array[String]
|
180
|
+
sigs = []
|
181
|
+
|
182
|
+
# Needs to require "active_storage/engine"
|
183
|
+
if klass.respond_to?(:attachment_reflections)
|
184
|
+
sigs << "module GeneratedAssociationMethods"
|
185
|
+
sigs << klass.attachment_reflections.map do |name, reflection|
|
186
|
+
case reflection.macro
|
187
|
+
when :has_one_attached
|
188
|
+
<<~EOS
|
189
|
+
def #{name}: () -> ActiveStorage::Attached::One
|
190
|
+
def #{name}=: (ActionDispatch::Http::UploadedFile) -> ActionDispatch::Http::UploadedFile
|
191
|
+
| (Rack::Test::UploadedFile) -> Rack::Test::UploadedFile
|
192
|
+
| (ActiveStorage::Blob) -> ActiveStorage::Blob
|
193
|
+
| (String) -> String
|
194
|
+
| ({ io: IO, filename: String, content_type: String? }) -> { io: IO, filename: String, content_type: String? }
|
195
|
+
| (nil) -> nil
|
196
|
+
EOS
|
197
|
+
when :has_many_attached
|
198
|
+
<<~EOS
|
199
|
+
def #{name}: () -> ActiveStorage::Attached::Many
|
200
|
+
def #{name}=: (untyped) -> untyped
|
201
|
+
EOS
|
202
|
+
else
|
203
|
+
raise
|
204
|
+
end
|
205
|
+
end.join("\n")
|
206
|
+
sigs << "end"
|
207
|
+
sigs << "include GeneratedAssociationMethods"
|
208
|
+
end
|
209
|
+
|
210
|
+
sigs.join("\n")
|
211
|
+
end
|
212
|
+
|
213
|
+
private def delegated_type_scope(singleton:)
|
214
|
+
definitions = delegated_type_definitions
|
215
|
+
return "" unless definitions
|
216
|
+
definitions.map do |definition|
|
217
|
+
definition[:types].map do |type|
|
218
|
+
scope_name = type.tableize.gsub("/", "_")
|
219
|
+
"def #{singleton ? 'self.' : ''}#{scope_name}: () -> #{relation_class_name}"
|
220
|
+
end
|
221
|
+
end.flatten.join("\n")
|
222
|
+
end
|
223
|
+
|
224
|
+
private def delegated_type_instance
|
225
|
+
definitions = delegated_type_definitions
|
226
|
+
return "" unless definitions
|
227
|
+
# @type var methods: Array[String]
|
228
|
+
methods = []
|
229
|
+
definitions.each do |definition|
|
230
|
+
methods << "def #{definition[:role]}_class: () -> Class"
|
231
|
+
methods << "def #{definition[:role]}_name: () -> String"
|
232
|
+
methods << definition[:types].map do |type|
|
233
|
+
scope_name = type.tableize.gsub("/", "_")
|
234
|
+
singular = scope_name.singularize
|
235
|
+
<<~RUBY.chomp
|
236
|
+
def #{singular}?: () -> bool
|
237
|
+
def #{singular}: () -> #{type.classify}?
|
238
|
+
def #{singular}_id: () -> Integer?
|
239
|
+
RUBY
|
240
|
+
end.join("\n")
|
241
|
+
end
|
242
|
+
methods.join("\n")
|
243
|
+
end
|
244
|
+
|
245
|
+
private def delegated_type_definitions
|
246
|
+
ast = parse_model_file
|
247
|
+
return unless ast
|
248
|
+
|
249
|
+
traverse(ast).map do |node|
|
250
|
+
# @type block: { role: Symbol, types: Array[String] }?
|
251
|
+
next unless node.type == :send
|
252
|
+
next unless node.children[0].nil?
|
253
|
+
next unless node.children[1] == :delegated_type
|
254
|
+
|
255
|
+
role_node = node.children[2]
|
256
|
+
next unless role_node
|
257
|
+
next unless role_node.type == :sym
|
258
|
+
# @type var role: Symbol
|
259
|
+
role = role_node.children[0]
|
260
|
+
|
261
|
+
args_node = node.children[3]
|
262
|
+
next unless args_node
|
263
|
+
next unless args_node.type == :hash
|
264
|
+
|
265
|
+
types = traverse(args_node).map do |n|
|
266
|
+
# @type block: Array[String]?
|
267
|
+
next unless n.type == :pair
|
268
|
+
key_node = n.children[0]
|
269
|
+
next unless key_node
|
270
|
+
next unless key_node.type == :sym
|
271
|
+
next unless key_node.children[0] == :types
|
272
|
+
|
273
|
+
types_node = n.children[1]
|
274
|
+
next unless types_node
|
275
|
+
next unless types_node.type == :array
|
276
|
+
code = types_node.loc.expression.source
|
277
|
+
eval(code)
|
278
|
+
end.compact.flatten
|
279
|
+
|
280
|
+
{ role: role, types: types }
|
281
|
+
end.compact
|
282
|
+
end
|
283
|
+
|
284
|
+
private def has_secure_password
|
285
|
+
ast = parse_model_file
|
286
|
+
return unless ast
|
287
|
+
|
288
|
+
traverse(ast).map do |node|
|
289
|
+
# @type block: String?
|
290
|
+
next unless node.type == :send
|
291
|
+
next unless node.children[0].nil?
|
292
|
+
next unless node.children[1] == :has_secure_password
|
293
|
+
|
294
|
+
attribute_node = node.children[2]
|
295
|
+
attribute = if attribute_node && attribute_node.type == :sym
|
296
|
+
attribute_node.children[0]
|
297
|
+
else
|
298
|
+
:password
|
299
|
+
end
|
300
|
+
|
301
|
+
<<~EOS
|
302
|
+
module ActiveModel_SecurePassword_InstanceMethodsOnActivation_#{attribute}
|
303
|
+
attr_reader #{attribute}: String?
|
304
|
+
def #{attribute}=: (String) -> String
|
305
|
+
def #{attribute}_confirmation=: (String) -> String
|
306
|
+
def authenticate_#{attribute}: (String) -> (#{klass_name} | false)
|
307
|
+
#{attribute == :password ? "alias authenticate authenticate_password" : ""}
|
308
|
+
end
|
309
|
+
include ActiveModel_SecurePassword_InstanceMethodsOnActivation_#{attribute}
|
310
|
+
EOS
|
311
|
+
end.compact.join("\n")
|
312
|
+
end
|
313
|
+
|
149
314
|
private def enum_instance_methods
|
150
315
|
# @type var methods: Array[String]
|
151
316
|
methods = []
|
152
317
|
enum_definitions.each do |hash|
|
153
318
|
hash.each do |name, values|
|
154
|
-
next if name == :_prefix || name == :_suffix
|
319
|
+
next if name == :_prefix || name == :_suffix || name == :_default
|
155
320
|
|
156
321
|
values.each do |label, value|
|
157
322
|
value_method_name = enum_method_name(hash, name, label)
|
@@ -169,7 +334,7 @@ module RbsRails
|
|
169
334
|
methods = []
|
170
335
|
enum_definitions.each do |hash|
|
171
336
|
hash.each do |name, values|
|
172
|
-
next if name == :_prefix || name == :_suffix
|
337
|
+
next if name == :_prefix || name == :_suffix || name == :_default
|
173
338
|
|
174
339
|
values.each do |label, value|
|
175
340
|
value_method_name = enum_method_name(hash, name, label)
|
@@ -230,7 +395,9 @@ module RbsRails
|
|
230
395
|
ast = parse_model_file
|
231
396
|
return '' unless ast
|
232
397
|
|
233
|
-
|
398
|
+
prefix = singleton ? 'self.' : ''
|
399
|
+
|
400
|
+
sigs = traverse(ast).map do |node|
|
234
401
|
# @type block: nil | String
|
235
402
|
next unless node.type == :send
|
236
403
|
next unless node.children[0].nil?
|
@@ -246,8 +413,16 @@ module RbsRails
|
|
246
413
|
next unless body_node.type == :block
|
247
414
|
|
248
415
|
args = args_to_type(body_node.children[1])
|
249
|
-
"def #{
|
250
|
-
end.compact
|
416
|
+
"def #{prefix}#{name}: #{args} -> #{relation_class_name}"
|
417
|
+
end.compact
|
418
|
+
|
419
|
+
if klass.respond_to?(:attachment_reflections)
|
420
|
+
klass.attachment_reflections.each do |name, _reflection|
|
421
|
+
sigs << "def #{prefix}with_attached_#{name}: () -> #{relation_class_name}"
|
422
|
+
end
|
423
|
+
end
|
424
|
+
|
425
|
+
sigs.join("\n")
|
251
426
|
end
|
252
427
|
|
253
428
|
private def args_to_type(args_node)
|
@@ -258,17 +433,17 @@ module RbsRails
|
|
258
433
|
args_node.children.each do |node|
|
259
434
|
case node.type
|
260
435
|
when :arg
|
261
|
-
res << "untyped
|
436
|
+
res << "untyped `#{node.children[0]}`"
|
262
437
|
when :optarg
|
263
|
-
res << "?untyped
|
438
|
+
res << "?untyped `#{node.children[0]}`"
|
264
439
|
when :kwarg
|
265
440
|
res << "#{node.children[0]}: untyped"
|
266
441
|
when :kwoptarg
|
267
442
|
res << "?#{node.children[0]}: untyped"
|
268
443
|
when :restarg
|
269
|
-
res << "*untyped
|
444
|
+
res << "*untyped `#{node.children[0]}`"
|
270
445
|
when :kwrestarg
|
271
|
-
res << "**untyped
|
446
|
+
res << "**untyped `#{node.children[0]}`"
|
272
447
|
when :blockarg
|
273
448
|
block = " { (*untyped) -> untyped }"
|
274
449
|
else
|
@@ -292,7 +467,7 @@ module RbsRails
|
|
292
467
|
end
|
293
468
|
|
294
469
|
private def traverse(node, &block)
|
295
|
-
return to_enum(__method__, node) unless block_given?
|
470
|
+
return to_enum(__method__ || raise, node) unless block_given?
|
296
471
|
|
297
472
|
# @type var block: ^(Parser::AST::Node) -> untyped
|
298
473
|
block.call node
|
@@ -306,7 +481,8 @@ module RbsRails
|
|
306
481
|
end
|
307
482
|
|
308
483
|
private def columns
|
309
|
-
|
484
|
+
mod_sig = +"module GeneratedAttributeMethods\n"
|
485
|
+
mod_sig << klass.columns.map do |col|
|
310
486
|
class_name = if enum_definitions.any? { |hash| hash.key?(col.name) || hash.key?(col.name.to_sym) }
|
311
487
|
'String'
|
312
488
|
else
|
@@ -315,7 +491,9 @@ module RbsRails
|
|
315
491
|
class_name_opt = optional(class_name)
|
316
492
|
column_type = col.null ? class_name_opt : class_name
|
317
493
|
sig = <<~EOS
|
318
|
-
|
494
|
+
def #{col.name}: () -> #{column_type}
|
495
|
+
def #{col.name}=: (#{column_type}) -> #{column_type}
|
496
|
+
def #{col.name}?: () -> bool
|
319
497
|
def #{col.name}_changed?: () -> bool
|
320
498
|
def #{col.name}_change: () -> [#{class_name_opt}, #{class_name_opt}]
|
321
499
|
def #{col.name}_will_change!: () -> void
|
@@ -332,9 +510,12 @@ module RbsRails
|
|
332
510
|
def restore_#{col.name}!: () -> void
|
333
511
|
def clear_#{col.name}_change: () -> void
|
334
512
|
EOS
|
335
|
-
sig << "
|
513
|
+
sig << "\n"
|
336
514
|
sig
|
337
515
|
end.join("\n")
|
516
|
+
mod_sig << "\nend\n"
|
517
|
+
mod_sig << "include GeneratedAttributeMethods"
|
518
|
+
mod_sig
|
338
519
|
end
|
339
520
|
|
340
521
|
private def optional(class_name)
|
@@ -1,14 +1,14 @@
|
|
1
1
|
module RbsRails
|
2
2
|
class DependencyBuilder
|
3
|
-
attr_reader :deps
|
3
|
+
attr_reader :deps, :done
|
4
4
|
|
5
5
|
def initialize
|
6
6
|
@deps = []
|
7
|
+
@done = Set.new(['ActiveRecord::Base', 'ActiveRecord', 'Object'])
|
7
8
|
end
|
8
9
|
|
9
10
|
def build
|
10
11
|
dep_rbs = +""
|
11
|
-
done = Set.new(['ActiveRecord::Base', 'ActiveRecord', 'Object'])
|
12
12
|
deps.uniq!
|
13
13
|
while dep = deps.shift
|
14
14
|
next unless done.add?(dep)
|
data/lib/rbs_rails/rake_task.rb
CHANGED
data/lib/rbs_rails/version.rb
CHANGED
@@ -0,0 +1,144 @@
|
|
1
|
+
---
|
2
|
+
sources:
|
3
|
+
- name: ruby/gem_rbs_collection
|
4
|
+
remote: https://github.com/ruby/gem_rbs_collection.git
|
5
|
+
revision: main
|
6
|
+
repo_dir: gems
|
7
|
+
path: ".gem_rbs_collection"
|
8
|
+
gems:
|
9
|
+
- name: logger
|
10
|
+
version: '0'
|
11
|
+
source:
|
12
|
+
type: stdlib
|
13
|
+
- name: set
|
14
|
+
version: '0'
|
15
|
+
source:
|
16
|
+
type: stdlib
|
17
|
+
- name: pathname
|
18
|
+
version: '0'
|
19
|
+
source:
|
20
|
+
type: stdlib
|
21
|
+
- name: json
|
22
|
+
version: '0'
|
23
|
+
source:
|
24
|
+
type: stdlib
|
25
|
+
- name: optparse
|
26
|
+
version: '0'
|
27
|
+
source:
|
28
|
+
type: stdlib
|
29
|
+
- name: rubygems
|
30
|
+
version: '0'
|
31
|
+
source:
|
32
|
+
type: stdlib
|
33
|
+
- name: tsort
|
34
|
+
version: '0'
|
35
|
+
source:
|
36
|
+
type: stdlib
|
37
|
+
- name: actionpack
|
38
|
+
version: '6.0'
|
39
|
+
source:
|
40
|
+
type: git
|
41
|
+
name: ruby/gem_rbs_collection
|
42
|
+
revision: 6320a194c85afbf4ff332c3eb75fcae2a6518c92
|
43
|
+
remote: https://github.com/ruby/gem_rbs_collection.git
|
44
|
+
repo_dir: gems
|
45
|
+
- name: actionview
|
46
|
+
version: '6.0'
|
47
|
+
source:
|
48
|
+
type: git
|
49
|
+
name: ruby/gem_rbs_collection
|
50
|
+
revision: 6320a194c85afbf4ff332c3eb75fcae2a6518c92
|
51
|
+
remote: https://github.com/ruby/gem_rbs_collection.git
|
52
|
+
repo_dir: gems
|
53
|
+
- name: activejob
|
54
|
+
version: '6.0'
|
55
|
+
source:
|
56
|
+
type: git
|
57
|
+
name: ruby/gem_rbs_collection
|
58
|
+
revision: 6320a194c85afbf4ff332c3eb75fcae2a6518c92
|
59
|
+
remote: https://github.com/ruby/gem_rbs_collection.git
|
60
|
+
repo_dir: gems
|
61
|
+
- name: activemodel
|
62
|
+
version: '6.0'
|
63
|
+
source:
|
64
|
+
type: git
|
65
|
+
name: ruby/gem_rbs_collection
|
66
|
+
revision: 6320a194c85afbf4ff332c3eb75fcae2a6518c92
|
67
|
+
remote: https://github.com/ruby/gem_rbs_collection.git
|
68
|
+
repo_dir: gems
|
69
|
+
- name: activerecord
|
70
|
+
version: '6.1'
|
71
|
+
source:
|
72
|
+
type: git
|
73
|
+
name: ruby/gem_rbs_collection
|
74
|
+
revision: 6320a194c85afbf4ff332c3eb75fcae2a6518c92
|
75
|
+
remote: https://github.com/ruby/gem_rbs_collection.git
|
76
|
+
repo_dir: gems
|
77
|
+
- name: activestorage
|
78
|
+
version: '6.1'
|
79
|
+
source:
|
80
|
+
type: git
|
81
|
+
name: ruby/gem_rbs_collection
|
82
|
+
revision: 6320a194c85afbf4ff332c3eb75fcae2a6518c92
|
83
|
+
remote: https://github.com/ruby/gem_rbs_collection.git
|
84
|
+
repo_dir: gems
|
85
|
+
- name: activesupport
|
86
|
+
version: '6.0'
|
87
|
+
source:
|
88
|
+
type: git
|
89
|
+
name: ruby/gem_rbs_collection
|
90
|
+
revision: 6320a194c85afbf4ff332c3eb75fcae2a6518c92
|
91
|
+
remote: https://github.com/ruby/gem_rbs_collection.git
|
92
|
+
repo_dir: gems
|
93
|
+
- name: parallel
|
94
|
+
version: '1.20'
|
95
|
+
source:
|
96
|
+
type: git
|
97
|
+
name: ruby/gem_rbs_collection
|
98
|
+
revision: 6320a194c85afbf4ff332c3eb75fcae2a6518c92
|
99
|
+
remote: https://github.com/ruby/gem_rbs_collection.git
|
100
|
+
repo_dir: gems
|
101
|
+
- name: rack
|
102
|
+
version: 2.2.2
|
103
|
+
source:
|
104
|
+
type: git
|
105
|
+
name: ruby/gem_rbs_collection
|
106
|
+
revision: 6320a194c85afbf4ff332c3eb75fcae2a6518c92
|
107
|
+
remote: https://github.com/ruby/gem_rbs_collection.git
|
108
|
+
repo_dir: gems
|
109
|
+
- name: railties
|
110
|
+
version: '6.0'
|
111
|
+
source:
|
112
|
+
type: git
|
113
|
+
name: ruby/gem_rbs_collection
|
114
|
+
revision: 6320a194c85afbf4ff332c3eb75fcae2a6518c92
|
115
|
+
remote: https://github.com/ruby/gem_rbs_collection.git
|
116
|
+
repo_dir: gems
|
117
|
+
- name: rbs
|
118
|
+
version: 2.2.2
|
119
|
+
source:
|
120
|
+
type: rubygems
|
121
|
+
- name: monitor
|
122
|
+
version: '0'
|
123
|
+
source:
|
124
|
+
type: stdlib
|
125
|
+
- name: tempfile
|
126
|
+
version: '0'
|
127
|
+
source:
|
128
|
+
type: stdlib
|
129
|
+
- name: date
|
130
|
+
version: '0'
|
131
|
+
source:
|
132
|
+
type: stdlib
|
133
|
+
- name: singleton
|
134
|
+
version: '0'
|
135
|
+
source:
|
136
|
+
type: stdlib
|
137
|
+
- name: mutex_m
|
138
|
+
version: '0'
|
139
|
+
source:
|
140
|
+
type: stdlib
|
141
|
+
- name: time
|
142
|
+
version: '0'
|
143
|
+
source:
|
144
|
+
type: stdlib
|
data/rbs_collection.yaml
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
# Download sources
|
2
|
+
sources:
|
3
|
+
- name: ruby/gem_rbs_collection
|
4
|
+
remote: https://github.com/ruby/gem_rbs_collection.git
|
5
|
+
revision: main
|
6
|
+
repo_dir: gems
|
7
|
+
|
8
|
+
# A directory to install the downloaded RBSs
|
9
|
+
path: .gem_rbs_collection
|
10
|
+
|
11
|
+
gems:
|
12
|
+
# Ignores - Gemfile.lock contains them but their RBSs are unnecessary
|
13
|
+
- name: steep
|
14
|
+
ignore: true
|
15
|
+
- name: nokogiri
|
16
|
+
ignore: true
|
17
|
+
- name: ast
|
18
|
+
ignore: true
|
19
|
+
- name: rainbow
|
20
|
+
ignore: true
|
21
|
+
- name: listen
|
22
|
+
ignore: true
|
23
|
+
|
24
|
+
# ignore RBS Rails itself
|
25
|
+
- name: rbs_rails
|
26
|
+
ignore: true
|
27
|
+
|
28
|
+
# They'are necessary to load RBS gem.
|
29
|
+
# See https://github.com/ruby/rbs/pull/921
|
30
|
+
- name: logger
|
31
|
+
- name: set
|
32
|
+
- name: pathname
|
33
|
+
- name: json
|
34
|
+
- name: optparse
|
35
|
+
- name: rubygems
|
36
|
+
- name: tsort
|
@@ -5,6 +5,7 @@ end
|
|
5
5
|
|
6
6
|
class RbsRails::ActiveRecord::Generator
|
7
7
|
@parse_model_file: nil | Parser::AST::Node
|
8
|
+
@dependencies: Array[String]
|
8
9
|
|
9
10
|
def initialize: (singleton(ActiveRecord::Base) klass, dependencies: Array[String]) -> untyped
|
10
11
|
|
@@ -14,6 +15,8 @@ class RbsRails::ActiveRecord::Generator
|
|
14
15
|
|
15
16
|
def pk_type: () -> String
|
16
17
|
|
18
|
+
def generated_relation_methods_decl: () -> String
|
19
|
+
|
17
20
|
def relation_decl: () -> String
|
18
21
|
|
19
22
|
def collection_proxy_decl: () -> String
|
@@ -30,6 +33,16 @@ class RbsRails::ActiveRecord::Generator
|
|
30
33
|
|
31
34
|
def belongs_to: () -> String
|
32
35
|
|
36
|
+
def generated_association_methods: () -> String
|
37
|
+
|
38
|
+
def delegated_type_scope: (singleton: bool) -> String
|
39
|
+
|
40
|
+
def delegated_type_instance: () -> String
|
41
|
+
|
42
|
+
def delegated_type_definitions: () -> Array[{ role: Symbol, types: Array[String] }]?
|
43
|
+
|
44
|
+
def has_secure_password: () -> String?
|
45
|
+
|
33
46
|
def enum_instance_methods: () -> String
|
34
47
|
|
35
48
|
def enum_scope_methods: (singleton: untyped `singleton`) -> String
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rbs_rails
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.10.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Masataka Pocke Kuwabara
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2022-03-23 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: parser
|
@@ -50,6 +50,7 @@ files:
|
|
50
50
|
- ".gitignore"
|
51
51
|
- ".gitmodules"
|
52
52
|
- CHANGELOG.md
|
53
|
+
- DESIGN.md
|
53
54
|
- Gemfile
|
54
55
|
- Gemfile.lock
|
55
56
|
- LICENSE
|
@@ -58,9 +59,7 @@ files:
|
|
58
59
|
- Steepfile
|
59
60
|
- bin/add-type-params.rb
|
60
61
|
- bin/console
|
61
|
-
- bin/gem_rbs
|
62
62
|
- bin/postprocess.rb
|
63
|
-
- bin/rbs
|
64
63
|
- bin/rbs-prototype-rb.rb
|
65
64
|
- bin/setup
|
66
65
|
- bin/to-ascii.rb
|
@@ -71,6 +70,8 @@ files:
|
|
71
70
|
- lib/rbs_rails/rake_task.rb
|
72
71
|
- lib/rbs_rails/util.rb
|
73
72
|
- lib/rbs_rails/version.rb
|
73
|
+
- rbs_collection.lock.yaml
|
74
|
+
- rbs_collection.yaml
|
74
75
|
- rbs_rails.gemspec
|
75
76
|
- sig/activerecord.rbs
|
76
77
|
- sig/fileutils.rbs
|
@@ -105,7 +106,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
105
106
|
- !ruby/object:Gem::Version
|
106
107
|
version: '0'
|
107
108
|
requirements: []
|
108
|
-
rubygems_version: 3.
|
109
|
+
rubygems_version: 3.4.0.dev
|
109
110
|
signing_key:
|
110
111
|
specification_version: 4
|
111
112
|
summary: A RBS files generator for Rails application
|
data/bin/gem_rbs
DELETED
@@ -1,94 +0,0 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
|
3
|
-
require 'net/http'
|
4
|
-
require 'json'
|
5
|
-
require 'securerandom'
|
6
|
-
require 'pathname'
|
7
|
-
|
8
|
-
TOKEN = ENV.fetch('GITHUB_TOKEN')
|
9
|
-
VERSION = "6.0.3.2"
|
10
|
-
|
11
|
-
def req(query)
|
12
|
-
http = Net::HTTP.new("api.github.com", 443)
|
13
|
-
http.use_ssl = true
|
14
|
-
header = {
|
15
|
-
"Authorization" => "Bearer #{TOKEN}",
|
16
|
-
'Content-Type' => 'application/json',
|
17
|
-
'User-Agent' => 'gem_rbs client',
|
18
|
-
}
|
19
|
-
resp = http.request_post('/graphql', JSON.generate(query), header)
|
20
|
-
JSON.parse(resp.body, symbolize_names: true).tap do |content|
|
21
|
-
raise content[:errors].inspect if content[:errors]
|
22
|
-
end
|
23
|
-
end
|
24
|
-
|
25
|
-
class QueryBuilder
|
26
|
-
attr_reader :variables
|
27
|
-
|
28
|
-
def initialize
|
29
|
-
@queries = []
|
30
|
-
@variables = {}
|
31
|
-
end
|
32
|
-
|
33
|
-
def add(query, variables)
|
34
|
-
query = query.dup
|
35
|
-
variables = variables.transform_keys do |key|
|
36
|
-
next key unless @variables.key?(key)
|
37
|
-
|
38
|
-
new_key = key + '_' + SecureRandom.hex(8)
|
39
|
-
query.gsub!(key, new_key)
|
40
|
-
new_key
|
41
|
-
end
|
42
|
-
|
43
|
-
@queries << query
|
44
|
-
@variables.merge!(variables)
|
45
|
-
end
|
46
|
-
|
47
|
-
def query
|
48
|
-
# TODO: Allow non-String type for variables
|
49
|
-
"query(#{variables.keys.map { |v| "$#{v}: String!" }.join(',')}) { #{@queries.join("\n")} }"
|
50
|
-
end
|
51
|
-
end
|
52
|
-
|
53
|
-
gems = %w[activesupport actionpack activejob activemodel actionview activerecord railties]
|
54
|
-
|
55
|
-
builder = QueryBuilder.new
|
56
|
-
gems.each do |gem|
|
57
|
-
path = "main:gems/#{gem}/#{VERSION}"
|
58
|
-
builder.add(<<~GRAPHQL, { 'path' => path })
|
59
|
-
#{gem}:repository(owner: "ruby", name: "gem_rbs_collection") {
|
60
|
-
object(expression: $path) {
|
61
|
-
... on Tree {
|
62
|
-
entries {
|
63
|
-
name
|
64
|
-
object {
|
65
|
-
... on Blob {
|
66
|
-
isTruncated
|
67
|
-
text
|
68
|
-
}
|
69
|
-
}
|
70
|
-
}
|
71
|
-
}
|
72
|
-
}
|
73
|
-
}
|
74
|
-
GRAPHQL
|
75
|
-
end
|
76
|
-
|
77
|
-
resp = req(query: builder.query, variables: builder.variables)
|
78
|
-
|
79
|
-
resp[:data].each do |gem_name, gem_value|
|
80
|
-
gem_value.dig(:object, :entries).each do |entry|
|
81
|
-
fname = entry[:name]
|
82
|
-
if fname.end_with?('.rbs')
|
83
|
-
content =
|
84
|
-
if entry.dig(:object, :isTruncated)
|
85
|
-
`curl -H 'Accept: application/vnd.github.v3.raw' -H Authorization: token #{TOKEN} https://api.github.com/repos/ruby/gem_rbs_collection/contents/gems/#{gem_name}/#{VERSION}/#{fname}`
|
86
|
-
else
|
87
|
-
entry.dig(:object, :text)
|
88
|
-
end
|
89
|
-
dir = Pathname("gem_rbs/gems/#{gem_name}/#{VERSION}")
|
90
|
-
dir.mkpath
|
91
|
-
dir.join(fname).write(content)
|
92
|
-
end
|
93
|
-
end
|
94
|
-
end
|
data/bin/rbs
DELETED
@@ -1,30 +0,0 @@
|
|
1
|
-
#!ruby
|
2
|
-
|
3
|
-
require 'pathname'
|
4
|
-
root = Pathname(__dir__) / '../'
|
5
|
-
|
6
|
-
def v(require)
|
7
|
-
if v = ENV['RAILS_VERSION']
|
8
|
-
"#{require}:#{v}"
|
9
|
-
else
|
10
|
-
require
|
11
|
-
end
|
12
|
-
end
|
13
|
-
|
14
|
-
def repo
|
15
|
-
ENV['RBS_REPO_DIR'] || Pathname(__dir__).join('../gem_rbs/gems').to_s
|
16
|
-
end
|
17
|
-
|
18
|
-
exec(
|
19
|
-
'rbs',
|
20
|
-
# Require stdlibs
|
21
|
-
'-rlogger', '-rpathname', '-rmutex_m', '-rdate', '-rmonitor', '-rsingleton', '-rtsort',
|
22
|
-
"--repo=#{repo}",
|
23
|
-
# Require Rails libraries
|
24
|
-
v('-ractivesupport'), v('-ractionpack'), v('-ractivejob'), v('-ractivemodel'), v('-ractionview'), v('-ractiverecord'), v('-rrailties'),
|
25
|
-
# Load signatures that are bundled in rbs_rails
|
26
|
-
'-I' + root.join('sig').to_s, '-I' + root.join('assets/sig').to_s,
|
27
|
-
# Expand arguments
|
28
|
-
*ARGV,
|
29
|
-
)
|
30
|
-
|