tapioca 0.10.1 → 0.10.2

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 (74) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +4 -3
  3. data/lib/tapioca/cli.rb +9 -10
  4. data/lib/tapioca/commands/annotations.rb +2 -2
  5. data/lib/tapioca/commands/check_shims.rb +2 -2
  6. data/lib/tapioca/commands/command.rb +2 -2
  7. data/lib/tapioca/commands/command_without_tracker.rb +18 -0
  8. data/lib/tapioca/commands/configure.rb +3 -3
  9. data/lib/tapioca/commands/dsl.rb +10 -10
  10. data/lib/tapioca/commands/gem.rb +5 -5
  11. data/lib/tapioca/commands/require.rb +2 -2
  12. data/lib/tapioca/commands/todo.rb +2 -2
  13. data/lib/tapioca/commands.rb +1 -0
  14. data/lib/tapioca/dsl/compiler.rb +3 -3
  15. data/lib/tapioca/dsl/compilers/aasm.rb +4 -4
  16. data/lib/tapioca/dsl/compilers/action_controller_helpers.rb +1 -1
  17. data/lib/tapioca/dsl/compilers/action_mailer.rb +1 -1
  18. data/lib/tapioca/dsl/compilers/active_job.rb +2 -2
  19. data/lib/tapioca/dsl/compilers/active_model_attributes.rb +1 -1
  20. data/lib/tapioca/dsl/compilers/active_record_associations.rb +13 -13
  21. data/lib/tapioca/dsl/compilers/active_record_columns.rb +22 -22
  22. data/lib/tapioca/dsl/compilers/active_record_fixtures.rb +1 -1
  23. data/lib/tapioca/dsl/compilers/active_record_relations.rb +49 -39
  24. data/lib/tapioca/dsl/compilers/active_record_scope.rb +3 -3
  25. data/lib/tapioca/dsl/compilers/active_record_typed_store.rb +2 -2
  26. data/lib/tapioca/dsl/compilers/active_storage.rb +2 -2
  27. data/lib/tapioca/dsl/compilers/active_support_current_attributes.rb +1 -1
  28. data/lib/tapioca/dsl/compilers/config.rb +2 -2
  29. data/lib/tapioca/dsl/compilers/graphql_input_object.rb +1 -0
  30. data/lib/tapioca/dsl/compilers/graphql_mutation.rb +1 -0
  31. data/lib/tapioca/dsl/compilers/identity_cache.rb +12 -12
  32. data/lib/tapioca/dsl/compilers/protobuf.rb +9 -9
  33. data/lib/tapioca/dsl/compilers/rails_generators.rb +2 -2
  34. data/lib/tapioca/dsl/compilers/sidekiq_worker.rb +1 -1
  35. data/lib/tapioca/dsl/compilers/smart_properties.rb +2 -2
  36. data/lib/tapioca/dsl/compilers/state_machines.rb +24 -24
  37. data/lib/tapioca/dsl/compilers/url_helpers.rb +1 -1
  38. data/lib/tapioca/dsl/compilers.rb +1 -1
  39. data/lib/tapioca/dsl/pipeline.rb +5 -4
  40. data/lib/tapioca/executor.rb +2 -2
  41. data/lib/tapioca/gem/events.rb +1 -1
  42. data/lib/tapioca/gem/listeners/foreign_constants.rb +3 -2
  43. data/lib/tapioca/gem/listeners/methods.rb +3 -3
  44. data/lib/tapioca/gem/listeners/mixins.rb +3 -7
  45. data/lib/tapioca/gem/listeners/source_location.rb +1 -1
  46. data/lib/tapioca/gem/listeners/subconstants.rb +1 -1
  47. data/lib/tapioca/gem/listeners/yard_doc.rb +1 -1
  48. data/lib/tapioca/gem/pipeline.rb +7 -3
  49. data/lib/tapioca/gemfile.rb +4 -4
  50. data/lib/tapioca/helpers/config_helper.rb +4 -4
  51. data/lib/tapioca/helpers/env_helper.rb +1 -0
  52. data/lib/tapioca/helpers/gem_helper.rb +17 -5
  53. data/lib/tapioca/helpers/rbi_files_helper.rb +3 -3
  54. data/lib/tapioca/helpers/rbi_helper.rb +1 -1
  55. data/lib/tapioca/helpers/sorbet_helper.rb +2 -2
  56. data/lib/tapioca/helpers/source_uri.rb +1 -1
  57. data/lib/tapioca/helpers/test/dsl_compiler.rb +1 -1
  58. data/lib/tapioca/loaders/dsl.rb +1 -1
  59. data/lib/tapioca/loaders/gem.rb +2 -2
  60. data/lib/tapioca/loaders/loader.rb +1 -1
  61. data/lib/tapioca/rbi_ext/model.rb +3 -3
  62. data/lib/tapioca/rbi_formatter.rb +2 -2
  63. data/lib/tapioca/runtime/generic_type_registry.rb +22 -2
  64. data/lib/tapioca/runtime/reflection.rb +8 -2
  65. data/lib/tapioca/runtime/trackers/autoload.rb +3 -0
  66. data/lib/tapioca/runtime/trackers/constant_definition.rb +13 -5
  67. data/lib/tapioca/runtime/trackers/mixin.rb +37 -36
  68. data/lib/tapioca/runtime/trackers/required_ancestor.rb +17 -4
  69. data/lib/tapioca/runtime/trackers/tracker.rb +45 -0
  70. data/lib/tapioca/runtime/trackers.rb +27 -1
  71. data/lib/tapioca/sorbet_ext/generic_name_patch.rb +17 -6
  72. data/lib/tapioca/version.rb +1 -1
  73. data/lib/tapioca.rb +0 -10
  74. metadata +4 -2
@@ -66,7 +66,7 @@ module Tapioca
66
66
 
67
67
  COLLECTION_TYPE = T.let(
68
68
  ->(type) { "T::Array[::#{type}]" },
69
- T.proc.params(type: T.any(Module, String)).returns(String)
69
+ T.proc.params(type: T.any(Module, String)).returns(String),
70
70
  )
71
71
 
72
72
  ConstantType = type_member { { fixed: T.class_of(::ActiveRecord::Base) } }
@@ -116,7 +116,7 @@ module Tapioca
116
116
  sig do
117
117
  params(
118
118
  field: T.untyped,
119
- returns_collection: T::Boolean
119
+ returns_collection: T::Boolean,
120
120
  ).returns(String)
121
121
  end
122
122
  def type_for_field(field, returns_collection:)
@@ -134,7 +134,7 @@ module Tapioca
134
134
  params(
135
135
  field: T.untyped,
136
136
  klass: RBI::Scope,
137
- returns_collection: T::Boolean
137
+ returns_collection: T::Boolean,
138
138
  ).void
139
139
  end
140
140
  def create_fetch_field_methods(field, klass, returns_collection:)
@@ -152,7 +152,7 @@ module Tapioca
152
152
  sig do
153
153
  params(
154
154
  field: T.untyped,
155
- klass: RBI::Scope
155
+ klass: RBI::Scope,
156
156
  ).void
157
157
  end
158
158
  def create_fetch_by_methods(field, klass)
@@ -168,7 +168,7 @@ module Tapioca
168
168
  sig do
169
169
  params(
170
170
  field: T.untyped,
171
- klass: RBI::Scope
171
+ klass: RBI::Scope,
172
172
  ).void
173
173
  end
174
174
  def create_index_fetch_by_methods(field, klass)
@@ -187,21 +187,21 @@ module Tapioca
187
187
  "#{name}!",
188
188
  class_method: true,
189
189
  parameters: parameters,
190
- return_type: type
190
+ return_type: type,
191
191
  )
192
192
 
193
193
  klass.create_method(
194
194
  name,
195
195
  class_method: true,
196
196
  parameters: parameters,
197
- return_type: as_nilable_type(type)
197
+ return_type: as_nilable_type(type),
198
198
  )
199
199
  else
200
200
  klass.create_method(
201
201
  name,
202
202
  class_method: true,
203
203
  parameters: parameters,
204
- return_type: COLLECTION_TYPE.call(constant)
204
+ return_type: COLLECTION_TYPE.call(constant),
205
205
  )
206
206
  end
207
207
 
@@ -213,7 +213,7 @@ module Tapioca
213
213
  create_param("index_values", type: "T::Enumerable[T.untyped]"),
214
214
  create_kw_opt_param("includes", default: "nil", type: "T.untyped"),
215
215
  ],
216
- return_type: COLLECTION_TYPE.call(constant)
216
+ return_type: COLLECTION_TYPE.call(constant),
217
217
  )
218
218
  end
219
219
  end
@@ -221,7 +221,7 @@ module Tapioca
221
221
  sig do
222
222
  params(
223
223
  field: T.untyped,
224
- klass: RBI::Scope
224
+ klass: RBI::Scope,
225
225
  ).void
226
226
  end
227
227
  def create_aliased_fetch_by_methods(field, klass)
@@ -238,7 +238,7 @@ module Tapioca
238
238
  "fetch_#{suffix}",
239
239
  class_method: true,
240
240
  parameters: parameters,
241
- return_type: type
241
+ return_type: type,
242
242
  )
243
243
 
244
244
  if length == 1
@@ -246,7 +246,7 @@ module Tapioca
246
246
  "fetch_multi_#{suffix}",
247
247
  class_method: true,
248
248
  parameters: [create_param("keys", type: "T::Enumerable[T.untyped]")],
249
- return_type: COLLECTION_TYPE.call(multi_type)
249
+ return_type: COLLECTION_TYPE.call(multi_type),
250
250
  )
251
251
  end
252
252
  end
@@ -37,7 +37,7 @@ module Tapioca
37
37
  # sig { returns(Integer) }
38
38
  # def customer_id; end
39
39
  #
40
- # sig { params(month: Integer).returns(Integer) }
40
+ # sig { params(value: Integer).returns(Integer) }
41
41
  # def customer_id=(value); end
42
42
  #
43
43
  # sig { returns(Integer) }
@@ -169,7 +169,7 @@ module Tapioca
169
169
 
170
170
  sig do
171
171
  params(
172
- descriptor: Google::Protobuf::FieldDescriptor
172
+ descriptor: Google::Protobuf::FieldDescriptor,
173
173
  ).returns(String)
174
174
  end
175
175
  def type_of(descriptor)
@@ -223,7 +223,7 @@ module Tapioca
223
223
  name: descriptor.name,
224
224
  type: type,
225
225
  init_type: "T.nilable(T.any(#{type}, T::Hash[#{key_type}, #{value_type}]))",
226
- default: "Google::Protobuf::Map.new(#{default_args.join(", ")})"
226
+ default: "Google::Protobuf::Map.new(#{default_args.join(", ")})",
227
227
  )
228
228
  else
229
229
  elem_type = type_of(descriptor)
@@ -236,7 +236,7 @@ module Tapioca
236
236
  name: descriptor.name,
237
237
  type: type,
238
238
  init_type: "T.nilable(T.any(#{type}, T::Array[#{elem_type}]))",
239
- default: "Google::Protobuf::RepeatedField.new(#{default_args.join(", ")})"
239
+ default: "Google::Protobuf::RepeatedField.new(#{default_args.join(", ")})",
240
240
  )
241
241
  end
242
242
  else
@@ -248,7 +248,7 @@ module Tapioca
248
248
  name: descriptor.name,
249
249
  type: type,
250
250
  init_type: nilable_type,
251
- default: "nil"
251
+ default: "nil",
252
252
  )
253
253
  end
254
254
  end
@@ -264,13 +264,13 @@ module Tapioca
264
264
 
265
265
  klass.create_method(
266
266
  field.name,
267
- return_type: field.type
267
+ return_type: field.type,
268
268
  )
269
269
 
270
270
  klass.create_method(
271
271
  "#{field.name}=",
272
272
  parameters: [create_param("value", type: field.type)],
273
- return_type: "void"
273
+ return_type: "void",
274
274
  )
275
275
 
276
276
  field
@@ -279,13 +279,13 @@ module Tapioca
279
279
  sig do
280
280
  params(
281
281
  klass: RBI::Scope,
282
- desc: Google::Protobuf::OneofDescriptor
282
+ desc: Google::Protobuf::OneofDescriptor,
283
283
  ).void
284
284
  end
285
285
  def create_oneof_method(klass, desc)
286
286
  klass.create_method(
287
287
  desc.name,
288
- return_type: "T.nilable(Symbol)"
288
+ return_type: "T.nilable(Symbol)",
289
289
  )
290
290
  end
291
291
  end
@@ -43,7 +43,7 @@ module Tapioca
43
43
 
44
44
  BUILT_IN_MATCHER = T.let(
45
45
  /::(ActionMailbox|ActionText|ActiveRecord|Rails)::Generators/,
46
- Regexp
46
+ Regexp,
47
47
  )
48
48
 
49
49
  ConstantType = type_member { { fixed: T.class_of(::Rails::Generators::Base) } }
@@ -86,7 +86,7 @@ module Tapioca
86
86
  klass.create_method(
87
87
  argument.name,
88
88
  parameters: [],
89
- return_type: type_for(argument)
89
+ return_type: type_for(argument),
90
90
  )
91
91
  end
92
92
 
@@ -87,7 +87,7 @@ module Tapioca
87
87
  params(
88
88
  worker: RBI::Scope,
89
89
  method_name: String,
90
- parameters: T::Array[RBI::TypedParam]
90
+ parameters: T::Array[RBI::TypedParam],
91
91
  ).void
92
92
  end
93
93
  def generate_perform_method(worker, method_name, parameters)
@@ -69,7 +69,7 @@ module Tapioca
69
69
  def decorate
70
70
  properties = T.let(
71
71
  T.unsafe(constant).properties,
72
- ::SmartProperties::PropertyCollection
72
+ ::SmartProperties::PropertyCollection,
73
73
  )
74
74
  return if properties.keys.empty?
75
75
 
@@ -103,7 +103,7 @@ module Tapioca
103
103
  sig do
104
104
  params(
105
105
  mod: RBI::Scope,
106
- property: ::SmartProperties::Property
106
+ property: ::SmartProperties::Property,
107
107
  ).void
108
108
  end
109
109
  def generate_methods_for_property(mod, property)
@@ -186,7 +186,7 @@ module Tapioca
186
186
  def define_activerecord_methods(instance_module)
187
187
  instance_module.create_method(
188
188
  "changed_for_autosave?",
189
- return_type: "T::Boolean"
189
+ return_type: "T::Boolean",
190
190
  )
191
191
  end
192
192
 
@@ -195,7 +195,7 @@ module Tapioca
195
195
  machine.states.each do |state|
196
196
  instance_module.create_method(
197
197
  "#{state.qualified_name}?",
198
- return_type: "T::Boolean"
198
+ return_type: "T::Boolean",
199
199
  )
200
200
  end
201
201
  end
@@ -205,22 +205,22 @@ module Tapioca
205
205
  machine.events.each do |event|
206
206
  instance_module.create_method(
207
207
  "can_#{event.qualified_name}?",
208
- return_type: "T::Boolean"
208
+ return_type: "T::Boolean",
209
209
  )
210
210
  instance_module.create_method(
211
211
  "#{event.qualified_name}_transition",
212
212
  parameters: [create_rest_param("args", type: "T.untyped")],
213
- return_type: "T.nilable(::StateMachines::Transition)"
213
+ return_type: "T.nilable(::StateMachines::Transition)",
214
214
  )
215
215
  instance_module.create_method(
216
216
  event.qualified_name.to_s,
217
217
  parameters: [create_rest_param("args", type: "T.untyped")],
218
- return_type: "T::Boolean"
218
+ return_type: "T::Boolean",
219
219
  )
220
220
  instance_module.create_method(
221
221
  "#{event.qualified_name}!",
222
222
  parameters: [create_rest_param("args", type: "T.untyped")],
223
- return_type: "T::Boolean"
223
+ return_type: "T::Boolean",
224
224
  )
225
225
  end
226
226
  end
@@ -229,19 +229,19 @@ module Tapioca
229
229
  params(
230
230
  instance_module: RBI::Module,
231
231
  machine: ::StateMachines::Machine,
232
- state_type: String
232
+ state_type: String,
233
233
  ).void
234
234
  end
235
235
  def define_state_accessor(instance_module, machine, state_type)
236
236
  attribute = machine.attribute.to_s
237
237
  instance_module.create_method(
238
238
  attribute,
239
- return_type: state_type
239
+ return_type: state_type,
240
240
  )
241
241
  instance_module.create_method(
242
242
  "#{attribute}=",
243
243
  parameters: [create_param("value", type: state_type)],
244
- return_type: state_type
244
+ return_type: state_type,
245
245
  )
246
246
  end
247
247
 
@@ -250,7 +250,7 @@ module Tapioca
250
250
  instance_module.create_method(
251
251
  "#{machine.name}?",
252
252
  parameters: [create_param("state", type: "T.any(String, Symbol)")],
253
- return_type: "T::Boolean"
253
+ return_type: "T::Boolean",
254
254
  )
255
255
  end
256
256
 
@@ -264,12 +264,12 @@ module Tapioca
264
264
  instance_module.create_method(
265
265
  events_attribute,
266
266
  parameters: [create_rest_param("args", type: "T.untyped")],
267
- return_type: "T::Array[T.any(String, Symbol)]"
267
+ return_type: "T::Array[T.any(String, Symbol)]",
268
268
  )
269
269
  instance_module.create_method(
270
270
  transitions_attribute,
271
271
  parameters: [create_rest_param("args", type: "T.untyped")],
272
- return_type: "T::Array[::StateMachines::Transition]"
272
+ return_type: "T::Array[::StateMachines::Transition]",
273
273
  )
274
274
  instance_module.create_method(
275
275
  "fire_#{event_attribute}",
@@ -277,26 +277,26 @@ module Tapioca
277
277
  create_param("event", type: "T.any(String, Symbol)"),
278
278
  create_rest_param("args", type: "T.untyped"),
279
279
  ],
280
- return_type: "T::Boolean"
280
+ return_type: "T::Boolean",
281
281
  )
282
282
  if machine.action
283
283
  instance_module.create_method(
284
284
  event_attribute,
285
- return_type: "T.nilable(Symbol)"
285
+ return_type: "T.nilable(Symbol)",
286
286
  )
287
287
  instance_module.create_method(
288
288
  "#{event_attribute}=",
289
289
  parameters: [create_param("value", type: "T.any(String, Symbol)")],
290
- return_type: "T.any(String, Symbol)"
290
+ return_type: "T.any(String, Symbol)",
291
291
  )
292
292
  instance_module.create_method(
293
293
  event_transition_attribute,
294
- return_type: "T.nilable(::StateMachines::Transition)"
294
+ return_type: "T.nilable(::StateMachines::Transition)",
295
295
  )
296
296
  instance_module.create_method(
297
297
  "#{event_transition_attribute}=",
298
298
  parameters: [create_param("value", type: "::StateMachines::Transition")],
299
- return_type: "::StateMachines::Transition"
299
+ return_type: "::StateMachines::Transition",
300
300
  )
301
301
  end
302
302
  end
@@ -308,7 +308,7 @@ module Tapioca
308
308
  instance_module.create_method(
309
309
  paths_attribute,
310
310
  parameters: [create_rest_param("args", type: "T.untyped")],
311
- return_type: "T::Array[::StateMachines::Transition]"
311
+ return_type: "T::Array[::StateMachines::Transition]",
312
312
  )
313
313
  end
314
314
 
@@ -316,7 +316,7 @@ module Tapioca
316
316
  params(
317
317
  instance_module: RBI::Module,
318
318
  class_module: RBI::Module,
319
- machine: ::StateMachines::Machine
319
+ machine: ::StateMachines::Machine,
320
320
  ).void
321
321
  end
322
322
  def define_name_helpers(instance_module, class_module, machine)
@@ -326,20 +326,20 @@ module Tapioca
326
326
  class_module.create_method(
327
327
  "human_#{name_attribute}",
328
328
  parameters: [create_param("state", type: "T.any(String, Symbol)")],
329
- return_type: "String"
329
+ return_type: "String",
330
330
  )
331
331
  class_module.create_method(
332
332
  "human_#{event_name_attribute}",
333
333
  parameters: [create_param("event", type: "T.any(String, Symbol)")],
334
- return_type: "String"
334
+ return_type: "String",
335
335
  )
336
336
  instance_module.create_method(
337
337
  name_attribute,
338
- return_type: "T.any(String, Symbol)"
338
+ return_type: "T.any(String, Symbol)",
339
339
  )
340
340
  instance_module.create_method(
341
341
  "human_#{name_attribute}",
342
- return_type: "String"
342
+ return_type: "String",
343
343
  )
344
344
  end
345
345
 
@@ -354,7 +354,7 @@ module Tapioca
354
354
  class_module.create_method(
355
355
  method.to_s,
356
356
  parameters: [create_rest_param("states", type: "T.any(String, Symbol)")],
357
- return_type: "T.untyped"
357
+ return_type: "T.untyped",
358
358
  )
359
359
  end
360
360
  end
@@ -154,7 +154,7 @@ module Tapioca
154
154
  mod.create_method(
155
155
  method.to_s,
156
156
  parameters: [create_rest_param("args", type: "T.untyped")],
157
- return_type: "String"
157
+ return_type: "String",
158
158
  )
159
159
  end
160
160
  end
@@ -15,7 +15,7 @@ module Tapioca
15
15
  "#{name}::", # compilers in this namespace
16
16
  "::", # compilers that need to be fully namespaced
17
17
  ],
18
- T::Array[String]
18
+ T::Array[String],
19
19
  )
20
20
  end
21
21
  end
@@ -36,7 +36,7 @@ module Tapioca
36
36
  )
37
37
  @active_compilers = T.let(
38
38
  gather_active_compilers(requested_compilers, excluded_compilers),
39
- T::Enumerable[T.class_of(Compiler)]
39
+ T::Enumerable[T.class_of(Compiler)],
40
40
  )
41
41
  @requested_constants = requested_constants
42
42
  @error_handler = error_handler
@@ -46,7 +46,7 @@ module Tapioca
46
46
 
47
47
  sig do
48
48
  type_parameters(:T).params(
49
- blk: T.proc.params(constant: Module, rbi: RBI::File).returns(T.type_parameter(:T))
49
+ blk: T.proc.params(constant: Module, rbi: RBI::File).returns(T.type_parameter(:T)),
50
50
  ).returns(T::Array[T.type_parameter(:T)])
51
51
  end
52
52
  def run(&blk)
@@ -63,7 +63,7 @@ module Tapioca
63
63
 
64
64
  result = Executor.new(
65
65
  constants_to_process,
66
- number_of_workers: @number_of_workers
66
+ number_of_workers: @number_of_workers,
67
67
  ).run_in_parallel do |constant|
68
68
  rbi = rbi_for_constant(constant)
69
69
  next if rbi.nil?
@@ -105,7 +105,7 @@ module Tapioca
105
105
  sig do
106
106
  params(
107
107
  requested_compilers: T::Array[T.class_of(Compiler)],
108
- excluded_compilers: T::Array[T.class_of(Compiler)]
108
+ excluded_compilers: T::Array[T.class_of(Compiler)],
109
109
  ).returns(T::Enumerable[T.class_of(Compiler)])
110
110
  end
111
111
  def gather_active_compilers(requested_compilers, excluded_compilers)
@@ -146,6 +146,7 @@ module Tapioca
146
146
  constants_by_name
147
147
  .keys
148
148
  .map { |name| T.cast(Runtime::Reflection.constantize(name), Module) }
149
+ .select { |mod| Runtime::Reflection.constant_defined?(mod) }
149
150
  .to_set
150
151
  end
151
152
 
@@ -16,13 +16,13 @@ module Tapioca
16
16
  # one has at least 4 items to process
17
17
  @number_of_workers = T.let(
18
18
  number_of_workers || [Etc.nprocessors, (queue.length.to_f / MINIMUM_ITEMS_PER_WORKER).ceil].min,
19
- Integer
19
+ Integer,
20
20
  )
21
21
  end
22
22
 
23
23
  sig do
24
24
  type_parameters(:T).params(
25
- block: T.proc.params(item: T.untyped).returns(T.type_parameter(:T))
25
+ block: T.proc.params(item: T.untyped).returns(T.type_parameter(:T)),
26
26
  ).returns(T::Array[T.type_parameter(:T)])
27
27
  end
28
28
  def run_in_parallel(&block)
@@ -124,7 +124,7 @@ module Tapioca
124
124
  method: UnboundMethod,
125
125
  node: RBI::Method,
126
126
  signature: T.untyped,
127
- parameters: T::Array[[Symbol, String]]
127
+ parameters: T::Array[[Symbol, String]],
128
128
  ).void.checked(:never)
129
129
  end
130
130
  def initialize(symbol, constant, method, node, signature, parameters) # rubocop:disable Metrics/ParameterLists
@@ -24,7 +24,7 @@ module Tapioca
24
24
  # The way we identify these "foreign constants" is by asking the mixin tracker which
25
25
  # constants have mixed in the current module that we are handling. We add all the
26
26
  # constants that we discover to the pipeline to be processed.
27
- Runtime::Trackers::Mixin.constants_with_mixin(mixin).each_value do |location_info|
27
+ Runtime::Trackers::Mixin.constants_with_mixin(mixin).each do |mixin_type, location_info|
28
28
  location_info.each do |constant, location|
29
29
  next unless mixed_in_by_gem?(location)
30
30
 
@@ -35,10 +35,11 @@ module Tapioca
35
35
  # base constant. Then, generate RBIs as if the base constant is extending the mixin,
36
36
  # which is functionally equivalent to including or prepending to the singleton class.
37
37
  if !name && constant.singleton_class?
38
- attached_class = attached_class_of(constant)
38
+ attached_class = Runtime::Trackers::Mixin.resolve_to_attached_class(constant, mixin, mixin_type)
39
39
  next unless attached_class
40
40
 
41
41
  constant = attached_class
42
+ name = @pipeline.name_of(constant)
42
43
  end
43
44
 
44
45
  @pipeline.push_foreign_constant(name, constant) if name
@@ -28,7 +28,7 @@ module Tapioca
28
28
  tree: RBI::Tree,
29
29
  module_name: String,
30
30
  mod: Module,
31
- for_visibility: T::Array[Symbol]
31
+ for_visibility: T::Array[Symbol],
32
32
  ).void
33
33
  end
34
34
  def compile_directly_owned_methods(tree, module_name, mod, for_visibility = [:public, :protected, :private])
@@ -57,7 +57,7 @@ module Tapioca
57
57
  symbol_name: String,
58
58
  constant: Module,
59
59
  method: T.nilable(UnboundMethod),
60
- visibility: RBI::Visibility
60
+ visibility: RBI::Visibility,
61
61
  ).void
62
62
  end
63
63
  def compile_method(tree, symbol_name, constant, method, visibility = RBI::Public.new)
@@ -112,7 +112,7 @@ module Tapioca
112
112
  rbi_method = RBI::Method.new(
113
113
  method_name,
114
114
  is_singleton: constant.singleton_class?,
115
- visibility: visibility
115
+ visibility: visibility,
116
116
  )
117
117
 
118
118
  sanitized_parameters.each do |type, name|
@@ -36,7 +36,7 @@ module Tapioca
36
36
  tree: RBI::Tree,
37
37
  constant: Module,
38
38
  mods: T::Array[Module],
39
- mixin_type: Runtime::Trackers::Mixin::Type
39
+ mixin_type: Runtime::Trackers::Mixin::Type,
40
40
  ).void
41
41
  end
42
42
  def add_mixins(tree, constant, mods, mixin_type)
@@ -69,15 +69,11 @@ module Tapioca
69
69
  params(
70
70
  constant: Module,
71
71
  mixin: Module,
72
- mixin_type: Runtime::Trackers::Mixin::Type
72
+ mixin_type: Runtime::Trackers::Mixin::Type,
73
73
  ).returns(T::Boolean)
74
74
  end
75
75
  def mixed_in_by_gem?(constant, mixin, mixin_type)
76
- mixin_location =
77
- T.cast(
78
- Runtime::Trackers::Mixin.constants_with_mixin(mixin).dig(mixin_type, constant),
79
- T.nilable(String)
80
- )
76
+ mixin_location = Runtime::Trackers::Mixin.mixin_location(mixin, mixin_type, constant)
81
77
 
82
78
  return true if mixin_location.nil?
83
79
 
@@ -61,7 +61,7 @@ module Tapioca
61
61
  gem_name: gem.name,
62
62
  gem_version: version,
63
63
  path: path.to_s,
64
- line_number: line.to_s
64
+ line_number: line.to_s,
65
65
  )
66
66
  node.comments << RBI::Comment.new("") if node.comments.any?
67
67
  node.comments << RBI::Comment.new(uri.to_s)
@@ -26,7 +26,7 @@ module Tapioca
26
26
  # Don't compile modules of Object because Object::Foo == Foo
27
27
  # Don't compile modules of BasicObject because BasicObject::BasicObject == BasicObject
28
28
  next if (Object == constant || BasicObject == constant) && Module === subconstant
29
- next unless subconstant
29
+ next unless Runtime::Reflection.constant_defined?(subconstant)
30
30
 
31
31
  @pipeline.push_constant(name, subconstant)
32
32
  end
@@ -43,7 +43,7 @@ module Tapioca
43
43
  separator = event.constant.singleton_class? ? "." : "#"
44
44
  event.node.comments = documentation_comments(
45
45
  "#{event.symbol}#{separator}#{event.node.name}",
46
- sigs: event.node.sigs
46
+ sigs: event.node.sigs,
47
47
  )
48
48
  end
49
49
 
@@ -91,7 +91,7 @@ module Tapioca
91
91
  method: UnboundMethod,
92
92
  node: RBI::Method,
93
93
  signature: T.untyped,
94
- parameters: T::Array[[Symbol, String]]
94
+ parameters: T::Array[[Symbol, String]],
95
95
  ).void.checked(:never)
96
96
  end
97
97
  def push_method(symbol, constant, method, node, signature, parameters) # rubocop:disable Metrics/ParameterLists
@@ -162,7 +162,7 @@ module Tapioca
162
162
  return if symbol_in_payload?(symbol) && !@bootstrap_symbols.include?(symbol)
163
163
 
164
164
  constant = constantize(symbol)
165
- push_constant(symbol, constant) if constant
165
+ push_constant(symbol, constant) if Runtime::Reflection.constant_defined?(constant)
166
166
  end
167
167
 
168
168
  sig { params(event: Gem::ConstantFound).void.checked(:never) }
@@ -260,6 +260,7 @@ module Tapioca
260
260
  return if klass_name&.start_with?("T::Types::", "T::Private::")
261
261
 
262
262
  type_name = klass_name || "T.untyped"
263
+ type_name = "T.untyped" if type_name == "NilClass"
263
264
  node = RBI::Const.new(name, "T.let(T.unsafe(nil), #{type_name})")
264
265
  push_const(name, klass, node)
265
266
  @root << node
@@ -321,7 +322,7 @@ module Tapioca
321
322
  next unless superclass_name
322
323
 
323
324
  resolved_superclass = constantize(superclass_name)
324
- next unless Module === resolved_superclass
325
+ next unless Module === resolved_superclass && Runtime::Reflection.constant_defined?(resolved_superclass)
325
326
  next if name_of(resolved_superclass) == constant_name
326
327
 
327
328
  # We found a suitable superclass
@@ -390,6 +391,9 @@ module Tapioca
390
391
  type_variables = Runtime::GenericTypeRegistry.lookup_type_variables(constant)
391
392
  return type_name unless type_variables
392
393
 
394
+ type_variables = type_variables.reject(&:fixed?)
395
+ return type_name if type_variables.empty?
396
+
393
397
  type_variable_names = type_variables.map { "T.untyped" }.join(", ")
394
398
 
395
399
  "#{type_name}[#{type_variable_names}]"