tapioca 0.10.1 → 0.10.2

Sign up to get free protection for your applications and to get access to all the features.
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}]"