rbs_rails 0.9.0 → 0.11.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ccb7076ac91a406f491cf3e6c4d8499525f860660061ff23809635d000d1aba3
4
- data.tar.gz: a863d9e16999e7491cef930b8fb79515c538ad7d83b919abad762a5c1290e370
3
+ metadata.gz: 66770df53a677c589c39cfd828149a60b4ef261979e11cc7dc823a1df475495f
4
+ data.tar.gz: 88de9ae8cc7597b4e28978f9a72a696742a5ece83b4d401fed92061fdd2b1590
5
5
  SHA512:
6
- metadata.gz: 10dccf3356c898258d6c13aaed04d61a5f137787f9ea696fe0d7005e2063c2fd130d9fdda59c4c7b4fa58d1cde84a3ca0cf750dac28f1ac9ffbfe94ead90da57
7
- data.tar.gz: b8f5c227bf58bdb16044867cd4abd883f21782817eda8fa6d85d1956418c763829748d5d0ee0e81e1005ffd18e022d6da6e83b64aa97cf4f77fe6942bacec48b
6
+ metadata.gz: e76c5de12b626f50db6f7e032dc323de1c79067a3cb9f8e0c4e3ba5ebd71d30d4e1679144573b3eec2788d75edd33b4ff084c5ffb7ccb8839f2293e5f061595e
7
+ data.tar.gz: b259952abf7664a8335a8cebda843e869a1b38c27fa010d0a927134aa56d11d63e4df20ce3850c9c2d12f62228593bd14f75ff95b7f782d00dc90d19610e71c1
@@ -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
data/CHANGELOG.md CHANGED
@@ -2,6 +2,34 @@
2
2
 
3
3
  ## master (unreleased)
4
4
 
5
+ ## 0.11.0 (2022-03-24)
6
+
7
+ ### New Features
8
+
9
+ * Add rails generator to generate rbs.rake. [#217](https://github.com/pocke/rbs_rails/pull/217)
10
+
11
+ ### Bug Fixes
12
+
13
+ * Do not expose polyfil RBSs. [#218](https://github.com/pocke/rbs_rails/pull/218)
14
+
15
+ ## 0.10.1 (2022-03-23)
16
+
17
+ ### Bug Fixes
18
+
19
+ * Generate dependency types of relations. [#216](https://github.com/pocke/rbs_rails/pull/216)
20
+
21
+ ## 0.10.0 (2022-03-18)
22
+
23
+ ### New Features
24
+
25
+ * Support `has_secure_password`. [#193](https://github.com/pocke/rbs_rails/pull/193)
26
+ * Support Active Storage. [#195](https://github.com/pocke/rbs_rails/pull/195)
27
+
28
+ ### Bug Fixes
29
+
30
+ * Use absolute path for class names to avoid using incorrect class. [#201](https://github.com/pocke/rbs_rails/pull/201)
31
+ * Fix NoMethodError on enum with `_default` option. [#208](https://github.com/pocke/rbs_rails/pull/208)
32
+
5
33
  ## 0.9.0 (2021-09-18)
6
34
 
7
35
  ### New Features
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
@@ -6,7 +6,7 @@ git_source(:github) { |repo_name| "https://github.com/#{repo_name}" }
6
6
  gemspec
7
7
 
8
8
  gem "rake", "~> 13.0"
9
- gem 'rails', '< 6.1', '>= 6.0'
10
- gem 'rbs', '>= 1.6'
11
- gem 'steep', github: 'soutaro/steep'
9
+ gem 'rails', '< 7', '>= 6.0'
10
+ gem 'rbs', '>= 2'
11
+ gem 'steep'
12
12
  gem 'minitest'
data/Gemfile.lock CHANGED
@@ -1,167 +1,165 @@
1
- GIT
2
- remote: https://github.com/soutaro/steep
3
- revision: 0673d88395fb0ea380463fef1aed568dfb077a60
4
- specs:
5
- steep (0.46.0)
6
- activesupport (>= 5.1)
7
- language_server-protocol (>= 3.15, < 4.0)
8
- listen (~> 3.0)
9
- parallel (>= 1.0.0)
10
- parser (>= 3.0)
11
- rainbow (>= 2.2.2, < 4.0)
12
- rbs (>= 1.6.0)
13
- terminal-table (>= 2, < 4)
14
-
15
1
  PATH
16
2
  remote: .
17
3
  specs:
18
- rbs_rails (0.9.0)
4
+ rbs_rails (0.11.0)
19
5
  parser
20
6
  rbs (>= 1)
21
7
 
22
8
  GEM
23
9
  remote: https://rubygems.org/
24
10
  specs:
25
- actioncable (6.0.4.1)
26
- actionpack (= 6.0.4.1)
11
+ actioncable (6.1.5)
12
+ actionpack (= 6.1.5)
13
+ activesupport (= 6.1.5)
27
14
  nio4r (~> 2.0)
28
15
  websocket-driver (>= 0.6.1)
29
- actionmailbox (6.0.4.1)
30
- actionpack (= 6.0.4.1)
31
- activejob (= 6.0.4.1)
32
- activerecord (= 6.0.4.1)
33
- activestorage (= 6.0.4.1)
34
- activesupport (= 6.0.4.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)
35
22
  mail (>= 2.7.1)
36
- actionmailer (6.0.4.1)
37
- actionpack (= 6.0.4.1)
38
- actionview (= 6.0.4.1)
39
- activejob (= 6.0.4.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)
40
28
  mail (~> 2.5, >= 2.5.4)
41
29
  rails-dom-testing (~> 2.0)
42
- actionpack (6.0.4.1)
43
- actionview (= 6.0.4.1)
44
- activesupport (= 6.0.4.1)
45
- rack (~> 2.0, >= 2.0.8)
30
+ actionpack (6.1.5)
31
+ actionview (= 6.1.5)
32
+ activesupport (= 6.1.5)
33
+ rack (~> 2.0, >= 2.0.9)
46
34
  rack-test (>= 0.6.3)
47
35
  rails-dom-testing (~> 2.0)
48
36
  rails-html-sanitizer (~> 1.0, >= 1.2.0)
49
- actiontext (6.0.4.1)
50
- actionpack (= 6.0.4.1)
51
- activerecord (= 6.0.4.1)
52
- activestorage (= 6.0.4.1)
53
- activesupport (= 6.0.4.1)
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)
54
42
  nokogiri (>= 1.8.5)
55
- actionview (6.0.4.1)
56
- activesupport (= 6.0.4.1)
43
+ actionview (6.1.5)
44
+ activesupport (= 6.1.5)
57
45
  builder (~> 3.1)
58
46
  erubi (~> 1.4)
59
47
  rails-dom-testing (~> 2.0)
60
48
  rails-html-sanitizer (~> 1.1, >= 1.2.0)
61
- activejob (6.0.4.1)
62
- activesupport (= 6.0.4.1)
49
+ activejob (6.1.5)
50
+ activesupport (= 6.1.5)
63
51
  globalid (>= 0.3.6)
64
- activemodel (6.0.4.1)
65
- activesupport (= 6.0.4.1)
66
- activerecord (6.0.4.1)
67
- activemodel (= 6.0.4.1)
68
- activesupport (= 6.0.4.1)
69
- activestorage (6.0.4.1)
70
- actionpack (= 6.0.4.1)
71
- activejob (= 6.0.4.1)
72
- activerecord (= 6.0.4.1)
73
- marcel (~> 1.0.0)
74
- activesupport (6.0.4.1)
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)
75
65
  concurrent-ruby (~> 1.0, >= 1.0.2)
76
- i18n (>= 0.7, < 2)
77
- minitest (~> 5.1)
78
- tzinfo (~> 1.1)
79
- zeitwerk (~> 2.2, >= 2.2.2)
66
+ i18n (>= 1.6, < 2)
67
+ minitest (>= 5.1)
68
+ tzinfo (~> 2.0)
69
+ zeitwerk (~> 2.3)
80
70
  ast (2.4.2)
81
71
  builder (3.2.4)
82
72
  concurrent-ruby (1.1.9)
83
73
  crass (1.0.6)
84
74
  erubi (1.10.0)
85
- ffi (1.15.4)
86
- globalid (0.5.2)
75
+ ffi (1.15.5)
76
+ globalid (1.0.0)
87
77
  activesupport (>= 5.0)
88
- i18n (1.8.10)
78
+ i18n (1.10.0)
89
79
  concurrent-ruby (~> 1.0)
90
80
  language_server-protocol (3.16.0.3)
91
- listen (3.7.0)
81
+ listen (3.7.1)
92
82
  rb-fsevent (~> 0.10, >= 0.10.3)
93
83
  rb-inotify (~> 0.9, >= 0.9.10)
94
- loofah (2.12.0)
84
+ loofah (2.15.0)
95
85
  crass (~> 1.0.2)
96
86
  nokogiri (>= 1.5.9)
97
87
  mail (2.7.1)
98
88
  mini_mime (>= 0.1.1)
99
- marcel (1.0.1)
89
+ marcel (1.0.2)
100
90
  method_source (1.0.0)
101
- mini_mime (1.1.1)
102
- mini_portile2 (2.6.1)
103
- minitest (5.14.4)
91
+ mini_mime (1.1.2)
92
+ mini_portile2 (2.8.0)
93
+ minitest (5.15.0)
104
94
  nio4r (2.5.8)
105
- nokogiri (1.12.4)
106
- mini_portile2 (~> 2.6.1)
95
+ nokogiri (1.13.3)
96
+ mini_portile2 (~> 2.8.0)
107
97
  racc (~> 1.4)
108
- parallel (1.20.1)
109
- parser (3.0.2.0)
98
+ parallel (1.21.0)
99
+ parser (3.1.1.0)
110
100
  ast (~> 2.4.1)
111
- racc (1.5.2)
101
+ racc (1.6.0)
112
102
  rack (2.2.3)
113
103
  rack-test (1.1.0)
114
104
  rack (>= 1.0, < 3)
115
- rails (6.0.4.1)
116
- actioncable (= 6.0.4.1)
117
- actionmailbox (= 6.0.4.1)
118
- actionmailer (= 6.0.4.1)
119
- actionpack (= 6.0.4.1)
120
- actiontext (= 6.0.4.1)
121
- actionview (= 6.0.4.1)
122
- activejob (= 6.0.4.1)
123
- activemodel (= 6.0.4.1)
124
- activerecord (= 6.0.4.1)
125
- activestorage (= 6.0.4.1)
126
- activesupport (= 6.0.4.1)
127
- bundler (>= 1.3.0)
128
- railties (= 6.0.4.1)
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)
129
119
  sprockets-rails (>= 2.0.0)
130
120
  rails-dom-testing (2.0.3)
131
121
  activesupport (>= 4.2.0)
132
122
  nokogiri (>= 1.6)
133
123
  rails-html-sanitizer (1.4.2)
134
124
  loofah (~> 2.3)
135
- railties (6.0.4.1)
136
- actionpack (= 6.0.4.1)
137
- activesupport (= 6.0.4.1)
125
+ railties (6.1.5)
126
+ actionpack (= 6.1.5)
127
+ activesupport (= 6.1.5)
138
128
  method_source
139
- rake (>= 0.8.7)
140
- thor (>= 0.20.3, < 2.0)
141
- rainbow (3.0.0)
129
+ rake (>= 12.2)
130
+ thor (~> 1.0)
131
+ rainbow (3.1.1)
142
132
  rake (13.0.6)
143
- rb-fsevent (0.11.0)
133
+ rb-fsevent (0.11.1)
144
134
  rb-inotify (0.10.1)
145
135
  ffi (~> 1.0)
146
- rbs (1.6.2)
147
- sprockets (4.0.2)
136
+ rbs (2.2.2)
137
+ sprockets (4.0.3)
148
138
  concurrent-ruby (~> 1.0)
149
139
  rack (> 1, < 3)
150
- sprockets-rails (3.2.2)
151
- actionpack (>= 4.0)
152
- activesupport (>= 4.0)
140
+ sprockets-rails (3.4.2)
141
+ actionpack (>= 5.2)
142
+ activesupport (>= 5.2)
153
143
  sprockets (>= 3.0.0)
154
- terminal-table (3.0.1)
144
+ steep (0.49.1)
145
+ activesupport (>= 5.1)
146
+ language_server-protocol (>= 3.15, < 4.0)
147
+ listen (~> 3.0)
148
+ parallel (>= 1.0.0)
149
+ parser (>= 3.0)
150
+ rainbow (>= 2.2.2, < 4.0)
151
+ rbs (>= 2.2.0)
152
+ terminal-table (>= 2, < 4)
153
+ terminal-table (3.0.2)
155
154
  unicode-display_width (>= 1.1.1, < 3)
156
- thor (1.1.0)
157
- thread_safe (0.3.6)
158
- tzinfo (1.2.9)
159
- thread_safe (~> 0.1)
160
- unicode-display_width (2.0.0)
155
+ thor (1.2.1)
156
+ tzinfo (2.0.4)
157
+ concurrent-ruby (~> 1.0)
158
+ unicode-display_width (2.1.0)
161
159
  websocket-driver (0.7.5)
162
160
  websocket-extensions (>= 0.1.0)
163
161
  websocket-extensions (0.1.5)
164
- zeitwerk (2.4.2)
162
+ zeitwerk (2.5.4)
165
163
 
166
164
  PLATFORMS
167
165
  ruby
@@ -169,11 +167,11 @@ PLATFORMS
169
167
 
170
168
  DEPENDENCIES
171
169
  minitest
172
- rails (>= 6.0, < 6.1)
170
+ rails (>= 6.0, < 7)
173
171
  rake (~> 13.0)
174
- rbs (>= 1.6)
172
+ rbs (>= 2)
175
173
  rbs_rails!
176
- steep!
174
+ steep
177
175
 
178
176
  BUNDLED WITH
179
- 2.2.27
177
+ 2.3.9
data/README.md CHANGED
@@ -20,12 +20,10 @@ Or install it yourself as:
20
20
 
21
21
  ## Usage
22
22
 
23
- Put the following code to `lib/tasks/rbs.rake`.
23
+ Run the following command. It generates `lib/tasks/rbs.rake`.
24
24
 
25
- ```ruby
26
- require 'rbs_rails/rake_task'
27
-
28
- RbsRails::RakeTask.new
25
+ ```console
26
+ $ bin/rails g rbs_rails:install
29
27
  ```
30
28
 
31
29
  Then, the following three tasks are available.
@@ -35,44 +33,30 @@ Then, the following three tasks are available.
35
33
  * `rbs_rails:all`: Execute all tasks of RBS Rails
36
34
 
37
35
 
36
+ ### Install RBS for `rails` gem
37
+
38
+ You need to install `rails` gem's RBS files. I highly recommend using `rbs collection`.
38
39
 
40
+ 1. Add `gem 'rails'` to your `Gemfile`.
41
+ 1. Then execute the following commands
42
+ ```console
43
+ $ bundle install
44
+ $ bundle exec rbs collection install
45
+ ```
39
46
 
40
47
  ### Steep integration
41
48
 
42
- You need to specify the following libraries by `Steepfile`.
49
+ Put the following code as `Steepfile`.
43
50
 
44
51
  ```ruby
45
- # Steepfile
46
-
47
52
  target :app do
48
53
  signature 'sig'
49
54
 
50
55
  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
- library 'time'
62
-
63
- library 'rack'
64
-
65
- library 'activesupport'
66
- library 'actionpack'
67
- library 'activejob'
68
- library 'activemodel'
69
- library 'actionview'
70
- library 'activerecord'
71
- library 'railties'
72
56
  end
73
57
  ```
74
58
 
75
- You need to put RBS repo to `path/to/rbs_repo`. See https://github.com/ruby/gem_rbs_collection
59
+ That's all! Now you can check your Rails app statically with `steep check` command.
76
60
 
77
61
  ## Development
78
62
 
@@ -0,0 +1,26 @@
1
+ require 'rails'
2
+
3
+ module RbsRails
4
+ class InstallGenerator < Rails::Generators::Base
5
+ def create_raketask
6
+ create_file "lib/tasks/rbs.rake", <<~RUBY
7
+ require 'rbs_rails/rake_task'
8
+
9
+ RbsRails::RakeTask.new do |task|
10
+ # If you want to avoid generating RBS for some classes, comment in it.
11
+ # default: nil
12
+ #
13
+ # task.ignore_model_if = -> (klass) { klass == MyClass }
14
+
15
+ # If you want to change the rake task namespace, comment in it.
16
+ # default: :rbs_rails
17
+ # task.name = :cool_rbs_rails
18
+
19
+ # If you want to change where RBS Rails writes RBSs into, comment in it.
20
+ # default: Rails.root / 'sig/rbs_rails'
21
+ # task.signature_root_dir = Rails.root / 'my_sig/rbs_rails'
22
+ end
23
+ RUBY
24
+ end
25
+ end
26
+ end
@@ -32,6 +32,8 @@ module RbsRails
32
32
 
33
33
  #{columns}
34
34
  #{associations}
35
+ #{generated_association_methods}
36
+ #{has_secure_password}
35
37
  #{delegated_type_instance}
36
38
  #{delegated_type_scope(singleton: true)}
37
39
  #{enum_instance_methods}
@@ -68,7 +70,7 @@ module RbsRails
68
70
 
69
71
  private def relation_decl
70
72
  <<~RBS
71
- class #{relation_class_name} < ActiveRecord::Relation
73
+ class #{relation_class_name} < ::ActiveRecord::Relation
72
74
  include GeneratedRelationMethods
73
75
  include _ActiveRecord_Relation[#{klass_name}, #{pk_type}]
74
76
  include Enumerable[#{klass_name}]
@@ -78,7 +80,7 @@ module RbsRails
78
80
 
79
81
  private def collection_proxy_decl
80
82
  <<~RBS
81
- class ActiveRecord_Associations_CollectionProxy < ActiveRecord::Associations::CollectionProxy
83
+ class ActiveRecord_Associations_CollectionProxy < ::ActiveRecord::Associations::CollectionProxy
82
84
  include GeneratedRelationMethods
83
85
  include _ActiveRecord_Relation[#{klass_name}, #{pk_type}]
84
86
  end
@@ -97,7 +99,7 @@ module RbsRails
97
99
  superclass_name = Util.module_name(superclass)
98
100
  @dependencies << superclass_name
99
101
 
100
- "class #{mod_name} < #{superclass_name}"
102
+ "class #{mod_name} < ::#{superclass_name}"
101
103
  when Module
102
104
  "module #{mod_name}"
103
105
  else
@@ -120,9 +122,13 @@ module RbsRails
120
122
 
121
123
  private def has_many
122
124
  klass.reflect_on_all_associations(:has_many).map do |a|
125
+ @dependencies << a.klass.name
126
+
123
127
  singular_name = a.name.to_s.singularize
124
128
  type = Util.module_name(a.klass)
125
129
  collection_type = "#{type}::ActiveRecord_Associations_CollectionProxy"
130
+ @dependencies << collection_type
131
+
126
132
  <<~RUBY.chomp
127
133
  def #{a.name}: () -> #{collection_type}
128
134
  def #{a.name}=: (#{collection_type} | Array[#{type}]) -> (#{collection_type} | Array[#{type}])
@@ -134,6 +140,8 @@ module RbsRails
134
140
 
135
141
  private def has_one
136
142
  klass.reflect_on_all_associations(:has_one).map do |a|
143
+ @dependencies << a.klass.name unless a.polymorphic?
144
+
137
145
  type = a.polymorphic? ? 'untyped' : Util.module_name(a.klass)
138
146
  type_optional = optional(type)
139
147
  <<~RUBY.chomp
@@ -149,6 +157,8 @@ module RbsRails
149
157
 
150
158
  private def belongs_to
151
159
  klass.reflect_on_all_associations(:belongs_to).map do |a|
160
+ @dependencies << a.klass.name unless a.polymorphic?
161
+
152
162
  type = a.polymorphic? ? 'untyped' : Util.module_name(a.klass)
153
163
  type_optional = optional(type)
154
164
  # @type var methods: Array[String]
@@ -165,6 +175,41 @@ module RbsRails
165
175
  end.join("\n")
166
176
  end
167
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
+
168
213
  private def delegated_type_scope(singleton:)
169
214
  definitions = delegated_type_definitions
170
215
  return "" unless definitions
@@ -236,12 +281,42 @@ module RbsRails
236
281
  end.compact
237
282
  end
238
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
+
239
314
  private def enum_instance_methods
240
315
  # @type var methods: Array[String]
241
316
  methods = []
242
317
  enum_definitions.each do |hash|
243
318
  hash.each do |name, values|
244
- next if name == :_prefix || name == :_suffix
319
+ next if name == :_prefix || name == :_suffix || name == :_default
245
320
 
246
321
  values.each do |label, value|
247
322
  value_method_name = enum_method_name(hash, name, label)
@@ -259,7 +334,7 @@ module RbsRails
259
334
  methods = []
260
335
  enum_definitions.each do |hash|
261
336
  hash.each do |name, values|
262
- next if name == :_prefix || name == :_suffix
337
+ next if name == :_prefix || name == :_suffix || name == :_default
263
338
 
264
339
  values.each do |label, value|
265
340
  value_method_name = enum_method_name(hash, name, label)
@@ -320,7 +395,9 @@ module RbsRails
320
395
  ast = parse_model_file
321
396
  return '' unless ast
322
397
 
323
- traverse(ast).map do |node|
398
+ prefix = singleton ? 'self.' : ''
399
+
400
+ sigs = traverse(ast).map do |node|
324
401
  # @type block: nil | String
325
402
  next unless node.type == :send
326
403
  next unless node.children[0].nil?
@@ -336,8 +413,16 @@ module RbsRails
336
413
  next unless body_node.type == :block
337
414
 
338
415
  args = args_to_type(body_node.children[1])
339
- "def #{singleton ? 'self.' : ''}#{name}: #{args} -> #{relation_class_name}"
340
- end.compact.join("\n")
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")
341
426
  end
342
427
 
343
428
  private def args_to_type(args_node)
@@ -396,7 +481,8 @@ module RbsRails
396
481
  end
397
482
 
398
483
  private def columns
399
- klass.columns.map do |col|
484
+ mod_sig = +"module GeneratedAttributeMethods\n"
485
+ mod_sig << klass.columns.map do |col|
400
486
  class_name = if enum_definitions.any? { |hash| hash.key?(col.name) || hash.key?(col.name.to_sym) }
401
487
  'String'
402
488
  else
@@ -405,7 +491,9 @@ module RbsRails
405
491
  class_name_opt = optional(class_name)
406
492
  column_type = col.null ? class_name_opt : class_name
407
493
  sig = <<~EOS
408
- attr_accessor #{col.name} (): #{column_type}
494
+ def #{col.name}: () -> #{column_type}
495
+ def #{col.name}=: (#{column_type}) -> #{column_type}
496
+ def #{col.name}?: () -> bool
409
497
  def #{col.name}_changed?: () -> bool
410
498
  def #{col.name}_change: () -> [#{class_name_opt}, #{class_name_opt}]
411
499
  def #{col.name}_will_change!: () -> void
@@ -422,9 +510,12 @@ module RbsRails
422
510
  def restore_#{col.name}!: () -> void
423
511
  def clear_#{col.name}_change: () -> void
424
512
  EOS
425
- sig << "attr_accessor #{col.name}? (): #{class_name}\n" if col.type == :boolean
513
+ sig << "\n"
426
514
  sig
427
515
  end.join("\n")
516
+ mod_sig << "\nend\n"
517
+ mod_sig << "include GeneratedAttributeMethods"
518
+ mod_sig
428
519
  end
429
520
 
430
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)
@@ -44,6 +44,7 @@ module RbsRails
44
44
 
45
45
  sig = RbsRails::ActiveRecord.class_to_rbs(klass, dependencies: dep_builder.deps)
46
46
  path.write sig
47
+ dep_builder.done << klass.name
47
48
  end
48
49
 
49
50
  if dep_rbs = dep_builder.build
@@ -2,5 +2,5 @@ module RbsRails
2
2
  # Because of copy_signatures is defined by lib/rbs_rails.rb
3
3
  # @dynamic self.copy_signatures
4
4
 
5
- VERSION = "0.9.0"
5
+ VERSION = "0.11.0"
6
6
  end
@@ -6,59 +6,31 @@ sources:
6
6
  repo_dir: gems
7
7
  path: ".gem_rbs_collection"
8
8
  gems:
9
- - name: pathname
10
- version: '0'
11
- source:
12
- type: stdlib
13
9
  - name: logger
14
10
  version: '0'
15
11
  source:
16
12
  type: stdlib
17
- - name: mutex_m
18
- version: '0'
19
- source:
20
- type: stdlib
21
- - name: date
22
- version: '0'
23
- source:
24
- type: stdlib
25
- - name: monitor
26
- version: '0'
27
- source:
28
- type: stdlib
29
- - name: singleton
30
- version: '0'
31
- source:
32
- type: stdlib
33
- - name: tsort
13
+ - name: set
34
14
  version: '0'
35
15
  source:
36
16
  type: stdlib
37
- - name: time
17
+ - name: pathname
38
18
  version: '0'
39
19
  source:
40
20
  type: stdlib
41
- - name: set
21
+ - name: json
42
22
  version: '0'
43
23
  source:
44
24
  type: stdlib
45
- - name: rack
46
- version: 2.2.2
47
- source:
48
- type: git
49
- name: ruby/gem_rbs_collection
50
- revision: 51880bed87fbc3dc8076fedb5cf798be05148220
51
- remote: https://github.com/ruby/gem_rbs_collection.git
52
- repo_dir: gems
53
- - name: json
25
+ - name: optparse
54
26
  version: '0'
55
27
  source:
56
28
  type: stdlib
57
- - name: strscan
29
+ - name: rubygems
58
30
  version: '0'
59
31
  source:
60
32
  type: stdlib
61
- - name: optparse
33
+ - name: tsort
62
34
  version: '0'
63
35
  source:
64
36
  type: stdlib
@@ -67,7 +39,7 @@ gems:
67
39
  source:
68
40
  type: git
69
41
  name: ruby/gem_rbs_collection
70
- revision: 51880bed87fbc3dc8076fedb5cf798be05148220
42
+ revision: 6320a194c85afbf4ff332c3eb75fcae2a6518c92
71
43
  remote: https://github.com/ruby/gem_rbs_collection.git
72
44
  repo_dir: gems
73
45
  - name: actionview
@@ -75,7 +47,7 @@ gems:
75
47
  source:
76
48
  type: git
77
49
  name: ruby/gem_rbs_collection
78
- revision: 51880bed87fbc3dc8076fedb5cf798be05148220
50
+ revision: 6320a194c85afbf4ff332c3eb75fcae2a6518c92
79
51
  remote: https://github.com/ruby/gem_rbs_collection.git
80
52
  repo_dir: gems
81
53
  - name: activejob
@@ -83,7 +55,7 @@ gems:
83
55
  source:
84
56
  type: git
85
57
  name: ruby/gem_rbs_collection
86
- revision: 51880bed87fbc3dc8076fedb5cf798be05148220
58
+ revision: 6320a194c85afbf4ff332c3eb75fcae2a6518c92
87
59
  remote: https://github.com/ruby/gem_rbs_collection.git
88
60
  repo_dir: gems
89
61
  - name: activemodel
@@ -91,15 +63,23 @@ gems:
91
63
  source:
92
64
  type: git
93
65
  name: ruby/gem_rbs_collection
94
- revision: 51880bed87fbc3dc8076fedb5cf798be05148220
66
+ revision: 6320a194c85afbf4ff332c3eb75fcae2a6518c92
95
67
  remote: https://github.com/ruby/gem_rbs_collection.git
96
68
  repo_dir: gems
97
69
  - name: activerecord
98
- version: '6.0'
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'
99
79
  source:
100
80
  type: git
101
81
  name: ruby/gem_rbs_collection
102
- revision: 51880bed87fbc3dc8076fedb5cf798be05148220
82
+ revision: 6320a194c85afbf4ff332c3eb75fcae2a6518c92
103
83
  remote: https://github.com/ruby/gem_rbs_collection.git
104
84
  repo_dir: gems
105
85
  - name: activesupport
@@ -107,7 +87,7 @@ gems:
107
87
  source:
108
88
  type: git
109
89
  name: ruby/gem_rbs_collection
110
- revision: 51880bed87fbc3dc8076fedb5cf798be05148220
90
+ revision: 6320a194c85afbf4ff332c3eb75fcae2a6518c92
111
91
  remote: https://github.com/ruby/gem_rbs_collection.git
112
92
  repo_dir: gems
113
93
  - name: parallel
@@ -115,7 +95,15 @@ gems:
115
95
  source:
116
96
  type: git
117
97
  name: ruby/gem_rbs_collection
118
- revision: 51880bed87fbc3dc8076fedb5cf798be05148220
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
119
107
  remote: https://github.com/ruby/gem_rbs_collection.git
120
108
  repo_dir: gems
121
109
  - name: railties
@@ -123,10 +111,34 @@ gems:
123
111
  source:
124
112
  type: git
125
113
  name: ruby/gem_rbs_collection
126
- revision: 51880bed87fbc3dc8076fedb5cf798be05148220
114
+ revision: 6320a194c85afbf4ff332c3eb75fcae2a6518c92
127
115
  remote: https://github.com/ruby/gem_rbs_collection.git
128
116
  repo_dir: gems
129
117
  - name: rbs
130
- version: 1.6.2
118
+ version: 2.2.2
131
119
  source:
132
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 CHANGED
@@ -9,25 +9,6 @@ sources:
9
9
  path: .gem_rbs_collection
10
10
 
11
11
  gems:
12
- # stdlibs
13
- - name: 'pathname'
14
- - name: 'logger'
15
- - name: 'mutex_m'
16
- - name: 'date'
17
- - name: 'monitor'
18
- - name: 'singleton'
19
- - name: 'tsort'
20
- - name: 'time'
21
- - name: 'set'
22
-
23
- # gems
24
- - name: 'rack'
25
-
26
- # RBS gem dependencies
27
- - name: 'json'
28
- - name: 'strscan'
29
- - name: 'optparse'
30
-
31
12
  # Ignores - Gemfile.lock contains them but their RBSs are unnecessary
32
13
  - name: steep
33
14
  ignore: true
@@ -43,3 +24,13 @@ gems:
43
24
  # ignore RBS Rails itself
44
25
  - name: rbs_rails
45
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
File without changes
@@ -0,0 +1,5 @@
1
+ class Thor
2
+ module Actions
3
+ def create_file: (String, String) -> void
4
+ end
5
+ end
@@ -0,0 +1,5 @@
1
+ module RbsRails
2
+ class InstallGenerator < Rails::Generators::Base
3
+ def create_raketask: () -> void
4
+ end
5
+ end
@@ -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
 
@@ -32,12 +33,16 @@ class RbsRails::ActiveRecord::Generator
32
33
 
33
34
  def belongs_to: () -> String
34
35
 
36
+ def generated_association_methods: () -> String
37
+
35
38
  def delegated_type_scope: (singleton: bool) -> String
36
39
 
37
40
  def delegated_type_instance: () -> String
38
41
 
39
42
  def delegated_type_definitions: () -> Array[{ role: Symbol, types: Array[String] }]?
40
43
 
44
+ def has_secure_password: () -> String?
45
+
41
46
  def enum_instance_methods: () -> String
42
47
 
43
48
  def enum_scope_methods: (singleton: untyped `singleton`) -> String
@@ -1,6 +1,7 @@
1
1
  module RbsRails
2
2
  class DependencyBuilder
3
3
  attr_reader deps: Array[String]
4
+ attr_reader done: Set[String]
4
5
 
5
6
  def initialize: () -> void
6
7
 
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.9.0
4
+ version: 0.11.0
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: 2021-09-18 00:00:00.000000000 Z
11
+ date: 2022-03-24 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
@@ -62,6 +63,7 @@ files:
62
63
  - bin/rbs-prototype-rb.rb
63
64
  - bin/setup
64
65
  - bin/to-ascii.rb
66
+ - lib/generators/rbs_rails/install_generator.rb
65
67
  - lib/rbs_rails.rb
66
68
  - lib/rbs_rails/active_record.rb
67
69
  - lib/rbs_rails/dependency_builder.rb
@@ -72,8 +74,10 @@ files:
72
74
  - rbs_collection.lock.yaml
73
75
  - rbs_collection.yaml
74
76
  - rbs_rails.gemspec
75
- - sig/activerecord.rbs
76
- - sig/fileutils.rbs
77
+ - sig/_internal/activerecord.rbs
78
+ - sig/_internal/fileutils.rbs
79
+ - sig/_internal/thor.rbs
80
+ - sig/install_generator.rbs
77
81
  - sig/parser.rbs
78
82
  - sig/rake.rbs
79
83
  - sig/rbs_rails.rbs
@@ -105,7 +109,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
105
109
  - !ruby/object:Gem::Version
106
110
  version: '0'
107
111
  requirements: []
108
- rubygems_version: 3.3.0.dev
112
+ rubygems_version: 3.4.0.dev
109
113
  signing_key:
110
114
  specification_version: 4
111
115
  summary: A RBS files generator for Rails application