tapioca 0.11.6 → 0.11.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8ee3bcaf55b533576a46aa60a0a03b946552ee3fba42f8b136108dea8d0888ba
4
- data.tar.gz: b0d12f84750676a3b99eb7e76e10d3be64a92359f5a440c0c8c5ef9c7f3e5ac9
3
+ metadata.gz: 68b1a51d995ed5925df2983b0fdc55ef14bdfb828780077035048f1a6305ad74
4
+ data.tar.gz: 9689fa2965d90459e47618b2d41df0e24acdb9599d3552205ed973fa37126c9b
5
5
  SHA512:
6
- metadata.gz: cf6bb9e139fabc27048c5237f0e8662f5972051ae01fd1fcaae34f11c23fceb471f7d7118df9dabd507b24f7fccf8d4a6208dfd02d08ed37453b1ef2679ba04f
7
- data.tar.gz: 2860aaa02b120a10182e7928fdc54f48d6eca933f4eee8ec51df78ae59043bc59c6cc839b1a65d2fe610c3ec545ad68b2caf400821b32c7ee029ca0046b88009
6
+ metadata.gz: 78cfdeb935bd82157c0f98344af6e131f5c5d0b256076ac69b1518f044f08ace764cfe7efe153928c7209a451ce194ae7d2ac82cebf68c1aed937b3016ba6cb3
7
+ data.tar.gz: d51e8ca0aafb1764efa553387d2569aec765c0eb6d5ac8344843b131d75fa6b2daa5bca6daa4304229eb6313ef244752fb1ec66c2c10d5868ee8983174bf5f3e
data/README.md CHANGED
@@ -163,36 +163,38 @@ Usage:
163
163
  tapioca gem [gem...]
164
164
 
165
165
  Options:
166
- --out, -o, [--outdir=directory] # The output directory for generated gem RBI files
167
- # Default: sorbet/rbi/gems
168
- [--file-header], [--no-file-header] # Add a "This file is generated" header on top of each generated RBI file
169
- # Default: true
170
- [--all], [--no-all] # Regenerate RBI files for all gems
171
- --pre, -b, [--prerequire=file] # A file to be required before Bundler.require is called
172
- --post, -a, [--postrequire=file] # A file to be required after Bundler.require is called
173
- # Default: sorbet/tapioca/require.rb
174
- -x, [--exclude=gem [gem ...]] # Exclude the given gem(s) from RBI generation
175
- --typed, -t, [--typed-overrides=gem:level [gem:level ...]] # Override for typed sigils for generated gem RBIs
176
- # Default: {"activesupport"=>"false"}
177
- [--verify], [--no-verify] # Verify RBIs are up-to-date
178
- [--doc], [--no-doc] # Include YARD documentation from sources when generating RBIs. Warning: this might be slow
179
- # Default: true
180
- [--loc], [--no-loc] # Include comments with source location when generating RBIs
181
- # Default: true
182
- [--exported-gem-rbis], [--no-exported-gem-rbis] # Include RBIs found in the `rbi/` directory of the gem
183
- # Default: true
184
- -w, [--workers=N] # Number of parallel workers to use when generating RBIs (default: auto)
185
- [--auto-strictness], [--no-auto-strictness] # Autocorrect strictness in gem RBIs in case of conflict with the DSL RBIs
186
- # Default: true
187
- --dsl-dir, [--dsl-dir=directory] # The DSL directory used to correct gems strictnesses
188
- # Default: sorbet/rbi/dsl
189
- [--rbi-max-line-length=N] # Set the max line length of generated RBIs. Signatures longer than the max line length will be wrapped
190
- # Default: 120
191
- -e, [--environment=ENVIRONMENT] # The Rack/Rails environment to use when generating RBIs
192
- # Default: development
193
- -c, [--config=<config file path>] # Path to the Tapioca configuration file
194
- # Default: sorbet/tapioca/config.yml
195
- -V, [--verbose], [--no-verbose] # Verbose output for debugging purposes
166
+ --out, -o, [--outdir=directory] # The output directory for generated gem RBI files
167
+ # Default: sorbet/rbi/gems
168
+ [--file-header], [--no-file-header] # Add a "This file is generated" header on top of each generated RBI file
169
+ # Default: true
170
+ [--all], [--no-all] # Regenerate RBI files for all gems
171
+ --pre, -b, [--prerequire=file] # A file to be required before Bundler.require is called
172
+ --post, -a, [--postrequire=file] # A file to be required after Bundler.require is called
173
+ # Default: sorbet/tapioca/require.rb
174
+ -x, [--exclude=gem [gem ...]] # Exclude the given gem(s) from RBI generation
175
+ --typed, -t, [--typed-overrides=gem:level [gem:level ...]] # Override for typed sigils for generated gem RBIs
176
+ # Default: {"activesupport"=>"false"}
177
+ [--verify], [--no-verify] # Verify RBIs are up-to-date
178
+ [--doc], [--no-doc] # Include YARD documentation from sources when generating RBIs. Warning: this might be slow
179
+ # Default: true
180
+ [--loc], [--no-loc] # Include comments with source location when generating RBIs
181
+ # Default: true
182
+ [--exported-gem-rbis], [--no-exported-gem-rbis] # Include RBIs found in the `rbi/` directory of the gem
183
+ # Default: true
184
+ -w, [--workers=N] # Number of parallel workers to use when generating RBIs (default: auto)
185
+ [--auto-strictness], [--no-auto-strictness] # Autocorrect strictness in gem RBIs in case of conflict with the DSL RBIs
186
+ # Default: true
187
+ --dsl-dir, [--dsl-dir=directory] # The DSL directory used to correct gems strictnesses
188
+ # Default: sorbet/rbi/dsl
189
+ [--rbi-max-line-length=N] # Set the max line length of generated RBIs. Signatures longer than the max line length will be wrapped
190
+ # Default: 120
191
+ -e, [--environment=ENVIRONMENT] # The Rack/Rails environment to use when generating RBIs
192
+ # Default: development
193
+ [--halt-upon-load-error], [--no-halt-upon-load-error] # Halt upon a load error while loading the Rails application
194
+ # Default: true
195
+ -c, [--config=<config file path>] # Path to the Tapioca configuration file
196
+ # Default: sorbet/tapioca/config.yml
197
+ -V, [--verbose], [--no-verbose] # Verbose output for debugging purposes
196
198
 
197
199
  generate RBIs from gems
198
200
  ```
@@ -347,16 +349,16 @@ Usage:
347
349
  tapioca annotations
348
350
 
349
351
  Options:
350
- [--sources=one two three] # URIs of the sources to pull gem RBI annotations from
352
+ [--sources=one two three] # URIs of the sources to pull gem RBI annotations from
351
353
  # Default: ["https://raw.githubusercontent.com/Shopify/rbi-central/main"]
352
- [--netrc], [--no-netrc] # Use .netrc to authenticate to private sources
354
+ [--netrc], [--no-netrc] # Use .netrc to authenticate to private sources
353
355
  # Default: true
354
- [--netrc-file=NETRC_FILE] # Path to .netrc file
355
- [--auth=AUTH] # HTTP authorization header for private sources
356
+ [--netrc-file=NETRC_FILE] # Path to .netrc file
357
+ [--auth=AUTH] # HTTP authorization header for private sources
356
358
  --typed, -t, [--typed-overrides=gem:level [gem:level ...]] # Override for typed sigils for pulled annotations
357
- -c, [--config=<config file path>] # Path to the Tapioca configuration file
359
+ -c, [--config=<config file path>] # Path to the Tapioca configuration file
358
360
  # Default: sorbet/tapioca/config.yml
359
- -V, [--verbose], [--no-verbose] # Verbose output for debugging purposes
361
+ -V, [--verbose], [--no-verbose] # Verbose output for debugging purposes
360
362
 
361
363
  Pull gem RBI annotations from remote sources
362
364
  ```
@@ -458,26 +460,28 @@ Usage:
458
460
  tapioca dsl [constant...]
459
461
 
460
462
  Options:
461
- --out, -o, [--outdir=directory] # The output directory for generated DSL RBI files
462
- # Default: sorbet/rbi/dsl
463
- [--file-header], [--no-file-header] # Add a "This file is generated" header on top of each generated RBI file
464
- # Default: true
465
- [--only=compiler [compiler ...]] # Only run supplied DSL compiler(s)
466
- [--exclude=compiler [compiler ...]] # Exclude supplied DSL compiler(s)
467
- [--verify], [--no-verify] # Verifies RBIs are up-to-date
468
- -q, [--quiet], [--no-quiet] # Suppresses file creation output
469
- -w, [--workers=N] # Number of parallel workers to use when generating RBIs (default: 2)
470
- # Default: 2
471
- [--rbi-max-line-length=N] # Set the max line length of generated RBIs. Signatures longer than the max line length will be wrapped
472
- # Default: 120
473
- -e, [--environment=ENVIRONMENT] # The Rack/Rails environment to use when generating RBIs
474
- # Default: development
475
- -l, [--list-compilers], [--no-list-compilers] # List all loaded compilers
476
- [--app-root=APP_ROOT] # The path to the Rails application
477
- # Default: .
478
- -c, [--config=<config file path>] # Path to the Tapioca configuration file
479
- # Default: sorbet/tapioca/config.yml
480
- -V, [--verbose], [--no-verbose] # Verbose output for debugging purposes
463
+ --out, -o, [--outdir=directory] # The output directory for generated DSL RBI files
464
+ # Default: sorbet/rbi/dsl
465
+ [--file-header], [--no-file-header] # Add a "This file is generated" header on top of each generated RBI file
466
+ # Default: true
467
+ [--only=compiler [compiler ...]] # Only run supplied DSL compiler(s)
468
+ [--exclude=compiler [compiler ...]] # Exclude supplied DSL compiler(s)
469
+ [--verify], [--no-verify] # Verifies RBIs are up-to-date
470
+ -q, [--quiet], [--no-quiet] # Suppresses file creation output
471
+ -w, [--workers=N] # Number of parallel workers to use when generating RBIs (default: 2)
472
+ # Default: 2
473
+ [--rbi-max-line-length=N] # Set the max line length of generated RBIs. Signatures longer than the max line length will be wrapped
474
+ # Default: 120
475
+ -e, [--environment=ENVIRONMENT] # The Rack/Rails environment to use when generating RBIs
476
+ # Default: development
477
+ -l, [--list-compilers], [--no-list-compilers] # List all loaded compilers
478
+ [--app-root=APP_ROOT] # The path to the Rails application
479
+ # Default: .
480
+ [--halt-upon-load-error], [--no-halt-upon-load-error] # Halt upon a load error while loading the Rails application
481
+ # Default: true
482
+ -c, [--config=<config file path>] # Path to the Tapioca configuration file
483
+ # Default: sorbet/tapioca/config.yml
484
+ -V, [--verbose], [--no-verbose] # Verbose output for debugging purposes
481
485
 
482
486
  generate RBIs for dynamic methods
483
487
  ```
@@ -827,6 +831,7 @@ dsl:
827
831
  environment: development
828
832
  list_compilers: false
829
833
  app_root: "."
834
+ halt_upon_load_error: true
830
835
  gem:
831
836
  outdir: sorbet/rbi/gems
832
837
  file_header: true
@@ -845,6 +850,7 @@ gem:
845
850
  dsl_dir: sorbet/rbi/dsl
846
851
  rbi_max_line_length: 120
847
852
  environment: development
853
+ halt_upon_load_error: true
848
854
  check_shims:
849
855
  gem_rbi_dir: sorbet/rbi/gems
850
856
  dsl_rbi_dir: sorbet/rbi/dsl
@@ -0,0 +1,69 @@
1
+ # typed: true
2
+ # frozen_string_literal: true
3
+
4
+ module Tapioca
5
+ module BundlerExt
6
+ # This is a module that gets prepended to `Bundler::Dependency` and
7
+ # makes sure even gems marked as `require: false` are required during
8
+ # `Bundler.require`.
9
+ module AutoRequireHook
10
+ extend T::Sig
11
+ extend T::Helpers
12
+
13
+ requires_ancestor { ::Bundler::Dependency }
14
+
15
+ @exclude = T.let([], T::Array[String])
16
+ @enabled = T.let(false, T::Boolean)
17
+
18
+ class << self
19
+ extend T::Sig
20
+
21
+ sig { params(name: T.untyped).returns(T::Boolean) }
22
+ def excluded?(name)
23
+ @exclude.include?(name)
24
+ end
25
+
26
+ def enabled?
27
+ @enabled
28
+ end
29
+
30
+ sig do
31
+ type_parameters(:Result).params(
32
+ exclude: T::Array[String],
33
+ blk: T.proc.returns(T.type_parameter(:Result)),
34
+ ).returns(T.type_parameter(:Result))
35
+ end
36
+ def override_require_false(exclude:, &blk)
37
+ @enabled = true
38
+ @exclude = exclude
39
+ blk.call
40
+ ensure
41
+ @enabled = false
42
+ end
43
+ end
44
+
45
+ sig { returns(T.untyped).checked(:never) }
46
+ def autorequire
47
+ value = super
48
+
49
+ # If autorequire is not enabled, we don't want to force require gems
50
+ return value unless AutoRequireHook.enabled?
51
+
52
+ # If the gem is excluded, we don't want to force require it, in case
53
+ # it has side-effects users don't want. For example, `fakefs` gem, if
54
+ # loaded, takes over filesystem operations.
55
+ return value if AutoRequireHook.excluded?(name)
56
+
57
+ # If a gem is marked as `require: false`, then its `autorequire`
58
+ # value will be `[]`. But, we want those gems to be loaded for our
59
+ # purposes as well, so we return `nil` in those cases, instead, which
60
+ # means `require: true`.
61
+ return nil if value == []
62
+
63
+ value
64
+ end
65
+
66
+ ::Bundler::Dependency.prepend(self)
67
+ end
68
+ end
69
+ end
data/lib/tapioca/cli.rb CHANGED
@@ -130,6 +130,10 @@ module Tapioca
130
130
  type: :string,
131
131
  desc: "The path to the Rails application",
132
132
  default: "."
133
+ option :halt_upon_load_error,
134
+ type: :boolean,
135
+ desc: "Halt upon a load error while loading the Rails application",
136
+ default: true
133
137
  def dsl(*constant_or_paths)
134
138
  set_environment(options)
135
139
 
@@ -150,6 +154,7 @@ module Tapioca
150
154
  number_of_workers: options[:workers],
151
155
  rbi_formatter: rbi_formatter(options),
152
156
  app_root: options[:app_root],
157
+ halt_upon_load_error: options[:halt_upon_load_error],
153
158
  )
154
159
 
155
160
  Tapioca.silence_warnings do
@@ -235,6 +240,10 @@ module Tapioca
235
240
  type: :string,
236
241
  desc: "The Rack/Rails environment to use when generating RBIs",
237
242
  default: DEFAULT_ENVIRONMENT
243
+ option :halt_upon_load_error,
244
+ type: :boolean,
245
+ desc: "Halt upon a load error while loading the Rails application",
246
+ default: true
238
247
  def gem(*gems)
239
248
  Tapioca.silence_warnings do
240
249
  set_environment(options)
@@ -257,6 +266,7 @@ module Tapioca
257
266
  auto_strictness: options[:auto_strictness],
258
267
  dsl_dir: options[:dsl_dir],
259
268
  rbi_formatter: rbi_formatter(options),
269
+ halt_upon_load_error: options[:halt_upon_load_error],
260
270
  )
261
271
 
262
272
  raise MalformattedArgumentError, "Options '--all' and '--verify' are mutually exclusive" if all && verify
@@ -24,6 +24,7 @@ module Tapioca
24
24
  gem_dir: String,
25
25
  rbi_formatter: RBIFormatter,
26
26
  app_root: String,
27
+ halt_upon_load_error: T::Boolean,
27
28
  ).void
28
29
  end
29
30
  def initialize(
@@ -41,7 +42,8 @@ module Tapioca
41
42
  auto_strictness: true,
42
43
  gem_dir: DEFAULT_GEM_DIR,
43
44
  rbi_formatter: DEFAULT_RBI_FORMATTER,
44
- app_root: "."
45
+ app_root: ".",
46
+ halt_upon_load_error: true
45
47
  )
46
48
  @requested_constants = requested_constants
47
49
  @requested_paths = requested_paths
@@ -58,6 +60,7 @@ module Tapioca
58
60
  @gem_dir = gem_dir
59
61
  @rbi_formatter = rbi_formatter
60
62
  @app_root = app_root
63
+ @halt_upon_load_error = halt_upon_load_error
61
64
 
62
65
  super()
63
66
  end
@@ -68,6 +71,7 @@ module Tapioca
68
71
  tapioca_path: @tapioca_path,
69
72
  eager_load: @requested_constants.empty? && @requested_paths.empty?,
70
73
  app_root: @app_root,
74
+ halt_upon_load_error: @halt_upon_load_error,
71
75
  )
72
76
 
73
77
  pipeline = create_pipeline
@@ -95,6 +99,7 @@ module Tapioca
95
99
  tapioca_path: @tapioca_path,
96
100
  eager_load: @requested_constants.empty? && @requested_paths.empty?,
97
101
  app_root: @app_root,
102
+ halt_upon_load_error: @halt_upon_load_error,
98
103
  )
99
104
 
100
105
  if @should_verify
@@ -23,6 +23,7 @@ module Tapioca
23
23
  auto_strictness: T::Boolean,
24
24
  dsl_dir: String,
25
25
  rbi_formatter: RBIFormatter,
26
+ halt_upon_load_error: T::Boolean,
26
27
  ).void
27
28
  end
28
29
  def initialize(
@@ -39,7 +40,8 @@ module Tapioca
39
40
  number_of_workers: nil,
40
41
  auto_strictness: true,
41
42
  dsl_dir: DEFAULT_DSL_DIR,
42
- rbi_formatter: DEFAULT_RBI_FORMATTER
43
+ rbi_formatter: DEFAULT_RBI_FORMATTER,
44
+ halt_upon_load_error: true
43
45
  )
44
46
  @gem_names = gem_names
45
47
  @exclude = exclude
@@ -61,6 +63,7 @@ module Tapioca
61
63
  @include_doc = T.let(include_doc, T::Boolean)
62
64
  @include_loc = T.let(include_loc, T::Boolean)
63
65
  @include_exported_rbis = include_exported_rbis
66
+ @halt_upon_load_error = halt_upon_load_error
64
67
  end
65
68
 
66
69
  sig { override.void }
@@ -70,6 +73,7 @@ module Tapioca
70
73
  prerequire: @prerequire,
71
74
  postrequire: @postrequire,
72
75
  default_command: default_command(:require),
76
+ halt_upon_load_error: @halt_upon_load_error,
73
77
  )
74
78
 
75
79
  gem_queue = gems_to_generate(@gem_names).reject { |gem| @exclude.include?(gem.name) }
@@ -245,6 +249,7 @@ module Tapioca
245
249
  prerequire: @prerequire,
246
250
  postrequire: @postrequire,
247
251
  default_command: default_command(:require),
252
+ halt_upon_load_error: @halt_upon_load_error,
248
253
  )
249
254
 
250
255
  Executor.new(gems, number_of_workers: @number_of_workers).run_in_parallel do |gem_name|
@@ -43,10 +43,10 @@ module Tapioca
43
43
 
44
44
  private
45
45
 
46
- sig { returns(T::Enumerable[Class]) }
46
+ sig { returns(T::Enumerable[T::Class[T.anything]]) }
47
47
  def all_classes
48
- @all_classes = T.let(@all_classes, T.nilable(T::Enumerable[Class]))
49
- @all_classes ||= T.cast(ObjectSpace.each_object(Class), T::Enumerable[Class]).each
48
+ @all_classes = T.let(@all_classes, T.nilable(T::Enumerable[T::Class[T.anything]]))
49
+ @all_classes ||= T.cast(ObjectSpace.each_object(Class), T::Enumerable[T::Class[T.anything]]).each
50
50
  end
51
51
 
52
52
  sig { returns(T::Enumerable[Module]) }
@@ -74,7 +74,7 @@ module Tapioca
74
74
  T::Array[String],
75
75
  )
76
76
 
77
- ConstantType = type_member { { fixed: T.all(::AASM::ClassMethods, Class) } }
77
+ ConstantType = type_member { { fixed: T.all(T::Class[::AASM], ::AASM::ClassMethods) } }
78
78
 
79
79
  sig { override.void }
80
80
  def decorate
@@ -39,7 +39,9 @@ module Tapioca
39
39
  class ActiveModelAttributes < Compiler
40
40
  extend T::Sig
41
41
 
42
- ConstantType = type_member { { fixed: T.all(Class, ::ActiveModel::Attributes::ClassMethods) } }
42
+ ConstantType = type_member do
43
+ { fixed: T.all(T::Class[::ActiveModel::Attributes], ::ActiveModel::Attributes::ClassMethods) }
44
+ end
43
45
 
44
46
  sig { override.void }
45
47
  def decorate
@@ -60,7 +60,9 @@ module Tapioca
60
60
  class ActiveModelSecurePassword < Compiler
61
61
  extend T::Sig
62
62
 
63
- ConstantType = type_member { { fixed: T.all(Class, ::ActiveModel::SecurePassword::ClassMethods) } }
63
+ ConstantType = type_member do
64
+ { fixed: T.all(T::Class[::ActiveModel::SecurePassword], ::ActiveModel::SecurePassword::ClassMethods) }
65
+ end
64
66
 
65
67
  sig { override.void }
66
68
  def decorate
@@ -110,10 +110,11 @@ module Tapioca
110
110
  return_type: "ActiveSupport::StringInquirer",
111
111
  )
112
112
 
113
+ return_type = sorbet_supports?(:generic_class) ? "T::Class[T.anything]" : "Class"
113
114
  mod.create_method(
114
115
  "#{role}_class",
115
116
  parameters: [],
116
- return_type: "Class",
117
+ return_type: return_type,
117
118
  )
118
119
 
119
120
  mod.create_method(
@@ -70,15 +70,24 @@ module Tapioca
70
70
 
71
71
  private
72
72
 
73
- sig { returns(Class) }
73
+ sig { returns(T::Class[ActiveRecord::TestFixtures]) }
74
74
  def fixture_loader
75
75
  @fixture_loader ||= T.let(
76
- Class.new do
77
- T.unsafe(self).include(ActiveRecord::TestFixtures)
78
- T.unsafe(self).fixture_path = Rails.root.join("test", "fixtures")
79
- T.unsafe(self).fixtures(:all)
80
- end,
81
- T.nilable(Class),
76
+ T.cast(
77
+ Class.new do
78
+ T.unsafe(self).include(ActiveRecord::TestFixtures)
79
+
80
+ T.unsafe(self).fixture_path = Rails.root.join("test", "fixtures")
81
+ # https://github.com/rails/rails/blob/7c70791470fc517deb7c640bead9f1b47efb5539/activerecord/lib/active_record/test_fixtures.rb#L46
82
+ singleton_class.define_method(:file_fixture_path) do
83
+ Rails.root.join("test", "fixtures", "files")
84
+ end
85
+
86
+ T.unsafe(self).fixtures(:all)
87
+ end,
88
+ T::Class[ActiveRecord::TestFixtures],
89
+ ),
90
+ T.nilable(T::Class[ActiveRecord::TestFixtures]),
82
91
  )
83
92
  end
84
93
 
@@ -70,7 +70,9 @@ module Tapioca
70
70
  class Kredis < Compiler
71
71
  extend T::Sig
72
72
 
73
- ConstantType = type_member { { fixed: T.all(Class, ::Kredis::Attributes::ClassMethods, Extensions::Kredis) } }
73
+ ConstantType = type_member do
74
+ { fixed: T.all(T::Class[::Kredis::Attributes], ::Kredis::Attributes::ClassMethods, Extensions::Kredis) }
75
+ end
74
76
 
75
77
  sig { override.void }
76
78
  def decorate
@@ -78,7 +78,7 @@ module Tapioca
78
78
 
79
79
  extend T::Sig
80
80
 
81
- ConstantType = type_member { { fixed: Module } }
81
+ ConstantType = type_member { { fixed: T::Class[T.anything] } }
82
82
 
83
83
  FIELD_RE = /^[a-z_][a-zA-Z0-9_]*$/
84
84
 
@@ -206,7 +206,7 @@ module Tapioca
206
206
  # > field, even if it was not defined in the enum.
207
207
  "T.any(Symbol, Integer)"
208
208
  when :message
209
- descriptor.subtype.msgclass.name
209
+ descriptor.subtype.msgclass.name || "T.untyped"
210
210
  when :int32, :int64, :uint32, :uint64
211
211
  "Integer"
212
212
  when :double, :float
@@ -225,14 +225,24 @@ module Tapioca
225
225
  descriptor.label == :optional && descriptor.type == :message
226
226
  end
227
227
 
228
+ sig { params(descriptor: Google::Protobuf::FieldDescriptor).returns(T::Boolean) }
229
+ def map_type?(descriptor)
230
+ # Defensively make sure that we are dealing with a repeated field
231
+ return false unless descriptor.label == :repeated
232
+
233
+ # Try to create a new instance with the field that maps to the descriptor name
234
+ # being assinged a hash value. If this goes through, then it's a map type.
235
+ constant.new(**{ descriptor.name => {} })
236
+ true
237
+ rescue ArgumentError
238
+ # This means the descriptor is not a map type
239
+ false
240
+ end
241
+
228
242
  sig { params(descriptor: Google::Protobuf::FieldDescriptor).returns(Field) }
229
243
  def field_of(descriptor)
230
244
  if descriptor.label == :repeated
231
- # Here we're going to check if the submsg_name is named according to
232
- # how Google names map entries.
233
- # https://github.com/protocolbuffers/protobuf/blob/f82e26/ruby/ext/google/protobuf_c/defs.c#L1963-L1966
234
- if descriptor.submsg_name.to_s.end_with?("_MapEntry_#{descriptor.name}") ||
235
- descriptor.submsg_name.to_s.end_with?("FieldsEntry")
245
+ if map_type?(descriptor)
236
246
  key = descriptor.subtype.lookup("key")
237
247
  value = descriptor.subtype.lookup("value")
238
248
 
@@ -20,7 +20,7 @@ module Tapioca
20
20
 
21
21
  compile_method(node, symbol, constant, initialize_method_for(constant))
22
22
  compile_directly_owned_methods(node, symbol, constant)
23
- compile_directly_owned_methods(node, symbol, singleton_class_of(constant))
23
+ compile_directly_owned_methods(node, symbol, singleton_class_of(constant), attached_class: constant)
24
24
  end
25
25
 
26
26
  sig do
@@ -29,14 +29,22 @@ module Tapioca
29
29
  module_name: String,
30
30
  mod: Module,
31
31
  for_visibility: T::Array[Symbol],
32
+ attached_class: T.nilable(Module),
32
33
  ).void
33
34
  end
34
- def compile_directly_owned_methods(tree, module_name, mod, for_visibility = [:public, :protected, :private])
35
+ def compile_directly_owned_methods(
36
+ tree,
37
+ module_name,
38
+ mod,
39
+ for_visibility = [:public, :protected, :private],
40
+ attached_class: nil
41
+ )
35
42
  method_names_by_visibility(mod)
36
43
  .delete_if { |visibility, _method_list| !for_visibility.include?(visibility) }
37
44
  .each do |visibility, method_list|
38
45
  method_list.sort!.map do |name|
39
46
  next if name == :initialize
47
+ next if method_new_in_abstract_class?(attached_class, name)
40
48
 
41
49
  vis = case visibility
42
50
  when :protected
@@ -180,6 +188,19 @@ module Tapioca
180
188
  .include?(method_name.gsub(/=$/, "").to_sym)
181
189
  end
182
190
 
191
+ sig do
192
+ params(
193
+ attached_class: T.nilable(Module),
194
+ method_name: Symbol,
195
+ ).returns(T.nilable(T::Boolean))
196
+ end
197
+ def method_new_in_abstract_class?(attached_class, method_name)
198
+ attached_class &&
199
+ method_name == :new &&
200
+ !!abstract_type_of(attached_class) &&
201
+ Class === attached_class.singleton_class
202
+ end
203
+
183
204
  sig { params(constant: Module).returns(T.nilable(UnboundMethod)) }
184
205
  def initialize_method_for(constant)
185
206
  constant.instance_method(:initialize)
@@ -16,12 +16,11 @@ module Tapioca
16
16
  constant = event.constant
17
17
  node = event.node
18
18
 
19
- abstract_type = T::Private::Abstract::Data.get(constant, :abstract_type) ||
20
- T::Private::Abstract::Data.get(singleton_class_of(constant), :abstract_type)
19
+ abstract_type = abstract_type_of(constant)
21
20
 
22
21
  node << RBI::Helper.new(abstract_type.to_s) if abstract_type
23
- node << RBI::Helper.new("final") if T::Private::Final.final_module?(constant)
24
- node << RBI::Helper.new("sealed") if T::Private::Sealed.sealed_module?(constant)
22
+ node << RBI::Helper.new("final") if final_module?(constant)
23
+ node << RBI::Helper.new("sealed") if sealed_module?(constant)
25
24
  end
26
25
 
27
26
  sig { override.params(event: NodeAdded).returns(T::Boolean) }
@@ -31,14 +31,14 @@ module Tapioca
31
31
 
32
32
  # Map each type variable to its string representation.
33
33
  #
34
- # Each entry of `type_variables` maps a Module to a String,
35
- # and the order they are inserted into the hash is the order they should be
36
- # defined in the source code.
37
- type_variable_declarations = type_variables.map do |type_variable|
38
- type_variable_name = type_variable.name
39
- next unless type_variable_name
34
+ # Each entry of `type_variables` maps a Module to a String, or
35
+ # is a `has_attached_class!` declaration, and the order they are inserted
36
+ # into the hash is the order they should be defined in the source code.
37
+ type_variable_declarations = type_variables.filter_map do |type_variable|
38
+ node = node_from_type_variable(type_variable)
39
+ next unless node
40
40
 
41
- tree << RBI::TypeMember.new(type_variable_name, type_variable.serialize)
41
+ tree << node
42
42
  end
43
43
 
44
44
  return if type_variable_declarations.empty?
@@ -46,6 +46,19 @@ module Tapioca
46
46
  tree << RBI::Extend.new("T::Generic")
47
47
  end
48
48
 
49
+ sig { params(type_variable: Tapioca::TypeVariableModule).returns(T.nilable(RBI::Node)) }
50
+ def node_from_type_variable(type_variable)
51
+ case type_variable.type
52
+ when Tapioca::TypeVariableModule::Type::HasAttachedClass
53
+ RBI::Send.new(type_variable.serialize)
54
+ else
55
+ type_variable_name = type_variable.name
56
+ return unless type_variable_name
57
+
58
+ RBI::TypeMember.new(type_variable_name, type_variable.serialize)
59
+ end
60
+ end
61
+
49
62
  sig { override.params(event: NodeAdded).returns(T::Boolean) }
50
63
  def ignore?(event)
51
64
  event.is_a?(Tapioca::Gem::ForeignScopeNodeAdded)
@@ -304,9 +304,9 @@ module Tapioca
304
304
  @root << scope
305
305
  end
306
306
 
307
- sig { params(constant: Class).returns(T.nilable(String)) }
307
+ sig { params(constant: T::Class[T.anything]).returns(T.nilable(String)) }
308
308
  def compile_superclass(constant)
309
- superclass = T.let(nil, T.nilable(Class)) # rubocop:disable Lint/UselessAssignment
309
+ superclass = T.let(nil, T.nilable(T::Class[T.anything])) # rubocop:disable Lint/UselessAssignment
310
310
 
311
311
  while (superclass = superclass_of(constant))
312
312
  constant_name = name_of(constant)
@@ -1,6 +1,8 @@
1
1
  # typed: strict
2
2
  # frozen_string_literal: true
3
3
 
4
+ require "tapioca/bundler_ext/auto_require_hook"
5
+
4
6
  module Tapioca
5
7
  class Gemfile
6
8
  extend(T::Sig)
@@ -12,50 +14,6 @@ module Tapioca
12
14
  )
13
15
  end
14
16
 
15
- # This is a module that gets prepended to `Bundler::Dependency` and
16
- # makes sure even gems marked as `require: false` are required during
17
- # `Bundler.require`.
18
- module AutoRequireHook
19
- extend T::Sig
20
- extend T::Helpers
21
-
22
- requires_ancestor { ::Bundler::Dependency }
23
-
24
- @exclude = T.let([], T::Array[String])
25
-
26
- class << self
27
- extend T::Sig
28
-
29
- sig { params(exclude: T::Array[String]).returns(T::Array[String]) }
30
- attr_writer :exclude
31
-
32
- sig { params(name: T.untyped).returns(T::Boolean) }
33
- def excluded?(name)
34
- @exclude.include?(name)
35
- end
36
- end
37
-
38
- sig { returns(T.untyped).checked(:never) }
39
- def autorequire
40
- value = super
41
-
42
- # If the gem is excluded, we don't want to force require it, in case
43
- # it has side-effects users don't want. For example, `fakefs` gem, if
44
- # loaded, takes over filesystem operations.
45
- return value if AutoRequireHook.excluded?(name)
46
-
47
- # If a gem is marked as `require: false`, then its `autorequire`
48
- # value will be `[]`. But, we want those gems to be loaded for our
49
- # purposes as well, so we return `nil` in those cases, instead, which
50
- # means `require: true`.
51
- return nil if value == []
52
-
53
- value
54
- end
55
-
56
- ::Bundler::Dependency.prepend(self)
57
- end
58
-
59
17
  sig { returns(Bundler::Definition) }
60
18
  attr_reader(:definition)
61
19
 
@@ -65,13 +23,15 @@ module Tapioca
65
23
  sig { returns(T::Array[String]) }
66
24
  attr_reader(:missing_specs)
67
25
 
68
- sig { params(exclude: T::Array[String]).void }
69
- def initialize(exclude)
70
- AutoRequireHook.exclude = exclude
26
+ sig { params(excluded_gems: T::Array[String]).void }
27
+ def initialize(excluded_gems)
71
28
  @gemfile = T.let(File.new(Bundler.default_gemfile), File)
72
29
  @lockfile = T.let(File.new(Bundler.default_lockfile), File)
73
30
  @definition = T.let(Bundler::Dsl.evaluate(gemfile, lockfile, {}), Bundler::Definition)
31
+ @excluded_gems = excluded_gems
32
+
74
33
  dependencies, missing_specs = load_dependencies
34
+
75
35
  @dependencies = T.let(dependencies, T::Array[GemSpec])
76
36
  @missing_specs = T.let(missing_specs, T::Array[String])
77
37
  end
@@ -83,7 +43,9 @@ module Tapioca
83
43
 
84
44
  sig { void }
85
45
  def require_bundle
86
- T.unsafe(runtime).require(*groups)
46
+ BundlerExt::AutoRequireHook.override_require_false(exclude: @excluded_gems) do
47
+ T.unsafe(runtime).require(*groups)
48
+ end
87
49
  end
88
50
 
89
51
  private
@@ -80,7 +80,7 @@ module Tapioca
80
80
  dsl_dir: String,
81
81
  auto_strictness: T::Boolean,
82
82
  gems: T::Array[Gemfile::GemSpec],
83
- compilers: T::Enumerable[Class],
83
+ compilers: T::Enumerable[T.class_of(Dsl::Compiler)],
84
84
  ).void
85
85
  end
86
86
  def validate_rbi_files(command:, gem_dir:, dsl_dir:, auto_strictness:, gems: [], compilers: [])
@@ -25,6 +25,7 @@ module Tapioca
25
25
  {
26
26
  # feature_name: ::Gem::Requirement.new(">= ___"), # https://github.com/sorbet/sorbet/pull/___
27
27
  non_generic_weak_map: ::Gem::Requirement.new(">= 0.5.10587"), # https://github.com/sorbet/sorbet/pull/6610
28
+ generic_class: ::Gem::Requirement.new(">= 0.5.10820"), # https://github.com/sorbet/sorbet/pull/6781
28
29
  }.freeze,
29
30
  T::Hash[Symbol, ::Gem::Requirement],
30
31
  )
@@ -30,6 +30,7 @@ require "tapioca/helpers/gem_helper"
30
30
 
31
31
  require "tapioca/helpers/sorbet_helper"
32
32
  require "tapioca/helpers/rbi_helper"
33
+ require "tapioca/sorbet_ext/backcompat_patches"
33
34
  require "tapioca/sorbet_ext/fixed_hash_patch"
34
35
  require "tapioca/sorbet_ext/name_patch"
35
36
  require "tapioca/sorbet_ext/generic_name_patch"
@@ -9,9 +9,16 @@ module Tapioca
9
9
  class << self
10
10
  extend T::Sig
11
11
 
12
- sig { params(tapioca_path: String, eager_load: T::Boolean, app_root: String).void }
13
- def load_application(tapioca_path:, eager_load: true, app_root: ".")
14
- loader = new(tapioca_path: tapioca_path, eager_load: eager_load, app_root: app_root)
12
+ sig do
13
+ params(tapioca_path: String, eager_load: T::Boolean, app_root: String, halt_upon_load_error: T::Boolean).void
14
+ end
15
+ def load_application(tapioca_path:, eager_load: true, app_root: ".", halt_upon_load_error: true)
16
+ loader = new(
17
+ tapioca_path: tapioca_path,
18
+ eager_load: eager_load,
19
+ app_root: app_root,
20
+ halt_upon_load_error: halt_upon_load_error,
21
+ )
15
22
  loader.load
16
23
  end
17
24
  end
@@ -25,13 +32,16 @@ module Tapioca
25
32
 
26
33
  protected
27
34
 
28
- sig { params(tapioca_path: String, eager_load: T::Boolean, app_root: String).void }
29
- def initialize(tapioca_path:, eager_load: true, app_root: ".")
35
+ sig do
36
+ params(tapioca_path: String, eager_load: T::Boolean, app_root: String, halt_upon_load_error: T::Boolean).void
37
+ end
38
+ def initialize(tapioca_path:, eager_load: true, app_root: ".", halt_upon_load_error: true)
30
39
  super()
31
40
 
32
41
  @tapioca_path = tapioca_path
33
42
  @eager_load = eager_load
34
43
  @app_root = app_root
44
+ @halt_upon_load_error = halt_upon_load_error
35
45
  end
36
46
 
37
47
  sig { void }
@@ -65,6 +75,7 @@ module Tapioca
65
75
  environment_load: true,
66
76
  eager_load: @eager_load,
67
77
  app_root: @app_root,
78
+ halt_upon_load_error: @halt_upon_load_error,
68
79
  )
69
80
 
70
81
  say("Done", :green)
@@ -15,14 +15,16 @@ module Tapioca
15
15
  prerequire: T.nilable(String),
16
16
  postrequire: String,
17
17
  default_command: String,
18
+ halt_upon_load_error: T::Boolean,
18
19
  ).void
19
20
  end
20
- def load_application(bundle:, prerequire:, postrequire:, default_command:)
21
+ def load_application(bundle:, prerequire:, postrequire:, default_command:, halt_upon_load_error:)
21
22
  loader = new(
22
23
  bundle: bundle,
23
24
  prerequire: prerequire,
24
25
  postrequire: postrequire,
25
26
  default_command: default_command,
27
+ halt_upon_load_error: halt_upon_load_error,
26
28
  )
27
29
  loader.load
28
30
  end
@@ -41,22 +43,24 @@ module Tapioca
41
43
  prerequire: T.nilable(String),
42
44
  postrequire: String,
43
45
  default_command: String,
46
+ halt_upon_load_error: T::Boolean,
44
47
  ).void
45
48
  end
46
- def initialize(bundle:, prerequire:, postrequire:, default_command:)
49
+ def initialize(bundle:, prerequire:, postrequire:, default_command:, halt_upon_load_error:)
47
50
  super()
48
51
 
49
52
  @bundle = bundle
50
53
  @prerequire = prerequire
51
54
  @postrequire = postrequire
52
55
  @default_command = default_command
56
+ @halt_upon_load_error = halt_upon_load_error
53
57
  end
54
58
 
55
59
  sig { void }
56
60
  def require_gem_file
57
61
  say("Requiring all gems to prepare for compiling... ")
58
62
  begin
59
- load_bundle(@bundle, @prerequire, @postrequire)
63
+ load_bundle(@bundle, @prerequire, @postrequire, @halt_upon_load_error)
60
64
  rescue LoadError => e
61
65
  explain_failed_require(@postrequire, e)
62
66
  exit(1)
@@ -19,12 +19,17 @@ module Tapioca
19
19
  private
20
20
 
21
21
  sig do
22
- params(gemfile: Tapioca::Gemfile, initialize_file: T.nilable(String), require_file: T.nilable(String)).void
22
+ params(
23
+ gemfile: Tapioca::Gemfile,
24
+ initialize_file: T.nilable(String),
25
+ require_file: T.nilable(String),
26
+ halt_upon_load_error: T::Boolean,
27
+ ).void
23
28
  end
24
- def load_bundle(gemfile, initialize_file, require_file)
29
+ def load_bundle(gemfile, initialize_file, require_file, halt_upon_load_error)
25
30
  require_helper(initialize_file)
26
31
 
27
- load_rails_application
32
+ load_rails_application(halt_upon_load_error: halt_upon_load_error)
28
33
 
29
34
  gemfile.require_bundle
30
35
 
@@ -33,8 +38,15 @@ module Tapioca
33
38
  load_rails_engines
34
39
  end
35
40
 
36
- sig { params(environment_load: T::Boolean, eager_load: T::Boolean, app_root: String).void }
37
- def load_rails_application(environment_load: false, eager_load: false, app_root: ".")
41
+ sig do
42
+ params(
43
+ environment_load: T::Boolean,
44
+ eager_load: T::Boolean,
45
+ app_root: String,
46
+ halt_upon_load_error: T::Boolean,
47
+ ).void
48
+ end
49
+ def load_rails_application(environment_load: false, eager_load: false, app_root: ".", halt_upon_load_error: true)
38
50
  return unless File.exist?("#{app_root}/config/application.rb")
39
51
 
40
52
  silence_deprecations
@@ -50,9 +62,13 @@ module Tapioca
50
62
  say(
51
63
  "\nTapioca attempted to load the Rails application after encountering a `config/application.rb` file, " \
52
64
  "but it failed. If your application uses Rails please ensure it can be loaded correctly before " \
53
- "generating RBIs.\n#{e}",
65
+ "generating RBIs. If your application does not use Rails and you wish to continue RBI generation " \
66
+ "please pass `--no-halt-upon-load-error` to the tapioca command in sorbet/tapioca/config.yml or in CLI." \
67
+ "\n#{e}",
54
68
  :yellow,
55
69
  )
70
+ raise e if halt_upon_load_error
71
+
56
72
  if e.backtrace
57
73
  backtrace = T.must(e.backtrace).join("\n")
58
74
  say(backtrace, :cyan) # TODO: Check verbose flag to print backtrace.
@@ -151,7 +151,7 @@ module Tapioca
151
151
  generic_type
152
152
  end
153
153
 
154
- sig { params(constant: Class).returns(Class) }
154
+ sig { params(constant: T::Class[T.anything]).returns(T::Class[T.anything]) }
155
155
  def create_safe_subclass(constant)
156
156
  # Lookup the "inherited" class method
157
157
  inherited_method = constant.method(:inherited)
@@ -52,7 +52,7 @@ module Tapioca
52
52
  UNDEFINED_CONSTANT
53
53
  end
54
54
 
55
- sig { params(object: BasicObject).returns(Class).checked(:never) }
55
+ sig { params(object: BasicObject).returns(T::Class[T.anything]).checked(:never) }
56
56
  def class_of(object)
57
57
  CLASS_METHOD.bind_call(object)
58
58
  end
@@ -68,7 +68,7 @@ module Tapioca
68
68
  name&.start_with?("#<") ? nil : name
69
69
  end
70
70
 
71
- sig { params(constant: Module).returns(Class) }
71
+ sig { params(constant: Module).returns(T::Class[T.anything]) }
72
72
  def singleton_class_of(constant)
73
73
  SINGLETON_CLASS_METHOD.bind_call(constant)
74
74
  end
@@ -78,7 +78,7 @@ module Tapioca
78
78
  ANCESTORS_METHOD.bind_call(constant)
79
79
  end
80
80
 
81
- sig { params(constant: Class).returns(T.nilable(Class)) }
81
+ sig { params(constant: T::Class[T.anything]).returns(T.nilable(T::Class[T.anything])) }
82
82
  def superclass_of(constant)
83
83
  SUPERCLASS_METHOD.bind_call(constant)
84
84
  end
@@ -113,7 +113,7 @@ module Tapioca
113
113
  if Class === constant
114
114
  ancestors_of(superclass_of(constant) || Object)
115
115
  else
116
- Module.ancestors
116
+ Module.new.ancestors
117
117
  end
118
118
  end
119
119
 
@@ -161,7 +161,7 @@ module Tapioca
161
161
  # descendants_of(C) # => [B, A, D]
162
162
  sig do
163
163
  type_parameters(:U)
164
- .params(klass: T.all(Class, T.type_parameter(:U)))
164
+ .params(klass: T.all(T::Class[T.anything], T.type_parameter(:U)))
165
165
  .returns(T::Array[T.type_parameter(:U)])
166
166
  end
167
167
  def descendants_of(klass)
@@ -192,6 +192,22 @@ module Tapioca
192
192
  end.to_set
193
193
  end
194
194
 
195
+ sig { params(constant: Module).returns(T.untyped) }
196
+ def abstract_type_of(constant)
197
+ T::Private::Abstract::Data.get(constant, :abstract_type) ||
198
+ T::Private::Abstract::Data.get(singleton_class_of(constant), :abstract_type)
199
+ end
200
+
201
+ sig { params(constant: Module).returns(T::Boolean) }
202
+ def final_module?(constant)
203
+ T::Private::Final.final_module?(constant)
204
+ end
205
+
206
+ sig { params(constant: Module).returns(T::Boolean) }
207
+ def sealed_module?(constant)
208
+ T::Private::Sealed.sealed_module?(constant)
209
+ end
210
+
195
211
  private
196
212
 
197
213
  sig { params(constant: Module).returns(T::Array[UnboundMethod]) }
@@ -0,0 +1,24 @@
1
+ # typed: true
2
+ # frozen_string_literal: true
3
+
4
+ unless defined?(T.anything)
5
+ module T
6
+ class << self
7
+ def anything
8
+ T.untyped
9
+ end
10
+ end
11
+ end
12
+ end
13
+
14
+ unless defined?(T::Class)
15
+ module T
16
+ module Class
17
+ class << self
18
+ def [](type)
19
+ T.untyped
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
@@ -49,6 +49,21 @@ module T
49
49
  Tapioca::Runtime::GenericTypeRegistry.register_type_variable(self, type_variable)
50
50
  end
51
51
  end
52
+
53
+ def has_attached_class!(variance = :invariant, &bounds_proc)
54
+ Tapioca::Runtime::GenericTypeRegistry.register_type_variable(
55
+ self,
56
+ Tapioca::TypeVariableModule.new(
57
+ T.cast(self, Module),
58
+ Tapioca::TypeVariableModule::Type::HasAttachedClass,
59
+ variance,
60
+ nil,
61
+ nil,
62
+ nil,
63
+ bounds_proc,
64
+ ),
65
+ )
66
+ end
52
67
  end
53
68
 
54
69
  prepend TypeStoragePatch
@@ -140,9 +155,13 @@ module Tapioca
140
155
  enums do
141
156
  Member = new("type_member")
142
157
  Template = new("type_template")
158
+ HasAttachedClass = new("has_attached_class!")
143
159
  end
144
160
  end
145
161
 
162
+ sig { returns(Type) }
163
+ attr_reader :type
164
+
146
165
  # rubocop:disable Metrics/ParameterLists
147
166
  sig do
148
167
  params(
@@ -2,5 +2,5 @@
2
2
  # frozen_string_literal: true
3
3
 
4
4
  module Tapioca
5
- VERSION = "0.11.6"
5
+ VERSION = "0.11.7"
6
6
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tapioca
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.11.6
4
+ version: 0.11.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ufuk Kayserilioglu
@@ -11,7 +11,7 @@ authors:
11
11
  autorequire:
12
12
  bindir: exe
13
13
  cert_chain: []
14
- date: 2023-05-12 00:00:00.000000000 Z
14
+ date: 2023-06-23 00:00:00.000000000 Z
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
17
17
  name: bundler
@@ -149,6 +149,7 @@ files:
149
149
  - README.md
150
150
  - exe/tapioca
151
151
  - lib/tapioca.rb
152
+ - lib/tapioca/bundler_ext/auto_require_hook.rb
152
153
  - lib/tapioca/cli.rb
153
154
  - lib/tapioca/commands.rb
154
155
  - lib/tapioca/commands/annotations.rb
@@ -253,6 +254,7 @@ files:
253
254
  - lib/tapioca/runtime/trackers/mixin.rb
254
255
  - lib/tapioca/runtime/trackers/required_ancestor.rb
255
256
  - lib/tapioca/runtime/trackers/tracker.rb
257
+ - lib/tapioca/sorbet_ext/backcompat_patches.rb
256
258
  - lib/tapioca/sorbet_ext/fixed_hash_patch.rb
257
259
  - lib/tapioca/sorbet_ext/generic_name_patch.rb
258
260
  - lib/tapioca/sorbet_ext/name_patch.rb
@@ -281,7 +283,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
281
283
  - !ruby/object:Gem::Version
282
284
  version: '0'
283
285
  requirements: []
284
- rubygems_version: 3.4.12
286
+ rubygems_version: 3.4.14
285
287
  signing_key:
286
288
  specification_version: 4
287
289
  summary: A Ruby Interface file generator for gems, core types and the Ruby standard