tapioca 0.10.4 → 0.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. checksums.yaml +4 -4
  2. data/lib/tapioca/cli.rb +14 -5
  3. data/lib/tapioca/commands/annotations.rb +2 -0
  4. data/lib/tapioca/commands/configure.rb +1 -0
  5. data/lib/tapioca/commands/dsl.rb +17 -3
  6. data/lib/tapioca/commands/gem.rb +4 -2
  7. data/lib/tapioca/dsl/compilers/aasm.rb +78 -17
  8. data/lib/tapioca/dsl/compilers/action_controller_helpers.rb +1 -1
  9. data/lib/tapioca/dsl/compilers/active_record_columns.rb +3 -3
  10. data/lib/tapioca/dsl/compilers/active_record_fixtures.rb +8 -5
  11. data/lib/tapioca/dsl/compilers/active_record_relations.rb +140 -83
  12. data/lib/tapioca/dsl/compilers/active_record_scope.rb +1 -1
  13. data/lib/tapioca/dsl/compilers/active_record_secure_token.rb +74 -0
  14. data/lib/tapioca/dsl/compilers/active_record_typed_store.rb +14 -11
  15. data/lib/tapioca/dsl/compilers/active_resource.rb +22 -15
  16. data/lib/tapioca/dsl/compilers/active_storage.rb +4 -2
  17. data/lib/tapioca/dsl/compilers/graphql_input_object.rb +21 -1
  18. data/lib/tapioca/dsl/compilers/kredis.rb +130 -0
  19. data/lib/tapioca/dsl/compilers/smart_properties.rb +7 -4
  20. data/lib/tapioca/dsl/compilers/url_helpers.rb +7 -4
  21. data/lib/tapioca/dsl/extensions/active_record.rb +9 -0
  22. data/lib/tapioca/dsl/extensions/kredis.rb +114 -0
  23. data/lib/tapioca/dsl/helpers/active_record_column_type_helper.rb +37 -27
  24. data/lib/tapioca/dsl/helpers/active_record_constants_helper.rb +1 -0
  25. data/lib/tapioca/dsl/pipeline.rb +12 -5
  26. data/lib/tapioca/gem/listeners/sorbet_enums.rb +1 -1
  27. data/lib/tapioca/gem/listeners/yard_doc.rb +13 -10
  28. data/lib/tapioca/gem/pipeline.rb +14 -0
  29. data/lib/tapioca/gemfile.rb +6 -2
  30. data/lib/tapioca/helpers/rbi_files_helper.rb +12 -6
  31. data/lib/tapioca/helpers/sorbet_helper.rb +7 -4
  32. data/lib/tapioca/helpers/source_uri.rb +10 -7
  33. data/lib/tapioca/loaders/gem.rb +4 -2
  34. data/lib/tapioca/loaders/loader.rb +99 -35
  35. data/lib/tapioca/rbi_ext/model.rb +8 -3
  36. data/lib/tapioca/rbi_formatter.rb +11 -8
  37. data/lib/tapioca/runtime/attached_class_of_32.rb +20 -0
  38. data/lib/tapioca/runtime/attached_class_of_legacy.rb +27 -0
  39. data/lib/tapioca/runtime/reflection.rb +11 -10
  40. data/lib/tapioca/runtime/trackers.rb +17 -0
  41. data/lib/tapioca/static/symbol_loader.rb +14 -14
  42. data/lib/tapioca/version.rb +1 -1
  43. data/lib/tapioca.rb +8 -5
  44. metadata +7 -2
@@ -164,16 +164,10 @@ module Tapioca
164
164
 
165
165
  sig { override.void }
166
166
  def decorate
167
- root.create_path(constant) do |model|
168
- relation_methods_module = model.create_module(RelationMethodsModuleName)
169
- association_relation_methods_module = model.create_module(AssociationRelationMethodsModuleName)
170
- common_relation_methods_module = model.create_module(CommonRelationMethodsModuleName)
171
-
172
- create_classes_and_includes(model)
173
- create_common_methods(common_relation_methods_module)
174
- create_relation_methods(relation_methods_module, association_relation_methods_module)
175
- create_association_relation_methods(association_relation_methods_module)
176
- end
167
+ create_classes_and_includes
168
+ create_common_methods
169
+ create_relation_methods
170
+ create_association_relation_methods
177
171
  end
178
172
 
179
173
  class << self
@@ -181,7 +175,7 @@ module Tapioca
181
175
 
182
176
  sig { override.returns(T::Enumerable[Module]) }
183
177
  def gather_constants
184
- ActiveRecord::Base.descendants.reject(&:abstract_class?)
178
+ descendants_of(ActiveRecord::Base).reject(&:abstract_class?)
185
179
  end
186
180
  end
187
181
 
@@ -196,28 +190,35 @@ module Tapioca
196
190
  T::Array[Symbol],
197
191
  )
198
192
 
199
- QUERY_METHODS = T.let(begin
200
- # Grab all Query methods
201
- query_methods = ActiveRecord::QueryMethods.instance_methods(false)
202
- # Grab all Spawn methods
203
- query_methods |= ActiveRecord::SpawnMethods.instance_methods(false)
204
- # Remove the ones we know are private API
205
- query_methods -= [:arel, :build_subquery, :construct_join_dependency, :extensions, :spawn]
206
- # Remove "where" which needs a custom return type for WhereChains
207
- query_methods -= [:where]
208
- # Remove the methods that ...
209
- query_methods
210
- .grep_v(/_clause$/) # end with "_clause"
211
- .grep_v(/_values?$/) # end with "_value" or "_values"
212
- .grep_v(/=$/) # end with "=""
213
- .grep_v(/(?<!uniq)!$/) # end with "!" except for "uniq!"
214
- end, T::Array[Symbol])
193
+ QUERY_METHODS = T.let(
194
+ begin
195
+ # Grab all Query methods
196
+ query_methods = ActiveRecord::QueryMethods.instance_methods(false)
197
+ # Grab all Spawn methods
198
+ query_methods |= ActiveRecord::SpawnMethods.instance_methods(false)
199
+ # Remove the ones we know are private API
200
+ query_methods -= [:arel, :build_subquery, :construct_join_dependency, :extensions, :spawn]
201
+ # Remove "where" which needs a custom return type for WhereChains
202
+ query_methods -= [:where]
203
+ # Remove the methods that ...
204
+ query_methods
205
+ .grep_v(/_clause$/) # end with "_clause"
206
+ .grep_v(/_values?$/) # end with "_value" or "_values"
207
+ .grep_v(/=$/) # end with "=""
208
+ .grep_v(/(?<!uniq)!$/) # end with "!" except for "uniq!"
209
+ end,
210
+ T::Array[Symbol],
211
+ )
215
212
  WHERE_CHAIN_QUERY_METHODS = T.let(
216
213
  ActiveRecord::QueryMethods::WhereChain.instance_methods(false),
217
214
  T::Array[Symbol],
218
215
  )
219
216
  FINDER_METHODS = T.let(ActiveRecord::FinderMethods.instance_methods(false), T::Array[Symbol])
220
- SIGNED_FINDER_METHODS = T.let(ActiveRecord::SignedId::ClassMethods.instance_methods(false), T::Array[Symbol])
217
+ SIGNED_FINDER_METHODS = T.let(
218
+ defined?(ActiveRecord::SignedId) ? ActiveRecord::SignedId::ClassMethods.instance_methods(false) : [],
219
+ T::Array[Symbol],
220
+ )
221
+ BATCHES_METHODS = T.let(ActiveRecord::Batches.instance_methods(false), T::Array[Symbol])
221
222
  CALCULATION_METHODS = T.let(ActiveRecord::Calculations.instance_methods(false), T::Array[Symbol])
222
223
  ENUMERABLE_QUERY_METHODS = T.let([:any?, :many?, :none?, :one?], T::Array[Symbol])
223
224
  FIND_OR_CREATE_METHODS = T.let(
@@ -228,6 +229,38 @@ module Tapioca
228
229
 
229
230
  private
230
231
 
232
+ sig { returns(RBI::Scope) }
233
+ def model
234
+ @model ||= T.let(
235
+ root.create_path(constant),
236
+ T.nilable(RBI::Scope),
237
+ )
238
+ end
239
+
240
+ sig { returns(RBI::Scope) }
241
+ def relation_methods_module
242
+ @relation_methods_module ||= T.let(
243
+ model.create_module(RelationMethodsModuleName),
244
+ T.nilable(RBI::Scope),
245
+ )
246
+ end
247
+
248
+ sig { returns(RBI::Scope) }
249
+ def association_relation_methods_module
250
+ @association_relation_methods_module ||= T.let(
251
+ model.create_module(AssociationRelationMethodsModuleName),
252
+ T.nilable(RBI::Scope),
253
+ )
254
+ end
255
+
256
+ sig { returns(RBI::Scope) }
257
+ def common_relation_methods_module
258
+ @common_relation_methods_module ||= T.let(
259
+ model.create_module(CommonRelationMethodsModuleName),
260
+ T.nilable(RBI::Scope),
261
+ )
262
+ end
263
+
231
264
  sig { returns(String) }
232
265
  def constant_name
233
266
  @constant_name ||= T.let(T.must(qualified_name_of(constant)), T.nilable(String))
@@ -238,8 +271,8 @@ module Tapioca
238
271
  method_name.to_s.end_with?("!")
239
272
  end
240
273
 
241
- sig { params(model: RBI::Scope).void }
242
- def create_classes_and_includes(model)
274
+ sig { void }
275
+ def create_classes_and_includes
243
276
  model.create_extend(CommonRelationMethodsModuleName)
244
277
  # The model always extends the generated relation module
245
278
  model.create_extend(RelationMethodsModuleName)
@@ -248,13 +281,13 @@ module Tapioca
248
281
  # See https://github.com/sorbet/sorbet/pull/4706 for details
249
282
  model.create_method("to_ary", return_type: "NilClass", visibility: RBI::Private.new)
250
283
 
251
- create_relation_class(model)
252
- create_association_relation_class(model)
253
- create_collection_proxy_class(model)
284
+ create_relation_class
285
+ create_association_relation_class
286
+ create_collection_proxy_class
254
287
  end
255
288
 
256
- sig { params(model: RBI::Scope).void }
257
- def create_relation_class(model)
289
+ sig { void }
290
+ def create_relation_class
258
291
  superclass = "::ActiveRecord::Relation"
259
292
 
260
293
  # The relation subclass includes the generated relation module
@@ -266,11 +299,11 @@ module Tapioca
266
299
  klass.create_method("to_ary", return_type: "T::Array[#{constant_name}]")
267
300
  end
268
301
 
269
- create_relation_where_chain_class(model)
302
+ create_relation_where_chain_class
270
303
  end
271
304
 
272
- sig { params(model: RBI::Scope).void }
273
- def create_association_relation_class(model)
305
+ sig { void }
306
+ def create_association_relation_class
274
307
  superclass = "::ActiveRecord::AssociationRelation"
275
308
 
276
309
  # Association subclasses include the generated association relation module
@@ -282,19 +315,19 @@ module Tapioca
282
315
  klass.create_method("to_ary", return_type: "T::Array[#{constant_name}]")
283
316
  end
284
317
 
285
- create_association_relation_where_chain_class(model)
318
+ create_association_relation_where_chain_class
286
319
  end
287
320
 
288
- sig { params(model: RBI::Scope).void }
289
- def create_relation_where_chain_class(model)
321
+ sig { void }
322
+ def create_relation_where_chain_class
290
323
  model.create_class(RelationWhereChainClassName, superclass_name: RelationClassName) do |klass|
291
324
  create_where_chain_methods(klass, RelationClassName)
292
325
  klass.create_type_variable("Elem", type: "type_member", fixed: constant_name)
293
326
  end
294
327
  end
295
328
 
296
- sig { params(model: RBI::Scope).void }
297
- def create_association_relation_where_chain_class(model)
329
+ sig { void }
330
+ def create_association_relation_where_chain_class
298
331
  model.create_class(
299
332
  AssociationRelationWhereChainClassName,
300
333
  superclass_name: AssociationRelationClassName,
@@ -329,8 +362,8 @@ module Tapioca
329
362
  end
330
363
  end
331
364
 
332
- sig { params(model: RBI::Scope).void }
333
- def create_collection_proxy_class(model)
365
+ sig { void }
366
+ def create_collection_proxy_class
334
367
  superclass = "::ActiveRecord::Associations::CollectionProxy"
335
368
 
336
369
  # The relation subclass includes the generated association relation module
@@ -423,13 +456,11 @@ module Tapioca
423
456
  end
424
457
  end
425
458
 
426
- sig { params(relation_methods_module: RBI::Scope, association_relation_methods_module: RBI::Scope).void }
427
- def create_relation_methods(relation_methods_module, association_relation_methods_module)
428
- create_relation_method("all", relation_methods_module, association_relation_methods_module)
459
+ sig { void }
460
+ def create_relation_methods
461
+ create_relation_method("all")
429
462
  create_relation_method(
430
463
  "where",
431
- relation_methods_module,
432
- association_relation_methods_module,
433
464
  parameters: [
434
465
  create_rest_param("args", type: "T.untyped"),
435
466
  create_block_param("blk", type: "T.untyped"),
@@ -441,8 +472,6 @@ module Tapioca
441
472
  QUERY_METHODS.each do |method_name|
442
473
  create_relation_method(
443
474
  method_name,
444
- relation_methods_module,
445
- association_relation_methods_module,
446
475
  parameters: [
447
476
  create_rest_param("args", type: "T.untyped"),
448
477
  create_block_param("blk", type: "T.untyped"),
@@ -451,8 +480,8 @@ module Tapioca
451
480
  end
452
481
  end
453
482
 
454
- sig { params(association_relation_methods_module: RBI::Scope).void }
455
- def create_association_relation_methods(association_relation_methods_module)
483
+ sig { void }
484
+ def create_association_relation_methods
456
485
  returning_type = "T.nilable(T.any(T::Array[Symbol], FalseClass))"
457
486
  unique_by_type = "T.nilable(T.any(T::Array[Symbol], Symbol))"
458
487
 
@@ -496,11 +525,10 @@ module Tapioca
496
525
  end
497
526
  end
498
527
 
499
- sig { params(common_relation_methods_module: RBI::Scope).void }
500
- def create_common_methods(common_relation_methods_module)
528
+ sig { void }
529
+ def create_common_methods
501
530
  create_common_method(
502
531
  "destroy_all",
503
- common_relation_methods_module,
504
532
  return_type: "T::Array[#{constant_name}]",
505
533
  )
506
534
 
@@ -509,7 +537,6 @@ module Tapioca
509
537
  when :exists?
510
538
  create_common_method(
511
539
  "exists?",
512
- common_relation_methods_module,
513
540
  parameters: [
514
541
  create_opt_param("conditions", type: "T.untyped", default: ":none"),
515
542
  ],
@@ -518,7 +545,6 @@ module Tapioca
518
545
  when :include?, :member?
519
546
  create_common_method(
520
547
  method_name,
521
- common_relation_methods_module,
522
548
  parameters: [
523
549
  create_param("record", type: "T.untyped"),
524
550
  ],
@@ -527,7 +553,6 @@ module Tapioca
527
553
  when :find
528
554
  create_common_method(
529
555
  "find",
530
- common_relation_methods_module,
531
556
  parameters: [
532
557
  create_rest_param("args", type: "T.untyped"),
533
558
  ],
@@ -536,7 +561,6 @@ module Tapioca
536
561
  when :find_by
537
562
  create_common_method(
538
563
  "find_by",
539
- common_relation_methods_module,
540
564
  parameters: [
541
565
  create_rest_param("args", type: "T.untyped"),
542
566
  ],
@@ -545,7 +569,6 @@ module Tapioca
545
569
  when :find_by!
546
570
  create_common_method(
547
571
  "find_by!",
548
- common_relation_methods_module,
549
572
  parameters: [
550
573
  create_rest_param("args", type: "T.untyped"),
551
574
  ],
@@ -554,7 +577,6 @@ module Tapioca
554
577
  when :find_sole_by
555
578
  create_common_method(
556
579
  "find_sole_by",
557
- common_relation_methods_module,
558
580
  parameters: [
559
581
  create_param("arg", type: "T.untyped"),
560
582
  create_rest_param("args", type: "T.untyped"),
@@ -564,14 +586,12 @@ module Tapioca
564
586
  when :sole
565
587
  create_common_method(
566
588
  "sole",
567
- common_relation_methods_module,
568
589
  parameters: [],
569
590
  return_type: constant_name,
570
591
  )
571
592
  when :first, :last, :take
572
593
  create_common_method(
573
594
  method_name,
574
- common_relation_methods_module,
575
595
  parameters: [
576
596
  create_opt_param("limit", type: "T.untyped", default: "nil"),
577
597
  ],
@@ -588,7 +608,6 @@ module Tapioca
588
608
 
589
609
  create_common_method(
590
610
  method_name,
591
- common_relation_methods_module,
592
611
  return_type: return_type,
593
612
  )
594
613
  end
@@ -599,7 +618,6 @@ module Tapioca
599
618
  when :find_signed
600
619
  create_common_method(
601
620
  "find_signed",
602
- common_relation_methods_module,
603
621
  parameters: [
604
622
  create_param("signed_id", type: "T.untyped"),
605
623
  create_kw_opt_param("purpose", type: "T.untyped", default: "nil"),
@@ -609,7 +627,6 @@ module Tapioca
609
627
  when :find_signed!
610
628
  create_common_method(
611
629
  "find_signed!",
612
- common_relation_methods_module,
613
630
  parameters: [
614
631
  create_param("signed_id", type: "T.untyped"),
615
632
  create_kw_opt_param("purpose", type: "T.untyped", default: "nil"),
@@ -624,7 +641,6 @@ module Tapioca
624
641
  when :average, :maximum, :minimum
625
642
  create_common_method(
626
643
  method_name,
627
- common_relation_methods_module,
628
644
  parameters: [
629
645
  create_param("column_name", type: "T.any(String, Symbol)"),
630
646
  ],
@@ -633,7 +649,6 @@ module Tapioca
633
649
  when :calculate
634
650
  create_common_method(
635
651
  "calculate",
636
- common_relation_methods_module,
637
652
  parameters: [
638
653
  create_param("operation", type: "Symbol"),
639
654
  create_param("column_name", type: "T.any(String, Symbol)"),
@@ -643,18 +658,16 @@ module Tapioca
643
658
  when :count
644
659
  create_common_method(
645
660
  "count",
646
- common_relation_methods_module,
647
661
  parameters: [
648
662
  create_opt_param("column_name", type: "T.untyped", default: "nil"),
649
663
  ],
650
664
  return_type: "T.untyped",
651
665
  )
652
666
  when :ids
653
- create_common_method("ids", common_relation_methods_module, return_type: "Array")
667
+ create_common_method("ids", return_type: "Array")
654
668
  when :pick, :pluck
655
669
  create_common_method(
656
670
  method_name,
657
- common_relation_methods_module,
658
671
  parameters: [
659
672
  create_rest_param("column_names", type: "T.untyped"),
660
673
  ],
@@ -663,7 +676,6 @@ module Tapioca
663
676
  when :sum
664
677
  create_common_method(
665
678
  "sum",
666
- common_relation_methods_module,
667
679
  parameters: [
668
680
  create_opt_param("column_name", type: "T.nilable(T.any(String, Symbol))", default: "nil"),
669
681
  create_block_param("block", type: "T.nilable(T.proc.params(record: T.untyped).returns(T.untyped))"),
@@ -673,11 +685,63 @@ module Tapioca
673
685
  end
674
686
  end
675
687
 
688
+ BATCHES_METHODS.each do |method_name|
689
+ case method_name
690
+ when :find_each
691
+ order = ActiveRecord::Batches.instance_method(:find_each).parameters.include?([:key, :order])
692
+ create_common_method(
693
+ "find_each",
694
+ parameters: [
695
+ create_kw_opt_param("start", type: "T.untyped", default: "nil"),
696
+ create_kw_opt_param("finish", type: "T.untyped", default: "nil"),
697
+ create_kw_opt_param("batch_size", type: "Integer", default: "1000"),
698
+ create_kw_opt_param("error_on_ignore", type: "T.untyped", default: "nil"),
699
+ *(create_kw_opt_param("order", type: "Symbol", default: ":asc") if order),
700
+ create_block_param("block", type: "T.nilable(T.proc.params(object: #{constant_name}).void)"),
701
+ ],
702
+ return_type: "T.nilable(T::Enumerator[#{constant_name}])",
703
+ )
704
+ when :find_in_batches
705
+ order = ActiveRecord::Batches.instance_method(:find_in_batches).parameters.include?([:key, :order])
706
+ create_common_method(
707
+ "find_in_batches",
708
+ parameters: [
709
+ create_kw_opt_param("start", type: "T.untyped", default: "nil"),
710
+ create_kw_opt_param("finish", type: "T.untyped", default: "nil"),
711
+ create_kw_opt_param("batch_size", type: "Integer", default: "1000"),
712
+ create_kw_opt_param("error_on_ignore", type: "T.untyped", default: "nil"),
713
+ *(create_kw_opt_param("order", type: "Symbol", default: ":asc") if order),
714
+ create_block_param(
715
+ "block",
716
+ type: "T.nilable(T.proc.params(object: T::Array[#{constant_name}]).void)",
717
+ ),
718
+ ],
719
+ return_type: "T.nilable(T::Enumerator[T::Enumerator[#{constant_name}]])",
720
+ )
721
+ when :in_batches
722
+ order = ActiveRecord::Batches.instance_method(:in_batches).parameters.include?([:key, :order])
723
+ use_ranges = ActiveRecord::Batches.instance_method(:in_batches).parameters.include?([:key, :use_ranges])
724
+ create_common_method(
725
+ "in_batches",
726
+ parameters: [
727
+ create_kw_opt_param("of", type: "Integer", default: "1000"),
728
+ create_kw_opt_param("start", type: "T.untyped", default: "nil"),
729
+ create_kw_opt_param("finish", type: "T.untyped", default: "nil"),
730
+ create_kw_opt_param("load", type: "T.untyped", default: "false"),
731
+ create_kw_opt_param("error_on_ignore", type: "T.untyped", default: "nil"),
732
+ *(create_kw_opt_param("order", type: "Symbol", default: ":asc") if order),
733
+ *(create_kw_opt_param("use_ranges", type: "T.untyped", default: "nil") if use_ranges),
734
+ create_block_param("block", type: "T.nilable(T.proc.params(object: #{RelationClassName}).void)"),
735
+ ],
736
+ return_type: "T.nilable(::ActiveRecord::Batches::BatchEnumerator)",
737
+ )
738
+ end
739
+ end
740
+
676
741
  ENUMERABLE_QUERY_METHODS.each do |method_name|
677
742
  block_type = "T.nilable(T.proc.params(record: #{constant_name}).returns(T.untyped))"
678
743
  create_common_method(
679
744
  method_name,
680
- common_relation_methods_module,
681
745
  parameters: [
682
746
  create_block_param("block", type: block_type),
683
747
  ],
@@ -689,7 +753,6 @@ module Tapioca
689
753
  block_type = "T.nilable(T.proc.params(object: #{constant_name}).void)"
690
754
  create_common_method(
691
755
  method_name,
692
- common_relation_methods_module,
693
756
  parameters: [
694
757
  create_param("attributes", type: "T.untyped"),
695
758
  create_block_param("block", type: block_type),
@@ -701,7 +764,6 @@ module Tapioca
701
764
  BUILDER_METHODS.each do |method_name|
702
765
  create_common_method(
703
766
  method_name,
704
- common_relation_methods_module,
705
767
  parameters: [
706
768
  create_opt_param("attributes", type: "T.untyped", default: "nil"),
707
769
  create_block_param("block", type: "T.nilable(T.proc.params(object: #{constant_name}).void)"),
@@ -714,12 +776,11 @@ module Tapioca
714
776
  sig do
715
777
  params(
716
778
  name: T.any(Symbol, String),
717
- common_relation_methods_module: RBI::Scope,
718
779
  parameters: T::Array[RBI::TypedParam],
719
780
  return_type: T.nilable(String),
720
781
  ).void
721
782
  end
722
- def create_common_method(name, common_relation_methods_module, parameters: [], return_type: nil)
783
+ def create_common_method(name, parameters: [], return_type: nil)
723
784
  common_relation_methods_module.create_method(
724
785
  name.to_s,
725
786
  parameters: parameters,
@@ -730,8 +791,6 @@ module Tapioca
730
791
  sig do
731
792
  params(
732
793
  name: T.any(Symbol, String),
733
- relation_methods_module: RBI::Scope,
734
- association_relation_methods_module: RBI::Scope,
735
794
  parameters: T::Array[RBI::TypedParam],
736
795
  relation_return_type: String,
737
796
  association_return_type: String,
@@ -739,8 +798,6 @@ module Tapioca
739
798
  end
740
799
  def create_relation_method(
741
800
  name,
742
- relation_methods_module,
743
- association_relation_methods_module,
744
801
  parameters: [],
745
802
  relation_return_type: RelationClassName,
746
803
  association_return_type: AssociationRelationClassName
@@ -83,7 +83,7 @@ module Tapioca
83
83
  class << self
84
84
  sig { override.returns(T::Enumerable[Module]) }
85
85
  def gather_constants
86
- descendants_of(::ActiveRecord::Base).reject(&:abstract_class?)
86
+ descendants_of(::ActiveRecord::Base)
87
87
  end
88
88
  end
89
89
 
@@ -0,0 +1,74 @@
1
+ # typed: strict
2
+ # frozen_string_literal: true
3
+
4
+ begin
5
+ require "active_record"
6
+ rescue LoadError
7
+ return
8
+ end
9
+
10
+ require "tapioca/dsl/helpers/active_record_constants_helper"
11
+
12
+ module Tapioca
13
+ module Dsl
14
+ module Compilers
15
+ # `Tapioca::Dsl::Compilers::ActiveModelSecurePassword` decorates RBI files for all
16
+ # classes that use [`ActiveRecord::SecureToken`](https://api.rubyonrails.org/classes/ActiveRecord/SecureToken/ClassMethods.html).
17
+ #
18
+ # For example, with the following class:
19
+ #
20
+ # ~~~rb
21
+ # class User < ActiveRecord::Base
22
+ # has_secure_token
23
+ # has_secure_token :auth_token, length: 36
24
+ # end
25
+ # ~~~
26
+ #
27
+ # this compiler will produce an RBI file with the following content:
28
+ # ~~~rbi
29
+ # # typed: true
30
+ #
31
+ # class User
32
+ # sig { returns(T::Boolean) }
33
+ # def regenerate_token; end
34
+ #
35
+ # sig { returns(T::Boolean) }
36
+ # def regenerate_auth_token; end
37
+ # end
38
+ # ~~~
39
+ class ActiveRecordSecureToken < Compiler
40
+ extend T::Sig
41
+ include Helpers::ActiveRecordConstantsHelper
42
+
43
+ ConstantType = type_member { { fixed: T.all(T.class_of(ActiveRecord::Base), Extensions::ActiveRecord) } }
44
+
45
+ sig { override.void }
46
+ def decorate
47
+ return if constant.__tapioca_secure_tokens.nil?
48
+
49
+ root.create_path(constant) do |model|
50
+ model.create_module(SecureTokensModuleName) do |mod|
51
+ constant.__tapioca_secure_tokens.each do |attribute|
52
+ mod.create_method(
53
+ "regenerate_#{attribute}",
54
+ return_type: "T::Boolean",
55
+ )
56
+ end
57
+ end
58
+
59
+ model.create_include(SecureTokensModuleName)
60
+ end
61
+ end
62
+
63
+ class << self
64
+ extend T::Sig
65
+
66
+ sig { override.returns(T::Enumerable[Module]) }
67
+ def gather_constants
68
+ descendants_of(::ActiveRecord::Base).reject(&:abstract_class?)
69
+ end
70
+ end
71
+ end
72
+ end
73
+ end
74
+ end
@@ -126,17 +126,20 @@ module Tapioca
126
126
 
127
127
  private
128
128
 
129
- TYPES = T.let({
130
- boolean: "T::Boolean",
131
- integer: "Integer",
132
- string: "String",
133
- float: "Float",
134
- date: "Date",
135
- time: "Time",
136
- datetime: "DateTime",
137
- decimal: "BigDecimal",
138
- any: "T.untyped",
139
- }.freeze, T::Hash[Symbol, String])
129
+ TYPES = T.let(
130
+ {
131
+ boolean: "T::Boolean",
132
+ integer: "Integer",
133
+ string: "String",
134
+ float: "Float",
135
+ date: "Date",
136
+ time: "Time",
137
+ datetime: "DateTime",
138
+ decimal: "BigDecimal",
139
+ any: "T.untyped",
140
+ }.freeze,
141
+ T::Hash[Symbol, String],
142
+ )
140
143
 
141
144
  sig { params(attr_type: Symbol).returns(String) }
142
145
  def type_for(attr_type)
@@ -85,18 +85,21 @@ module Tapioca
85
85
 
86
86
  private
87
87
 
88
- TYPES = T.let({
89
- boolean: "T::Boolean",
90
- integer: "Integer",
91
- string: "String",
92
- float: "Float",
93
- date: "Date",
94
- time: "Time",
95
- datetime: "DateTime",
96
- decimal: "BigDecimal",
97
- binary: "String",
98
- text: "String",
99
- }.freeze, T::Hash[Symbol, String])
88
+ TYPES = T.let(
89
+ {
90
+ boolean: "T::Boolean",
91
+ integer: "Integer",
92
+ string: "String",
93
+ float: "Float",
94
+ date: "Date",
95
+ time: "Time",
96
+ datetime: "DateTime",
97
+ decimal: "BigDecimal",
98
+ binary: "String",
99
+ text: "String",
100
+ }.freeze,
101
+ T::Hash[Symbol, String],
102
+ )
100
103
 
101
104
  sig { params(attr_type: Symbol).returns(String) }
102
105
  def type_for(attr_type)
@@ -109,9 +112,13 @@ module Tapioca
109
112
 
110
113
  klass.create_method(attribute, return_type: return_type)
111
114
  klass.create_method("#{attribute}?", return_type: "T::Boolean")
112
- klass.create_method("#{attribute}=", parameters: [
113
- create_param("value", type: return_type),
114
- ], return_type: return_type)
115
+ klass.create_method(
116
+ "#{attribute}=",
117
+ parameters: [
118
+ create_param("value", type: return_type),
119
+ ],
120
+ return_type: return_type,
121
+ )
115
122
  end
116
123
  end
117
124
  end
@@ -48,8 +48,10 @@ module Tapioca
48
48
 
49
49
  ConstantType = type_member do
50
50
  {
51
- fixed: T.all(Module,
52
- ::ActiveStorage::Reflection::ActiveRecordExtensions::ClassMethods),
51
+ fixed: T.all(
52
+ Module,
53
+ ::ActiveStorage::Reflection::ActiveRecordExtensions::ClassMethods,
54
+ ),
53
55
  }
54
56
  end
55
57