tapioca 0.16.10 → 0.17.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 (123) hide show
  1. checksums.yaml +4 -4
  2. data/lib/ruby_lsp/tapioca/addon.rb +24 -20
  3. data/lib/ruby_lsp/tapioca/run_gem_rbi_check.rb +20 -20
  4. data/lib/tapioca/bundler_ext/auto_require_hook.rb +5 -10
  5. data/lib/tapioca/commands/abstract_dsl.rb +36 -62
  6. data/lib/tapioca/commands/abstract_gem.rb +23 -43
  7. data/lib/tapioca/commands/annotations.rb +27 -33
  8. data/lib/tapioca/commands/check_shims.rb +4 -13
  9. data/lib/tapioca/commands/command.rb +8 -20
  10. data/lib/tapioca/commands/command_without_tracker.rb +1 -1
  11. data/lib/tapioca/commands/configure.rb +11 -16
  12. data/lib/tapioca/commands/dsl_compiler_list.rb +2 -1
  13. data/lib/tapioca/commands/dsl_generate.rb +2 -1
  14. data/lib/tapioca/commands/dsl_verify.rb +2 -1
  15. data/lib/tapioca/commands/gem_generate.rb +4 -8
  16. data/lib/tapioca/commands/gem_sync.rb +2 -1
  17. data/lib/tapioca/commands/gem_verify.rb +3 -2
  18. data/lib/tapioca/commands/require.rb +3 -7
  19. data/lib/tapioca/commands/todo.rb +6 -10
  20. data/lib/tapioca/dsl/compiler.rb +28 -53
  21. data/lib/tapioca/dsl/compilers/aasm.rb +31 -41
  22. data/lib/tapioca/dsl/compilers/action_controller_helpers.rb +7 -5
  23. data/lib/tapioca/dsl/compilers/action_mailer.rb +5 -3
  24. data/lib/tapioca/dsl/compilers/action_text.rb +5 -3
  25. data/lib/tapioca/dsl/compilers/active_job.rb +5 -8
  26. data/lib/tapioca/dsl/compilers/active_model_attributes.rb +9 -7
  27. data/lib/tapioca/dsl/compilers/active_model_secure_password.rb +4 -2
  28. data/lib/tapioca/dsl/compilers/active_model_validations_confirmation.rb +4 -2
  29. data/lib/tapioca/dsl/compilers/active_record_associations.rb +16 -42
  30. data/lib/tapioca/dsl/compilers/active_record_columns.rb +19 -24
  31. data/lib/tapioca/dsl/compilers/active_record_delegated_types.rb +7 -5
  32. data/lib/tapioca/dsl/compilers/active_record_enum.rb +6 -4
  33. data/lib/tapioca/dsl/compilers/active_record_fixtures.rb +53 -61
  34. data/lib/tapioca/dsl/compilers/active_record_relations.rb +86 -119
  35. data/lib/tapioca/dsl/compilers/active_record_scope.rb +7 -11
  36. data/lib/tapioca/dsl/compilers/active_record_secure_token.rb +4 -2
  37. data/lib/tapioca/dsl/compilers/active_record_store.rb +4 -2
  38. data/lib/tapioca/dsl/compilers/active_record_typed_store.rb +18 -26
  39. data/lib/tapioca/dsl/compilers/active_resource.rb +18 -19
  40. data/lib/tapioca/dsl/compilers/active_storage.rb +5 -5
  41. data/lib/tapioca/dsl/compilers/active_support_concern.rb +8 -6
  42. data/lib/tapioca/dsl/compilers/active_support_current_attributes.rb +7 -5
  43. data/lib/tapioca/dsl/compilers/active_support_time_ext.rb +4 -2
  44. data/lib/tapioca/dsl/compilers/config.rb +4 -2
  45. data/lib/tapioca/dsl/compilers/frozen_record.rb +6 -9
  46. data/lib/tapioca/dsl/compilers/graphql_input_object.rb +8 -8
  47. data/lib/tapioca/dsl/compilers/graphql_mutation.rb +5 -8
  48. data/lib/tapioca/dsl/compilers/identity_cache.rb +10 -37
  49. data/lib/tapioca/dsl/compilers/json_api_client_resource.rb +8 -16
  50. data/lib/tapioca/dsl/compilers/kredis.rb +6 -4
  51. data/lib/tapioca/dsl/compilers/mixed_in_class_attributes.rb +4 -2
  52. data/lib/tapioca/dsl/compilers/protobuf.rb +12 -24
  53. data/lib/tapioca/dsl/compilers/rails_generators.rb +8 -9
  54. data/lib/tapioca/dsl/compilers/sidekiq_worker.rb +22 -11
  55. data/lib/tapioca/dsl/compilers/smart_properties.rb +11 -20
  56. data/lib/tapioca/dsl/compilers/state_machines.rb +14 -24
  57. data/lib/tapioca/dsl/compilers/url_helpers.rb +9 -7
  58. data/lib/tapioca/dsl/compilers.rb +4 -7
  59. data/lib/tapioca/dsl/helpers/active_model_type_helper.rb +13 -16
  60. data/lib/tapioca/dsl/helpers/active_record_column_type_helper.rb +13 -28
  61. data/lib/tapioca/dsl/helpers/active_record_constants_helper.rb +19 -15
  62. data/lib/tapioca/dsl/helpers/graphql_type_helper.rb +5 -24
  63. data/lib/tapioca/dsl/pipeline.rb +30 -58
  64. data/lib/tapioca/executor.rb +6 -12
  65. data/lib/tapioca/gem/events.rb +22 -28
  66. data/lib/tapioca/gem/listeners/base.rb +6 -6
  67. data/lib/tapioca/gem/listeners/dynamic_mixins.rb +4 -2
  68. data/lib/tapioca/gem/listeners/foreign_constants.rb +5 -7
  69. data/lib/tapioca/gem/listeners/methods.rb +15 -34
  70. data/lib/tapioca/gem/listeners/mixins.rb +6 -18
  71. data/lib/tapioca/gem/listeners/remove_empty_payload_scopes.rb +4 -2
  72. data/lib/tapioca/gem/listeners/sorbet_enums.rb +4 -2
  73. data/lib/tapioca/gem/listeners/sorbet_helpers.rb +4 -2
  74. data/lib/tapioca/gem/listeners/sorbet_props.rb +4 -2
  75. data/lib/tapioca/gem/listeners/sorbet_required_ancestors.rb +4 -2
  76. data/lib/tapioca/gem/listeners/sorbet_signatures.rb +7 -5
  77. data/lib/tapioca/gem/listeners/sorbet_type_variables.rb +6 -4
  78. data/lib/tapioca/gem/listeners/source_location.rb +7 -4
  79. data/lib/tapioca/gem/listeners/subconstants.rb +5 -4
  80. data/lib/tapioca/gem/listeners/yard_doc.rb +23 -22
  81. data/lib/tapioca/gem/pipeline.rb +57 -72
  82. data/lib/tapioca/gem_info.rb +1 -1
  83. data/lib/tapioca/gemfile.rb +64 -73
  84. data/lib/tapioca/helpers/cli_helper.rb +3 -3
  85. data/lib/tapioca/helpers/config_helper.rb +15 -24
  86. data/lib/tapioca/helpers/env_helper.rb +1 -1
  87. data/lib/tapioca/helpers/gem_helper.rb +5 -5
  88. data/lib/tapioca/helpers/git_attributes.rb +3 -3
  89. data/lib/tapioca/helpers/rbi_files_helper.rb +73 -67
  90. data/lib/tapioca/helpers/rbi_helper.rb +14 -22
  91. data/lib/tapioca/helpers/sorbet_helper.rb +9 -18
  92. data/lib/tapioca/helpers/source_uri.rb +15 -25
  93. data/lib/tapioca/helpers/test/content.rb +6 -6
  94. data/lib/tapioca/helpers/test/dsl_compiler.rb +19 -29
  95. data/lib/tapioca/helpers/test/isolation.rb +4 -4
  96. data/lib/tapioca/helpers/test/template.rb +5 -7
  97. data/lib/tapioca/internal.rb +5 -1
  98. data/lib/tapioca/loaders/dsl.rb +11 -19
  99. data/lib/tapioca/loaders/gem.rb +6 -21
  100. data/lib/tapioca/loaders/loader.rb +15 -27
  101. data/lib/tapioca/rbi_ext/model.rb +12 -37
  102. data/lib/tapioca/rbi_formatter.rb +10 -19
  103. data/lib/tapioca/rbs/rewriter.rb +55 -0
  104. data/lib/tapioca/repo_index.rb +7 -7
  105. data/lib/tapioca/runtime/attached_class_of_32.rb +1 -1
  106. data/lib/tapioca/runtime/attached_class_of_legacy.rb +1 -1
  107. data/lib/tapioca/runtime/dynamic_mixin_compiler.rb +23 -23
  108. data/lib/tapioca/runtime/generic_type_registry.rb +13 -23
  109. data/lib/tapioca/runtime/reflection.rb +48 -56
  110. data/lib/tapioca/runtime/trackers/autoload.rb +4 -8
  111. data/lib/tapioca/runtime/trackers/mixin.rb +6 -10
  112. data/lib/tapioca/runtime/trackers/required_ancestor.rb +3 -3
  113. data/lib/tapioca/runtime/trackers/tracker.rb +2 -2
  114. data/lib/tapioca/runtime/trackers.rb +4 -8
  115. data/lib/tapioca/sorbet_ext/generic_name_patch.rb +9 -15
  116. data/lib/tapioca/sorbet_ext/name_patch.rb +1 -1
  117. data/lib/tapioca/sorbet_ext/proc_bind_patch.rb +1 -1
  118. data/lib/tapioca/static/requires_compiler.rb +6 -6
  119. data/lib/tapioca/static/symbol_loader.rb +14 -16
  120. data/lib/tapioca/static/symbol_table_parser.rb +8 -8
  121. data/lib/tapioca/version.rb +1 -1
  122. data/lib/tapioca.rb +22 -29
  123. metadata +25 -10
@@ -64,7 +64,8 @@ module Tapioca
64
64
 
65
65
  ConstantType = type_member { { fixed: T.class_of(::ActiveSupport::CurrentAttributes) } }
66
66
 
67
- sig { override.void }
67
+ # @override
68
+ #: -> void
68
69
  def decorate
69
70
  dynamic_methods = dynamic_methods_of_constant
70
71
  instance_methods = instance_methods_of_constant - dynamic_methods
@@ -96,7 +97,8 @@ module Tapioca
96
97
  class << self
97
98
  extend T::Sig
98
99
 
99
- sig { override.returns(T::Enumerable[Module]) }
100
+ # @override
101
+ #: -> T::Enumerable[Module]
100
102
  def gather_constants
101
103
  descendants_of(::ActiveSupport::CurrentAttributes)
102
104
  end
@@ -104,17 +106,17 @@ module Tapioca
104
106
 
105
107
  private
106
108
 
107
- sig { returns(T::Array[Symbol]) }
109
+ #: -> Array[Symbol]
108
110
  def dynamic_methods_of_constant
109
111
  constant.instance_variable_get(:@generated_attribute_methods)&.instance_methods(false) || []
110
112
  end
111
113
 
112
- sig { returns(T::Array[Symbol]) }
114
+ #: -> Array[Symbol]
113
115
  def instance_methods_of_constant
114
116
  constant.instance_methods(false)
115
117
  end
116
118
 
117
- sig { params(klass: RBI::Scope, method: String, class_method: T::Boolean).void }
119
+ #: (RBI::Scope klass, String method, class_method: bool) -> void
118
120
  def generate_method(klass, method, class_method:)
119
121
  method_def = if class_method
120
122
  constant.method(method)
@@ -39,7 +39,8 @@ module Tapioca
39
39
 
40
40
  ConstantType = type_member { { fixed: T.class_of(::Time) } }
41
41
 
42
- sig { override.void }
42
+ # @override
43
+ #: -> void
43
44
  def decorate
44
45
  return unless constant.respond_to?(:zone)
45
46
 
@@ -57,7 +58,8 @@ module Tapioca
57
58
  class << self
58
59
  extend T::Sig
59
60
 
60
- sig { override.returns(T::Enumerable[Module]) }
61
+ # @override
62
+ #: -> T::Enumerable[Module]
61
63
  def gather_constants
62
64
  [::Time]
63
65
  end
@@ -47,7 +47,8 @@ module Tapioca
47
47
 
48
48
  ConstantType = type_member { { fixed: Module } }
49
49
 
50
- sig { override.void }
50
+ # @override
51
+ #: -> void
51
52
  def decorate
52
53
  # The constant we are given is the specialized config options type
53
54
  option_class_name = constant.name
@@ -95,7 +96,8 @@ module Tapioca
95
96
  class << self
96
97
  extend T::Sig
97
98
 
98
- sig { override.returns(T::Enumerable[Module]) }
99
+ # @override
100
+ #: -> T::Enumerable[Module]
99
101
  def gather_constants
100
102
  name = ::Config.const_name
101
103
  return [] unless Object.const_defined?(name)
@@ -63,7 +63,8 @@ module Tapioca
63
63
 
64
64
  ConstantType = type_member { { fixed: T.all(T.class_of(::FrozenRecord::Base), Extensions::FrozenRecord) } }
65
65
 
66
- sig { override.void }
66
+ # @override
67
+ #: -> void
67
68
  def decorate
68
69
  attributes = constant.attributes
69
70
  return if attributes.empty?
@@ -87,7 +88,8 @@ module Tapioca
87
88
  class << self
88
89
  extend T::Sig
89
90
 
90
- sig { override.returns(T::Enumerable[Module]) }
91
+ # @override
92
+ #: -> T::Enumerable[Module]
91
93
  def gather_constants
92
94
  descendants_of(::FrozenRecord::Base).reject(&:abstract_class?)
93
95
  end
@@ -95,7 +97,7 @@ module Tapioca
95
97
 
96
98
  private
97
99
 
98
- sig { params(record: RBI::Scope).void }
100
+ #: (RBI::Scope record) -> void
99
101
  def decorate_scopes(record)
100
102
  scopes = constant.__tapioca_scope_names
101
103
  return if scopes.nil?
@@ -111,12 +113,7 @@ module Tapioca
111
113
  record.create_extend(module_name)
112
114
  end
113
115
 
114
- sig do
115
- params(
116
- scope_method: String,
117
- mod: RBI::Scope,
118
- ).void
119
- end
116
+ #: (String scope_method, RBI::Scope mod) -> void
120
117
  def generate_scope_method(scope_method, mod)
121
118
  mod.create_method(
122
119
  scope_method,
@@ -39,7 +39,8 @@ module Tapioca
39
39
 
40
40
  ConstantType = type_member { { fixed: T.class_of(GraphQL::Schema::InputObject) } }
41
41
 
42
- sig { override.void }
42
+ # @override
43
+ #: -> void
43
44
  def decorate
44
45
  # Skip methods explicitly defined in code
45
46
  arguments = constant.all_argument_definitions.select do |argument|
@@ -61,15 +62,13 @@ module Tapioca
61
62
 
62
63
  private
63
64
 
64
- sig { returns(T.nilable(String)) }
65
+ #: -> String?
65
66
  def graphql_input_object_argument_source_file
66
- @graphql_input_object_argument_source_file ||= T.let(
67
- GraphQL::Schema::InputObject.method(:argument).source_location&.first,
68
- T.nilable(String),
69
- )
67
+ @graphql_input_object_argument_source_file ||=
68
+ GraphQL::Schema::InputObject.method(:argument).source_location&.first #: String?
70
69
  end
71
70
 
72
- sig { params(method_name: String).returns(T::Boolean) }
71
+ #: (String method_name) -> bool
73
72
  def method_defined_by_graphql?(method_name)
74
73
  method_file = constant.instance_method(method_name).source_location&.first
75
74
  !!(method_file && graphql_input_object_argument_source_file == method_file)
@@ -78,7 +77,8 @@ module Tapioca
78
77
  class << self
79
78
  extend T::Sig
80
79
 
81
- sig { override.returns(T::Enumerable[Module]) }
80
+ # @override
81
+ #: -> T::Enumerable[Module]
82
82
  def gather_constants
83
83
  all_classes.select { |c| GraphQL::Schema::InputObject > c }
84
84
  end
@@ -40,7 +40,8 @@ module Tapioca
40
40
 
41
41
  ConstantType = type_member { { fixed: T.class_of(GraphQL::Schema::Mutation) } }
42
42
 
43
- sig { override.void }
43
+ # @override
44
+ #: -> void
44
45
  def decorate
45
46
  return unless constant.method_defined?(:resolve)
46
47
 
@@ -63,12 +64,7 @@ module Tapioca
63
64
  end
64
65
  end
65
66
 
66
- sig do
67
- params(
68
- argument: T.nilable(GraphQL::Schema::Argument),
69
- constant: T.class_of(GraphQL::Schema::Mutation),
70
- ).returns(String)
71
- end
67
+ #: (GraphQL::Schema::Argument? argument, singleton(GraphQL::Schema::Mutation) constant) -> String
72
68
  def argument_type(argument, constant)
73
69
  return "T.untyped" unless argument
74
70
 
@@ -78,7 +74,8 @@ module Tapioca
78
74
  class << self
79
75
  extend T::Sig
80
76
 
81
- sig { override.returns(T::Enumerable[Module]) }
77
+ # @override
78
+ #: -> T::Enumerable[Module]
82
79
  def gather_constants
83
80
  all_classes.select { |c| GraphQL::Schema::Mutation > c && GraphQL::Schema::RelayClassicMutation != c }
84
81
  end
@@ -58,14 +58,12 @@ module Tapioca
58
58
  class IdentityCache < Compiler
59
59
  extend T::Sig
60
60
 
61
- COLLECTION_TYPE = T.let(
62
- ->(type) { "T::Array[::#{type}]" },
63
- T.proc.params(type: T.any(Module, String)).returns(String),
64
- )
61
+ COLLECTION_TYPE = ->(type) { "T::Array[::#{type}]" } #: ^((Module | String) type) -> String
65
62
 
66
63
  ConstantType = type_member { { fixed: T.class_of(::ActiveRecord::Base) } }
67
64
 
68
- sig { override.void }
65
+ # @override
66
+ #: -> void
69
67
  def decorate
70
68
  caches = constant.send(:all_cached_associations)
71
69
  cache_indexes = constant.send(:cache_indexes)
@@ -97,7 +95,8 @@ module Tapioca
97
95
  class << self
98
96
  extend T::Sig
99
97
 
100
- sig { override.returns(T::Enumerable[Module]) }
98
+ # @override
99
+ #: -> T::Enumerable[Module]
101
100
  def gather_constants
102
101
  descendants_of(::ActiveRecord::Base).select do |klass|
103
102
  ::IdentityCache::WithoutPrimaryIndex > klass
@@ -107,12 +106,7 @@ module Tapioca
107
106
 
108
107
  private
109
108
 
110
- sig do
111
- params(
112
- field: T.untyped,
113
- returns_collection: T::Boolean,
114
- ).returns(String)
115
- end
109
+ #: (untyped field, returns_collection: bool) -> String
116
110
  def type_for_field(field, returns_collection:)
117
111
  cache_type = field.reflection.compute_class(field.reflection.class_name)
118
112
  if returns_collection
@@ -124,13 +118,7 @@ module Tapioca
124
118
  "T.untyped"
125
119
  end
126
120
 
127
- sig do
128
- params(
129
- field: T.untyped,
130
- klass: RBI::Scope,
131
- returns_collection: T::Boolean,
132
- ).void
133
- end
121
+ #: (untyped field, RBI::Scope klass, returns_collection: bool) -> void
134
122
  def create_fetch_field_methods(field, klass, returns_collection:)
135
123
  name = field.cached_accessor_name.to_s
136
124
  type = type_for_field(field, returns_collection: returns_collection)
@@ -143,12 +131,7 @@ module Tapioca
143
131
  end
144
132
  end
145
133
 
146
- sig do
147
- params(
148
- field: T.untyped,
149
- klass: RBI::Scope,
150
- ).void
151
- end
134
+ #: (untyped field, RBI::Scope klass) -> void
152
135
  def create_fetch_by_methods(field, klass)
153
136
  is_cache_index = field.instance_variable_defined?(:@attribute_proc)
154
137
 
@@ -159,12 +142,7 @@ module Tapioca
159
142
  create_index_fetch_by_methods(field, klass) if is_cache_index
160
143
  end
161
144
 
162
- sig do
163
- params(
164
- field: T.untyped,
165
- klass: RBI::Scope,
166
- ).void
167
- end
145
+ #: (untyped field, RBI::Scope klass) -> void
168
146
  def create_index_fetch_by_methods(field, klass)
169
147
  fields_name = field.key_fields.join("_and_")
170
148
  name = "fetch_by_#{fields_name}"
@@ -209,12 +187,7 @@ module Tapioca
209
187
  )
210
188
  end
211
189
 
212
- sig do
213
- params(
214
- field: T.untyped,
215
- klass: RBI::Scope,
216
- ).void
217
- end
190
+ #: (untyped field, RBI::Scope klass) -> void
218
191
  def create_aliased_fetch_by_methods(field, klass)
219
192
  type, _ = Helpers::ActiveRecordColumnTypeHelper.new(
220
193
  constant,
@@ -84,7 +84,8 @@ module Tapioca
84
84
 
85
85
  ConstantType = type_member { { fixed: T.class_of(::JsonApiClient::Resource) } }
86
86
 
87
- sig { override.void }
87
+ # @override
88
+ #: -> void
88
89
  def decorate
89
90
  schema = resource_schema
90
91
  return if schema.nil? && constant.associations.empty?
@@ -108,7 +109,8 @@ module Tapioca
108
109
  class << self
109
110
  extend T::Sig
110
111
 
111
- sig { override.returns(T::Enumerable[Module]) }
112
+ # @override
113
+ #: -> T::Enumerable[Module]
112
114
  def gather_constants
113
115
  all_modules.select do |c|
114
116
  name_of(c) && ::JsonApiClient::Resource > c
@@ -118,7 +120,7 @@ module Tapioca
118
120
 
119
121
  private
120
122
 
121
- sig { returns(T.nilable(::JsonApiClient::Schema)) }
123
+ #: -> ::JsonApiClient::Schema?
122
124
  def resource_schema
123
125
  schema = constant.schema
124
126
 
@@ -126,12 +128,7 @@ module Tapioca
126
128
  schema if schema.size > 0 # rubocop:disable Style/ZeroLengthPredicate
127
129
  end
128
130
 
129
- sig do
130
- params(
131
- mod: RBI::Scope,
132
- property: ::JsonApiClient::Schema::Property,
133
- ).void
134
- end
131
+ #: (RBI::Scope mod, ::JsonApiClient::Schema::Property property) -> void
135
132
  def generate_methods_for_property(mod, property)
136
133
  type = type_for(property)
137
134
 
@@ -141,7 +138,7 @@ module Tapioca
141
138
  mod.create_method("#{name}=", parameters: [create_param(name, type: type)], return_type: type)
142
139
  end
143
140
 
144
- sig { params(property: ::JsonApiClient::Schema::Property).returns(String) }
141
+ #: (::JsonApiClient::Schema::Property property) -> String
145
142
  def type_for(property)
146
143
  type = ::JsonApiClient::Schema::TypeFactory.type_for(property.type)
147
144
  return "T.untyped" if type.nil?
@@ -181,12 +178,7 @@ module Tapioca
181
178
  end
182
179
  end
183
180
 
184
- sig do
185
- params(
186
- mod: RBI::Scope,
187
- association: JsonApiClient::Associations::BaseAssociation,
188
- ).void
189
- end
181
+ #: (RBI::Scope mod, JsonApiClient::Associations::BaseAssociation association) -> void
190
182
  def generate_methods_for_association(mod, association)
191
183
  # If the association is broken, it will raise a NameError when trying to access the association_class
192
184
  klass = association.association_class
@@ -70,7 +70,8 @@ module Tapioca
70
70
  { fixed: T.all(T::Class[::Kredis::Attributes], ::Kredis::Attributes::ClassMethods, Extensions::Kredis) }
71
71
  end
72
72
 
73
- sig { override.void }
73
+ # @override
74
+ #: -> void
74
75
  def decorate
75
76
  return if constant.__tapioca_kredis_types.nil?
76
77
 
@@ -89,7 +90,8 @@ module Tapioca
89
90
  class << self
90
91
  extend T::Sig
91
92
 
92
- sig { override.returns(T::Enumerable[Module]) }
93
+ # @override
94
+ #: -> T::Enumerable[Module]
93
95
  def gather_constants
94
96
  all_classes
95
97
  .grep(::Kredis::Attributes::ClassMethods)
@@ -99,7 +101,7 @@ module Tapioca
99
101
 
100
102
  private
101
103
 
102
- sig { params(mod: RBI::Scope, method: String, data: T::Hash[Symbol, T.untyped]).void }
104
+ #: (RBI::Scope mod, String method, Hash[Symbol, untyped] data) -> void
103
105
  def generate_methods(mod, method, data)
104
106
  return_type = data.fetch(:type)
105
107
  case return_type
@@ -114,7 +116,7 @@ module Tapioca
114
116
  mod.create_method(method, return_type: return_type)
115
117
  end
116
118
 
117
- sig { params(mod: RBI::Scope, klass_name: String, values: T::Array[T.untyped]).void }
119
+ #: (RBI::Scope mod, String klass_name, Array[untyped] values) -> void
118
120
  def create_enum_class(mod, klass_name, values)
119
121
  klass = mod.create_class(klass_name, superclass_name: "Kredis::Types::Enum")
120
122
  values.each do |value|
@@ -49,7 +49,8 @@ module Tapioca
49
49
 
50
50
  ConstantType = type_member { { fixed: Module } }
51
51
 
52
- sig { override.void }
52
+ # @override
53
+ #: -> void
53
54
  def decorate
54
55
  mixin_compiler = Runtime::DynamicMixinCompiler.new(constant)
55
56
  return if mixin_compiler.empty_attributes?
@@ -62,7 +63,8 @@ module Tapioca
62
63
  class << self
63
64
  extend T::Sig
64
65
 
65
- sig { override.returns(T::Enumerable[Module]) }
66
+ # @override
67
+ #: -> T::Enumerable[Module]
66
68
  def gather_constants
67
69
  # Select all non-anonymous modules that have overridden Module.included
68
70
  all_modules.select do |mod|
@@ -78,7 +78,8 @@ module Tapioca
78
78
 
79
79
  FIELD_RE = /^[a-z_][a-zA-Z0-9_]*$/
80
80
 
81
- sig { override.void }
81
+ # @override
82
+ #: -> void
82
83
  def decorate
83
84
  root.create_path(constant) do |klass|
84
85
  if constant == Google::Protobuf::RepeatedField
@@ -155,7 +156,8 @@ module Tapioca
155
156
  class << self
156
157
  extend T::Sig
157
158
 
158
- sig { override.returns(T::Enumerable[Module]) }
159
+ # @override
160
+ #: -> T::Enumerable[Module]
159
161
  def gather_constants
160
162
  marker = Google::Protobuf::MessageExts::ClassMethods
161
163
 
@@ -178,7 +180,7 @@ module Tapioca
178
180
 
179
181
  private
180
182
 
181
- sig { params(desc: Google::Protobuf::FieldDescriptor).returns(T::Boolean) }
183
+ #: (Google::Protobuf::FieldDescriptor desc) -> bool
182
184
  def has_presence?(desc)
183
185
  if desc.respond_to?(:has_presence?)
184
186
  # This method is only defined in google-protobuf 3.26.0 and later
@@ -190,7 +192,7 @@ module Tapioca
190
192
  end
191
193
  end
192
194
 
193
- sig { params(klass: RBI::Scope, names: String).void }
195
+ #: (RBI::Scope klass, *String names) -> void
194
196
  def create_type_members(klass, *names)
195
197
  klass.create_extend("T::Generic")
196
198
 
@@ -199,11 +201,7 @@ module Tapioca
199
201
  end
200
202
  end
201
203
 
202
- sig do
203
- params(
204
- descriptor: Google::Protobuf::FieldDescriptor,
205
- ).returns(String)
206
- end
204
+ #: (Google::Protobuf::FieldDescriptor descriptor) -> String
207
205
  def type_of(descriptor)
208
206
  case descriptor.type
209
207
  when :enum
@@ -229,12 +227,12 @@ module Tapioca
229
227
  end
230
228
  end
231
229
 
232
- sig { params(descriptor: Google::Protobuf::FieldDescriptor).returns(T::Boolean) }
230
+ #: (Google::Protobuf::FieldDescriptor descriptor) -> bool
233
231
  def nilable_descriptor?(descriptor)
234
232
  descriptor.label == :optional && descriptor.type == :message
235
233
  end
236
234
 
237
- sig { params(descriptor: Google::Protobuf::FieldDescriptor).returns(T::Boolean) }
235
+ #: (Google::Protobuf::FieldDescriptor descriptor) -> bool
238
236
  def map_type?(descriptor)
239
237
  # Defensively make sure that we are dealing with a repeated field
240
238
  return false unless descriptor.label == :repeated
@@ -248,7 +246,7 @@ module Tapioca
248
246
  false
249
247
  end
250
248
 
251
- sig { params(descriptor: Google::Protobuf::FieldDescriptor).returns(Field) }
249
+ #: (Google::Protobuf::FieldDescriptor descriptor) -> Field
252
250
  def field_of(descriptor)
253
251
  if descriptor.label == :repeated
254
252
  if map_type?(descriptor)
@@ -290,12 +288,7 @@ module Tapioca
290
288
  end
291
289
  end
292
290
 
293
- sig do
294
- params(
295
- klass: RBI::Scope,
296
- desc: Google::Protobuf::FieldDescriptor,
297
- ).returns(Field)
298
- end
291
+ #: (RBI::Scope klass, Google::Protobuf::FieldDescriptor desc) -> Field
299
292
  def create_descriptor_method(klass, desc)
300
293
  field = field_of(desc)
301
294
 
@@ -325,12 +318,7 @@ module Tapioca
325
318
  field
326
319
  end
327
320
 
328
- sig do
329
- params(
330
- klass: RBI::Scope,
331
- desc: Google::Protobuf::OneofDescriptor,
332
- ).void
333
- end
321
+ #: (RBI::Scope klass, Google::Protobuf::OneofDescriptor desc) -> void
334
322
  def create_oneof_method(klass, desc)
335
323
  klass.create_method(
336
324
  desc.name,
@@ -36,14 +36,12 @@ module Tapioca
36
36
  class RailsGenerators < Compiler
37
37
  extend T::Sig
38
38
 
39
- BUILT_IN_MATCHER = T.let(
40
- /::(ActionMailbox|ActionText|ActiveRecord|Rails)::Generators/,
41
- Regexp,
42
- )
39
+ BUILT_IN_MATCHER = /::(ActionMailbox|ActionText|ActiveRecord|Rails)::Generators/
43
40
 
44
41
  ConstantType = type_member { { fixed: T.class_of(::Rails::Generators::Base) } }
45
42
 
46
- sig { override.void }
43
+ # @override
44
+ #: -> void
47
45
  def decorate
48
46
  base_class = base_class_of_constant
49
47
  arguments = constant.arguments - base_class.arguments
@@ -62,7 +60,8 @@ module Tapioca
62
60
  class << self
63
61
  extend T::Sig
64
62
 
65
- sig { override.returns(T::Enumerable[Module]) }
63
+ # @override
64
+ #: -> T::Enumerable[Module]
66
65
  def gather_constants
67
66
  all_classes.select do |const|
68
67
  name = qualified_name_of(const)
@@ -76,7 +75,7 @@ module Tapioca
76
75
 
77
76
  private
78
77
 
79
- sig { params(klass: RBI::Tree, argument: T.any(Thor::Argument, Thor::Option)).void }
78
+ #: (RBI::Tree klass, (Thor::Argument | Thor::Option) argument) -> void
80
79
  def generate_methods_for_argument(klass, argument)
81
80
  klass.create_method(
82
81
  argument.name,
@@ -85,7 +84,7 @@ module Tapioca
85
84
  )
86
85
  end
87
86
 
88
- sig { returns(T.class_of(::Rails::Generators::Base)) }
87
+ #: -> singleton(::Rails::Generators::Base)
89
88
  def base_class_of_constant
90
89
  ancestor = inherited_ancestors_of(constant).find do |klass|
91
90
  qualified_name_of(klass)&.match?(BUILT_IN_MATCHER)
@@ -94,7 +93,7 @@ module Tapioca
94
93
  T.cast(ancestor, T.class_of(::Rails::Generators::Base))
95
94
  end
96
95
 
97
- sig { params(arg: T.any(Thor::Argument, Thor::Option)).returns(String) }
96
+ #: ((Thor::Argument | Thor::Option) arg) -> String
98
97
  def type_for(arg)
99
98
  type =
100
99
  case arg.type
@@ -36,12 +36,18 @@ module Tapioca
36
36
  # def self.perform_in(interval, customer_id); end
37
37
  # end
38
38
  # ~~~
39
+ #
40
+ # If your project uses `ActiveSupport` as well, then the compiler will automatically add its classes
41
+ # as accepted values for the `interval` parameter:
42
+ # * `self.perform_at` will also accept a `ActiveSupport::TimeWithZone` value
43
+ # * `self.perform_in` will also accept a `ActiveSupport::Duration` value
39
44
  class SidekiqWorker < Compiler
40
45
  extend T::Sig
41
46
 
42
47
  ConstantType = type_member { { fixed: T.class_of(::Sidekiq::Worker) } }
43
48
 
44
- sig { override.void }
49
+ # @override
50
+ #: -> void
45
51
  def decorate
46
52
  return unless constant.instance_methods.include?(:perform)
47
53
 
@@ -53,12 +59,22 @@ module Tapioca
53
59
  # `perform_at` and is just an alias for `perform_in` so both methods technically
54
60
  # accept a datetime, time, or numeric but we're typing them differently so they
55
61
  # semantically make sense.
62
+ at_return_type = if defined?(ActiveSupport::TimeWithZone)
63
+ "T.any(DateTime, Time, ActiveSupport::TimeWithZone)"
64
+ else
65
+ "T.any(DateTime, Time)"
66
+ end
56
67
  at_params = [
57
- create_param("interval", type: "T.any(DateTime, Time)"),
68
+ create_param("interval", type: at_return_type),
58
69
  *async_params,
59
70
  ]
71
+ in_return_type = if defined?(ActiveSupport::Duration)
72
+ "T.any(Numeric, ActiveSupport::Duration)"
73
+ else
74
+ "Numeric"
75
+ end
60
76
  in_params = [
61
- create_param("interval", type: "Numeric"),
77
+ create_param("interval", type: in_return_type),
62
78
  *async_params,
63
79
  ]
64
80
 
@@ -71,7 +87,8 @@ module Tapioca
71
87
  class << self
72
88
  extend T::Sig
73
89
 
74
- sig { override.returns(T::Enumerable[Module]) }
90
+ # @override
91
+ #: -> T::Enumerable[Module]
75
92
  def gather_constants
76
93
  all_classes.select { |c| Sidekiq::Worker > c }
77
94
  end
@@ -79,13 +96,7 @@ module Tapioca
79
96
 
80
97
  private
81
98
 
82
- sig do
83
- params(
84
- worker: RBI::Scope,
85
- method_name: String,
86
- parameters: T::Array[RBI::TypedParam],
87
- ).void
88
- end
99
+ #: (RBI::Scope worker, String method_name, Array[RBI::TypedParam] parameters) -> void
89
100
  def generate_perform_method(worker, method_name, parameters)
90
101
  if constant.method(method_name.to_sym).owner == Sidekiq::Worker::ClassMethods
91
102
  worker.create_method(method_name, parameters: parameters, return_type: "String", class_method: true)