rbs_rails 0.11.0 → 0.12.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.github/workflows/ci.yml +1 -1
- data/CHANGELOG.md +13 -0
- data/Gemfile +3 -3
- data/Gemfile.lock +179 -125
- data/README.md +1 -0
- data/Steepfile +5 -0
- data/lib/generators/rbs_rails/install_generator.rb +16 -12
- data/lib/rbs_rails/active_record.rb +58 -46
- data/lib/rbs_rails/dependency_builder.rb +5 -1
- data/lib/rbs_rails/rake_task.rb +7 -7
- data/lib/rbs_rails/util.rb +14 -10
- data/lib/rbs_rails/version.rb +1 -1
- data/rbs_collection.lock.yaml +228 -48
- data/rbs_collection.yaml +0 -2
- data/rbs_rails.gemspec +1 -1
- data/sig/rbs_rails/active_record.rbs +9 -3
- data/sig/rbs_rails/dependency_builder.rbs +4 -0
- data/sig/rbs_rails/rake_task.rbs +1 -1
- data/sig/rbs_rails/util.rbs +1 -1
- metadata +4 -9
- data/sig/_internal/fileutils.rbs +0 -4
- data/sig/_internal/thor.rbs +0 -5
@@ -12,12 +12,14 @@ module RbsRails
|
|
12
12
|
end
|
13
13
|
|
14
14
|
class Generator
|
15
|
+
IGNORED_ENUM_KEYS = %i[_prefix _suffix _default _scopes]
|
16
|
+
|
15
17
|
def initialize(klass, dependencies:)
|
16
18
|
@klass = klass
|
17
19
|
@dependencies = dependencies
|
18
|
-
@klass_name = Util.module_name(klass)
|
20
|
+
@klass_name = Util.module_name(klass, abs: false)
|
19
21
|
|
20
|
-
namespaces = klass_name.split('::').tap{ |names| names.pop }
|
22
|
+
namespaces = klass_name(abs: false).split('::').tap{ |names| names.pop }
|
21
23
|
@dependencies << namespaces.join('::') unless namespaces.empty?
|
22
24
|
end
|
23
25
|
|
@@ -28,7 +30,7 @@ module RbsRails
|
|
28
30
|
private def klass_decl
|
29
31
|
<<~RBS
|
30
32
|
#{header}
|
31
|
-
extend _ActiveRecord_Relation_ClassMethods[#{klass_name}, #{relation_class_name}, #{pk_type}]
|
33
|
+
extend ::_ActiveRecord_Relation_ClassMethods[#{klass_name}, #{relation_class_name}, #{pk_type}]
|
32
34
|
|
33
35
|
#{columns}
|
34
36
|
#{associations}
|
@@ -60,7 +62,7 @@ module RbsRails
|
|
60
62
|
|
61
63
|
private def generated_relation_methods_decl
|
62
64
|
<<~RBS
|
63
|
-
module
|
65
|
+
module #{generated_relation_methods_name(abs: false)}
|
64
66
|
#{enum_scope_methods(singleton: false)}
|
65
67
|
#{scopes(singleton: false)}
|
66
68
|
#{delegated_type_scope(singleton: false)}
|
@@ -70,10 +72,10 @@ module RbsRails
|
|
70
72
|
|
71
73
|
private def relation_decl
|
72
74
|
<<~RBS
|
73
|
-
class #{relation_class_name} < ::ActiveRecord::Relation
|
74
|
-
include
|
75
|
-
include _ActiveRecord_Relation[#{klass_name}, #{pk_type}]
|
76
|
-
include Enumerable[#{klass_name}]
|
75
|
+
class #{relation_class_name(abs: false)} < ::ActiveRecord::Relation
|
76
|
+
include #{generated_relation_methods_name}
|
77
|
+
include ::_ActiveRecord_Relation[#{klass_name}, #{pk_type}]
|
78
|
+
include ::Enumerable[#{klass_name}]
|
77
79
|
end
|
78
80
|
RBS
|
79
81
|
end
|
@@ -81,22 +83,22 @@ module RbsRails
|
|
81
83
|
private def collection_proxy_decl
|
82
84
|
<<~RBS
|
83
85
|
class ActiveRecord_Associations_CollectionProxy < ::ActiveRecord::Associations::CollectionProxy
|
84
|
-
include
|
85
|
-
include _ActiveRecord_Relation[#{klass_name}, #{pk_type}]
|
86
|
+
include #{generated_relation_methods_name}
|
87
|
+
include ::_ActiveRecord_Relation[#{klass_name}, #{pk_type}]
|
86
88
|
end
|
87
89
|
RBS
|
88
90
|
end
|
89
91
|
|
90
92
|
private def header
|
91
93
|
namespace = +''
|
92
|
-
klass_name.split('::').map do |mod_name|
|
94
|
+
klass_name(abs: false).split('::').map do |mod_name|
|
93
95
|
namespace += "::#{mod_name}"
|
94
96
|
mod_object = Object.const_get(namespace)
|
95
97
|
case mod_object
|
96
98
|
when Class
|
97
99
|
# @type var superclass: Class
|
98
100
|
superclass = _ = mod_object.superclass
|
99
|
-
superclass_name = Util.module_name(superclass)
|
101
|
+
superclass_name = Util.module_name(superclass, abs: false)
|
100
102
|
@dependencies << superclass_name
|
101
103
|
|
102
104
|
"class #{mod_name} < ::#{superclass_name}"
|
@@ -109,7 +111,7 @@ module RbsRails
|
|
109
111
|
end
|
110
112
|
|
111
113
|
private def footer
|
112
|
-
"end\n" * klass_name.split('::').size
|
114
|
+
"end\n" * klass_name(abs: false).split('::').size
|
113
115
|
end
|
114
116
|
|
115
117
|
private def associations
|
@@ -131,9 +133,9 @@ module RbsRails
|
|
131
133
|
|
132
134
|
<<~RUBY.chomp
|
133
135
|
def #{a.name}: () -> #{collection_type}
|
134
|
-
def #{a.name}=: (#{collection_type} | Array[#{type}]) -> (#{collection_type} | Array[#{type}])
|
135
|
-
def #{singular_name}_ids: () -> Array[Integer]
|
136
|
-
def #{singular_name}_ids=: (Array[Integer]) -> Array[Integer]
|
136
|
+
def #{a.name}=: (#{collection_type} | ::Array[#{type}]) -> (#{collection_type} | ::Array[#{type}])
|
137
|
+
def #{singular_name}_ids: () -> ::Array[::Integer]
|
138
|
+
def #{singular_name}_ids=: (::Array[::Integer]) -> ::Array[::Integer]
|
137
139
|
RUBY
|
138
140
|
end.join("\n")
|
139
141
|
end
|
@@ -147,7 +149,7 @@ module RbsRails
|
|
147
149
|
<<~RUBY.chomp
|
148
150
|
def #{a.name}: () -> #{type_optional}
|
149
151
|
def #{a.name}=: (#{type_optional}) -> #{type_optional}
|
150
|
-
def build_#{a.name}: (untyped) -> #{type}
|
152
|
+
def build_#{a.name}: (?untyped) -> #{type}
|
151
153
|
def create_#{a.name}: (untyped) -> #{type}
|
152
154
|
def create_#{a.name}!: (untyped) -> #{type}
|
153
155
|
def reload_#{a.name}: () -> #{type_optional}
|
@@ -159,11 +161,13 @@ module RbsRails
|
|
159
161
|
klass.reflect_on_all_associations(:belongs_to).map do |a|
|
160
162
|
@dependencies << a.klass.name unless a.polymorphic?
|
161
163
|
|
164
|
+
is_optional = a.options[:optional]
|
165
|
+
|
162
166
|
type = a.polymorphic? ? 'untyped' : Util.module_name(a.klass)
|
163
167
|
type_optional = optional(type)
|
164
168
|
# @type var methods: Array[String]
|
165
169
|
methods = []
|
166
|
-
methods << "def #{a.name}: () -> #{type}"
|
170
|
+
methods << "def #{a.name}: () -> #{is_optional ? type_optional : type}"
|
167
171
|
methods << "def #{a.name}=: (#{type_optional}) -> #{type_optional}"
|
168
172
|
methods << "def reload_#{a.name}: () -> #{type_optional}"
|
169
173
|
if !a.polymorphic?
|
@@ -186,21 +190,21 @@ module RbsRails
|
|
186
190
|
case reflection.macro
|
187
191
|
when :has_one_attached
|
188
192
|
<<~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? }
|
193
|
+
def #{name}: () -> ::ActiveStorage::Attached::One
|
194
|
+
def #{name}=: (::ActionDispatch::Http::UploadedFile) -> ::ActionDispatch::Http::UploadedFile
|
195
|
+
| (::Rack::Test::UploadedFile) -> ::Rack::Test::UploadedFile
|
196
|
+
| (::ActiveStorage::Blob) -> ::ActiveStorage::Blob
|
197
|
+
| (::String) -> ::String
|
198
|
+
| ({ io: ::IO, filename: ::String, content_type: ::String? }) -> { io: ::IO, filename: ::String, content_type: ::String? }
|
195
199
|
| (nil) -> nil
|
196
200
|
EOS
|
197
201
|
when :has_many_attached
|
198
202
|
<<~EOS
|
199
|
-
def #{name}: () -> ActiveStorage::Attached::Many
|
203
|
+
def #{name}: () -> ::ActiveStorage::Attached::Many
|
200
204
|
def #{name}=: (untyped) -> untyped
|
201
205
|
EOS
|
202
206
|
else
|
203
|
-
raise
|
207
|
+
raise "unknown macro: #{reflection.macro}"
|
204
208
|
end
|
205
209
|
end.join("\n")
|
206
210
|
sigs << "end"
|
@@ -316,7 +320,7 @@ module RbsRails
|
|
316
320
|
methods = []
|
317
321
|
enum_definitions.each do |hash|
|
318
322
|
hash.each do |name, values|
|
319
|
-
next if name
|
323
|
+
next if IGNORED_ENUM_KEYS.include?(name)
|
320
324
|
|
321
325
|
values.each do |label, value|
|
322
326
|
value_method_name = enum_method_name(hash, name, label)
|
@@ -334,7 +338,7 @@ module RbsRails
|
|
334
338
|
methods = []
|
335
339
|
enum_definitions.each do |hash|
|
336
340
|
hash.each do |name, values|
|
337
|
-
next if name
|
341
|
+
next if IGNORED_ENUM_KEYS.include?(name)
|
338
342
|
|
339
343
|
values.each do |label, value|
|
340
344
|
value_method_name = enum_method_name(hash, name, label)
|
@@ -456,7 +460,7 @@ module RbsRails
|
|
456
460
|
private def parse_model_file
|
457
461
|
return @parse_model_file if defined?(@parse_model_file)
|
458
462
|
|
459
|
-
path = Rails.root.join('app/models/', klass_name.underscore + '.rb')
|
463
|
+
path = Rails.root.join('app/models/', klass_name(abs: false).underscore + '.rb')
|
460
464
|
return @parse_model_file = nil unless path.exist?
|
461
465
|
return [] unless path.exist?
|
462
466
|
|
@@ -467,24 +471,32 @@ module RbsRails
|
|
467
471
|
end
|
468
472
|
|
469
473
|
private def traverse(node, &block)
|
470
|
-
return to_enum(__method__ || raise, node) unless
|
474
|
+
return to_enum(__method__ || raise, node) unless block
|
471
475
|
|
472
|
-
# @type var block: ^(Parser::AST::Node) -> untyped
|
473
476
|
block.call node
|
474
477
|
node.children.each do |child|
|
475
478
|
traverse(child, &block) if child.is_a?(Parser::AST::Node)
|
476
479
|
end
|
477
480
|
end
|
478
481
|
|
479
|
-
private def relation_class_name
|
480
|
-
"ActiveRecord_Relation"
|
482
|
+
private def relation_class_name(abs: true)
|
483
|
+
abs ? "#{klass_name}::ActiveRecord_Relation" : "ActiveRecord_Relation"
|
484
|
+
end
|
485
|
+
|
486
|
+
private def klass_name(abs: true)
|
487
|
+
abs ? "::#{@klass_name}" : @klass_name
|
481
488
|
end
|
482
489
|
|
490
|
+
private def generated_relation_methods_name(abs: true)
|
491
|
+
abs ? "#{klass_name}::GeneratedRelationMethods" : "GeneratedRelationMethods"
|
492
|
+
end
|
493
|
+
|
494
|
+
|
483
495
|
private def columns
|
484
496
|
mod_sig = +"module GeneratedAttributeMethods\n"
|
485
497
|
mod_sig << klass.columns.map do |col|
|
486
498
|
class_name = if enum_definitions.any? { |hash| hash.key?(col.name) || hash.key?(col.name.to_sym) }
|
487
|
-
'String'
|
499
|
+
'::String'
|
488
500
|
else
|
489
501
|
sql_type_to_class(col.type)
|
490
502
|
end
|
@@ -499,12 +511,12 @@ module RbsRails
|
|
499
511
|
def #{col.name}_will_change!: () -> void
|
500
512
|
def #{col.name}_was: () -> #{class_name_opt}
|
501
513
|
def #{col.name}_previously_changed?: () -> bool
|
502
|
-
def #{col.name}_previous_change: () -> Array[#{class_name_opt}]?
|
514
|
+
def #{col.name}_previous_change: () -> ::Array[#{class_name_opt}]?
|
503
515
|
def #{col.name}_previously_was: () -> #{class_name_opt}
|
504
516
|
def #{col.name}_before_last_save: () -> #{class_name_opt}
|
505
|
-
def #{col.name}_change_to_be_saved: () -> Array[#{class_name_opt}]?
|
517
|
+
def #{col.name}_change_to_be_saved: () -> ::Array[#{class_name_opt}]?
|
506
518
|
def #{col.name}_in_database: () -> #{class_name_opt}
|
507
|
-
def saved_change_to_#{col.name}: () -> Array[#{class_name_opt}]?
|
519
|
+
def saved_change_to_#{col.name}: () -> ::Array[#{class_name_opt}]?
|
508
520
|
def saved_change_to_#{col.name}?: () -> bool
|
509
521
|
def will_save_change_to_#{col.name}?: () -> bool
|
510
522
|
def restore_#{col.name}!: () -> void
|
@@ -525,25 +537,25 @@ module RbsRails
|
|
525
537
|
private def sql_type_to_class(t)
|
526
538
|
case t
|
527
539
|
when :integer
|
528
|
-
'Integer'
|
540
|
+
'::Integer'
|
529
541
|
when :float
|
530
|
-
'Float'
|
542
|
+
'::Float'
|
531
543
|
when :decimal
|
532
|
-
'BigDecimal'
|
544
|
+
'::BigDecimal'
|
533
545
|
when :string, :text, :citext, :uuid, :binary
|
534
|
-
'String'
|
546
|
+
'::String'
|
535
547
|
when :datetime
|
536
|
-
'ActiveSupport::TimeWithZone'
|
548
|
+
'::ActiveSupport::TimeWithZone'
|
537
549
|
when :boolean
|
538
550
|
"bool"
|
539
551
|
when :jsonb, :json
|
540
552
|
"untyped"
|
541
553
|
when :date
|
542
|
-
'Date'
|
554
|
+
'::Date'
|
543
555
|
when :time
|
544
|
-
'Time'
|
556
|
+
'::Time'
|
545
557
|
when :inet
|
546
|
-
"IPAddr"
|
558
|
+
"::IPAddr"
|
547
559
|
else
|
548
560
|
# Unknown column type, give up
|
549
561
|
'untyped'
|
@@ -551,7 +563,7 @@ module RbsRails
|
|
551
563
|
end
|
552
564
|
|
553
565
|
private
|
554
|
-
attr_reader :klass
|
566
|
+
attr_reader :klass
|
555
567
|
end
|
556
568
|
end
|
557
569
|
end
|
@@ -10,7 +10,7 @@ module RbsRails
|
|
10
10
|
def build
|
11
11
|
dep_rbs = +""
|
12
12
|
deps.uniq!
|
13
|
-
while dep =
|
13
|
+
while dep = shift
|
14
14
|
next unless done.add?(dep)
|
15
15
|
|
16
16
|
case dep_object = Object.const_get(dep)
|
@@ -39,5 +39,9 @@ module RbsRails
|
|
39
39
|
Util.format_rbs(dep_rbs)
|
40
40
|
end
|
41
41
|
end
|
42
|
+
|
43
|
+
private def shift
|
44
|
+
deps.shift&.sub(/^::/, '')
|
45
|
+
end
|
42
46
|
end
|
43
47
|
end
|
data/lib/rbs_rails/rake_task.rb
CHANGED
@@ -3,17 +3,17 @@ require 'rake/tasklib'
|
|
3
3
|
|
4
4
|
module RbsRails
|
5
5
|
class RakeTask < Rake::TaskLib
|
6
|
-
attr_accessor :ignore_model_if, :name
|
6
|
+
attr_accessor :ignore_model_if, :name
|
7
|
+
attr_writer :signature_root_dir
|
7
8
|
|
8
9
|
def initialize(name = :rbs_rails, &block)
|
9
10
|
super()
|
10
11
|
|
11
12
|
@name = name
|
13
|
+
@signature_root_dir = Rails.root / 'sig/rbs_rails'
|
12
14
|
|
13
15
|
block.call(self) if block
|
14
16
|
|
15
|
-
setup_signature_root_dir!
|
16
|
-
|
17
17
|
def_generate_rbs_for_models
|
18
18
|
def_generate_rbs_for_path_helpers
|
19
19
|
def_all
|
@@ -64,10 +64,10 @@ module RbsRails
|
|
64
64
|
end
|
65
65
|
end
|
66
66
|
|
67
|
-
private def
|
68
|
-
@signature_root_dir
|
69
|
-
|
70
|
-
|
67
|
+
private def signature_root_dir
|
68
|
+
Pathname(@signature_root_dir).tap do |dir|
|
69
|
+
dir.mkpath
|
70
|
+
end
|
71
71
|
end
|
72
72
|
end
|
73
73
|
end
|
data/lib/rbs_rails/util.rb
CHANGED
@@ -4,19 +4,23 @@ module RbsRails
|
|
4
4
|
|
5
5
|
extend self
|
6
6
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
end
|
12
|
-
else
|
13
|
-
def module_name(mod)
|
14
|
-
MODULE_NAME.bind(mod).call
|
15
|
-
end
|
7
|
+
def module_name(mod, abs: true)
|
8
|
+
name = MODULE_NAME.bind_call(mod)
|
9
|
+
name ="::#{name}" if abs
|
10
|
+
name
|
16
11
|
end
|
17
12
|
|
18
13
|
def format_rbs(rbs)
|
19
|
-
decls =
|
14
|
+
decls =
|
15
|
+
if Gem::Version.new('3') <= Gem::Version.new(RBS::VERSION)
|
16
|
+
parsed = _ = RBS::Parser.parse_signature(rbs)
|
17
|
+
parsed[1] + parsed[2]
|
18
|
+
else
|
19
|
+
# TODO: Remove this type annotation when rbs_rails drops support of RBS 2.x.
|
20
|
+
# @type var parsed: [RBS::Declarations::t]
|
21
|
+
parsed = _ = RBS::Parser.parse_signature(rbs)
|
22
|
+
end
|
23
|
+
|
20
24
|
StringIO.new.tap do |io|
|
21
25
|
RBS::Writer.new(out: io).write(decls)
|
22
26
|
end.string
|
data/lib/rbs_rails/version.rb
CHANGED