tapioca 0.19.1 → 0.20.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +84 -0
  3. data/lib/ruby_lsp/tapioca/run_gem_rbi_check.rb +1 -1
  4. data/lib/tapioca/cli.rb +9 -0
  5. data/lib/tapioca/commands/abstract_dsl.rb +76 -20
  6. data/lib/tapioca/commands/abstract_gem.rb +1 -0
  7. data/lib/tapioca/commands/annotations.rb +1 -1
  8. data/lib/tapioca/commands/gem_generate.rb +20 -4
  9. data/lib/tapioca/dsl/compiler.rb +24 -10
  10. data/lib/tapioca/dsl/compilers/aasm.rb +24 -17
  11. data/lib/tapioca/dsl/compilers/active_job.rb +1 -1
  12. data/lib/tapioca/dsl/compilers/active_model_attributes.rb +1 -1
  13. data/lib/tapioca/dsl/compilers/active_record_delegated_types.rb +64 -16
  14. data/lib/tapioca/dsl/compilers/active_record_fixtures.rb +17 -11
  15. data/lib/tapioca/dsl/compilers/active_record_relations.rb +2 -2
  16. data/lib/tapioca/dsl/compilers/config.rb +1 -1
  17. data/lib/tapioca/dsl/compilers/json_api_client_resource.rb +1 -1
  18. data/lib/tapioca/dsl/compilers/sidekiq_worker.rb +1 -1
  19. data/lib/tapioca/dsl/compilers/url_helpers.rb +312 -8
  20. data/lib/tapioca/dsl/compilers.rb +1 -1
  21. data/lib/tapioca/dsl/helpers/graphql_type_helper.rb +10 -3
  22. data/lib/tapioca/dsl/pipeline.rb +6 -27
  23. data/lib/tapioca/gem/events.rb +1 -1
  24. data/lib/tapioca/gem/listeners/documentation.rb +13 -8
  25. data/lib/tapioca/gem/listeners/methods.rb +79 -13
  26. data/lib/tapioca/gem/listeners/sorbet_enums.rb +1 -1
  27. data/lib/tapioca/gem/pipeline.rb +3 -3
  28. data/lib/tapioca/gemfile.rb +13 -0
  29. data/lib/tapioca/helpers/env_helper.rb +1 -1
  30. data/lib/tapioca/helpers/file_helper.rb +42 -0
  31. data/lib/tapioca/helpers/rbi_files_helper.rb +96 -5
  32. data/lib/tapioca/helpers/rbi_helper.rb +17 -3
  33. data/lib/tapioca/helpers/sorbet_helper.rb +1 -1
  34. data/lib/tapioca/internal.rb +2 -0
  35. data/lib/tapioca/loaders/gem.rb +33 -0
  36. data/lib/tapioca/loaders/loader.rb +0 -13
  37. data/lib/tapioca/rbi_ext/model.rb +16 -2
  38. data/lib/tapioca/rbs/bootsnap_cache.rb +52 -0
  39. data/lib/tapioca/rbs/rewriter.rb +91 -25
  40. data/lib/tapioca/runtime/dynamic_mixin_compiler.rb +1 -2
  41. data/lib/tapioca/runtime/generic_type_registry.rb +38 -14
  42. data/lib/tapioca/runtime/reflection.rb +18 -1
  43. data/lib/tapioca/sorbet_ext/generic_name_patch.rb +0 -20
  44. data/lib/tapioca/sorbet_ext/generic_type_patch.rb +48 -0
  45. data/lib/tapioca/version.rb +1 -1
  46. data/lib/tapioca.rb +11 -10
  47. metadata +9 -6
@@ -76,11 +76,10 @@ module RBI
76
76
  if !block || !parameters.empty? || return_type
77
77
  # If there is no block, and the params and return type have not been supplied, then
78
78
  # we create a single signature with the given parameters and return type
79
- params = parameters.map { |param| RBI::SigParam.new(param.param.name.to_s, param.type) }
80
79
  return_type ||= "T.untyped"
81
80
  type_params = Tapioca::RBIHelper.extract_type_parameters(parameters.map(&:type).append(return_type))
82
81
 
83
- sig = RBI::Sig.new(params: params, return_type: return_type, type_params: type_params)
82
+ sig = RBI::Sig.new(params: parameters.map(&:to_sig_param), return_type: return_type, type_params: type_params)
84
83
  sigs << sig
85
84
  end
86
85
 
@@ -117,5 +116,20 @@ module RBI
117
116
  class TypedParam < T::Struct
118
117
  const :param, RBI::Param
119
118
  const :type, String
119
+
120
+ #: -> RBI::SigParam
121
+ def to_sig_param
122
+ name = case param
123
+ when RestParam
124
+ param.anonymous? ? "*".inspect : param.name.to_s
125
+ when KwRestParam
126
+ param.anonymous? ? "**".inspect : param.name.to_s
127
+ when BlockParam
128
+ param.anonymous? ? "&".inspect : param.name.to_s
129
+ else
130
+ param.name.to_s
131
+ end
132
+ RBI::SigParam.new(name, type)
133
+ end
120
134
  end
121
135
  end
@@ -0,0 +1,52 @@
1
+ # typed: strict
2
+ # frozen_string_literal: true
3
+
4
+ require "bundler"
5
+ require "digest"
6
+ require "fileutils"
7
+
8
+ module Tapioca
9
+ module RBS
10
+ # Prepares the Bootsnap iseq cache used for RBS rewrite output.
11
+ #
12
+ # RBS rewrite output can change when the lockfile changes, even if the
13
+ # source files are unchanged.
14
+ # To account for this, we store the current Gemfile.lock SHA256 in a
15
+ # `.gemfile-lock-digest` file.
16
+ # A digest mismatch deletes Bootsnap's cache payload and records the new
17
+ # digest, so this run rebuilds the cache from scratch.
18
+ module BootsnapCache
19
+ DIGEST_FILE = ".gemfile-lock-digest" #: String
20
+
21
+ class << self
22
+ #: (String) -> void
23
+ def prepare_for_setup(cache_dir)
24
+ digest = gemfile_lock_digest
25
+ return if digest_matches?(cache_dir, digest)
26
+
27
+ FileUtils.rm_rf(File.join(cache_dir, "bootsnap"))
28
+ FileUtils.mkdir_p(cache_dir)
29
+ File.write(digest_path(cache_dir), digest)
30
+ end
31
+
32
+ private
33
+
34
+ #: -> String
35
+ def gemfile_lock_digest
36
+ Digest::SHA256.file(Bundler.default_lockfile).hexdigest
37
+ end
38
+
39
+ #: (String, String) -> bool
40
+ def digest_matches?(cache_dir, digest)
41
+ path = digest_path(cache_dir)
42
+ File.file?(path) && File.read(path).chomp == digest
43
+ end
44
+
45
+ #: (String) -> String
46
+ def digest_path(cache_dir)
47
+ File.join(cache_dir, DIGEST_FILE)
48
+ end
49
+ end
50
+ end
51
+ end
52
+ end
@@ -1,39 +1,104 @@
1
1
  # typed: strict
2
2
  # frozen_string_literal: true
3
3
 
4
- require "require-hooks/setup"
5
-
6
4
  # This code rewrites RBS comments back into Sorbet's signatures as the files are being loaded.
7
5
  # This will allow `sorbet-runtime` to wrap the methods as if they were originally written with the `sig{}` blocks.
8
6
  # This will in turn allow Tapioca to use this signatures to generate typed RBI files.
9
7
 
10
- begin
11
- # When in a `bootsnap` environment, files are loaded from the cache and won't trigger the `source_transform` method.
12
- # The `require-hooks` gem comes with a `bootsnap` mode that will disable the `bootsnap/compile_cache/iseq` caching.
13
- # Sadly, we're way to early in the boot process to use it as bootsnap won't be loaded yet and the `require-hooks`
14
- # setup won't pick it up.
15
- #
16
- # As a workaround, if we can preemptively require `bootsnap` and `bootsnap/compile_cache/iseq` we manually override
17
- # the `load_iseq` method to disable the caching mechanism.
18
- #
19
- # This will make the Rails app load slower but allows us to trigger the RBS -> RBI source transform.
20
- require "bootsnap"
21
- require "bootsnap/compile_cache/iseq"
22
-
23
- module Bootsnap
24
- module CompileCache
25
- module ISeq
26
- module InstructionSequenceMixin
27
- #: (String) -> RubyVM::InstructionSequence
28
- def load_iseq(path)
29
- super if defined?(super)
8
+ module Tapioca
9
+ module RBS
10
+ class HostBootsnapSetupError < StandardError; end
11
+
12
+ # Raises when the host calls `Bootsnap.setup` after tapioca's setup. Host's call
13
+ # would overwrite tapioca's cache directory, so rewritten iseqs would end up in
14
+ # the host's regular cache.
15
+ module BootsnapGuard
16
+ extend T::Sig
17
+
18
+ sig { params(_kwargs: T.untyped).void }
19
+ def setup(**_kwargs)
20
+ Kernel.raise HostBootsnapSetupError, <<~MSG
21
+ Bootsnap.setup was called while TAPIOCA_RBS_CACHE=1 is set. Tapioca already
22
+ configured bootsnap with a dedicated cache directory; re-running setup
23
+ would overwrite that config and start writing rewritten iseqs into your
24
+ host's cache.
25
+
26
+ Gate your host's Bootsnap.setup on the env var, e.g. in config/boot.rb:
27
+
28
+ require "bootsnap/setup" unless ENV["TAPIOCA_RBS_CACHE"] == "1"
29
+ MSG
30
+ end
31
+ end
32
+
33
+ module BootsnapIntegration
34
+ class << self
35
+ extend T::Sig
36
+
37
+ sig { void }
38
+ def setup
39
+ require "bootsnap"
40
+ require "tapioca/rbs/bootsnap_cache"
41
+
42
+ cache_dir = ENV.fetch("TAPIOCA_BOOTSNAP_CACHE_DIR", File.join(Dir.pwd, "tmp/cache/bootsnap-tapioca-rbs"))
43
+ Tapioca::RBS::BootsnapCache.prepare_for_setup(cache_dir)
44
+
45
+ Bootsnap.setup(
46
+ cache_dir: cache_dir,
47
+ development_mode: true,
48
+ load_path_cache: true,
49
+ compile_cache_iseq: true,
50
+ compile_cache_yaml: true,
51
+ readonly: false,
52
+ revalidation: true,
53
+ )
54
+ Bootsnap.log_stats!
55
+
56
+ Bootsnap.singleton_class.prepend(Tapioca::RBS::BootsnapGuard)
57
+ end
58
+ end
59
+ end
60
+ end
61
+ end
62
+
63
+ # When TAPIOCA_RBS_CACHE=1, use a dedicated Bootsnap cache directory for
64
+ # RBS-rewritten iseqs. After setup, BootsnapGuard is prepended so the host
65
+ # application cannot replace Tapioca's cache directory.
66
+ if ENV["TAPIOCA_RBS_CACHE"] == "1"
67
+ begin
68
+ Tapioca::RBS::BootsnapIntegration.setup
69
+ rescue LoadError
70
+ # Bootsnap is not in the bundle, skip iseq caching.
71
+ end
72
+
73
+ require "require-hooks/setup"
74
+ else
75
+ require "require-hooks/setup"
76
+
77
+ begin
78
+ # Disable Bootsnap's iseq cache unless TAPIOCA_RBS_CACHE=1 enabled the separate cache above.
79
+ #
80
+ # This is necessary because host apps can call Bootsnap.setup after tapioca loads this file. When that happens,
81
+ # Bootsnap installs `load_iseq` and serves files from its cache, which bypasses RequireHooks.source_transform.
82
+ # Preloading bootsnap's iseq support lets us override `load_iseq` before setup installs it, preserving the default
83
+ # RBS rewrite behavior at the cost of slower app boot.
84
+ require "bootsnap"
85
+ require "bootsnap/compile_cache/iseq"
86
+
87
+ module Bootsnap
88
+ module CompileCache
89
+ module ISeq
90
+ module InstructionSequenceMixin
91
+ #: (String) -> RubyVM::InstructionSequence
92
+ def load_iseq(path)
93
+ super if defined?(super) # Disable Bootsnap's hook, but trigger any others.
94
+ end
30
95
  end
31
96
  end
32
97
  end
33
98
  end
99
+ rescue LoadError
100
+ # Bootsnap is not in the bundle, we don't need to do anything.
34
101
  end
35
- rescue LoadError
36
- # Bootsnap is not in the bundle, we don't need to do anything.
37
102
  end
38
103
 
39
104
  # We need to include `T::Sig` very early to make sure that the `sig` method is available since gems using RBS comments
@@ -47,7 +112,8 @@ RequireHooks.source_transform(patterns: ["**/*.rb"]) do |path, source|
47
112
 
48
113
  # For performance reasons, we only rewrite files that use Sorbet.
49
114
  if source =~ /^\s*#\s*typed: (ignore|false|true|strict|strong|__STDLIB_INTERNAL)/
50
- Spoom::Sorbet::Translate.rbs_comments_to_sorbet_sigs(source, file: path)
115
+ # Sorbet runtime only supports one signature per method, so keep the last overload.
116
+ Spoom::Sorbet::Translate.rbs_comments_to_sorbet_sigs(source, file: path, overloads_strategy: :translate_last)
51
117
  end
52
118
  rescue Spoom::Sorbet::Translate::Error
53
119
  # If we can't translate the RBS comments back into Sorbet's signatures, we just skip the file.
@@ -53,7 +53,7 @@ module Tapioca
53
53
  mixins_from_modules[mod] = (after - before).reverse!
54
54
  end
55
55
  end
56
- rescue Exception # rubocop:disable Lint/RescueException
56
+ rescue Exception
57
57
  # this is a best effort, bail if we can't perform this
58
58
  end
59
59
 
@@ -85,7 +85,6 @@ module Tapioca
85
85
  super(*attrs, **kwargs) if defined?(super)
86
86
  end
87
87
 
88
- # rubocop:disable Style/MissingRespondToMissing
89
88
  T::Sig::WithoutRuntime.sig { params(symbol: Symbol, args: T.untyped).returns(T.untyped) }
90
89
  def method_missing(symbol, *args)
91
90
  # We need this here so that we can handle any random instance
@@ -6,7 +6,7 @@ module Tapioca
6
6
  # This class is responsible for storing and looking up information related to generic types.
7
7
  #
8
8
  # The class stores 2 different kinds of data, in two separate lookup tables:
9
- # 1. a lookup of generic type instances by name: `@generic_instances`
9
+ # 1. a lookup of generic type instances by constant and name: `@generic_instances`
10
10
  # 2. a lookup of type variable serializer by constant and type variable
11
11
  # instance: `@type_variables`
12
12
  #
@@ -21,15 +21,22 @@ module Tapioca
21
21
  # variable to type variable serializers. This allows us to associate type variables
22
22
  # to the constant names that represent them, easily.
23
23
  module GenericTypeRegistry
24
- @generic_instances = {} #: Hash[String, Module[top]]
24
+ @generic_instances = {}.compare_by_identity #: Hash[Module[top], Hash[String, Module[top]]]
25
25
 
26
26
  @type_variables = {}.compare_by_identity #: Hash[Module[top], Array[TypeVariableModule]]
27
27
 
28
- class GenericType < T::Types::Simple
28
+ # Subclasses `T::Types::Base` rather than `T::Types::Simple` so that all
29
+ # validation goes through the `valid?` override below. `Simple` fast paths
30
+ # check `raw_type` directly, which for us is the clone, not the underlying type.
31
+ class GenericType < T::Types::Base
32
+ #: Module[top]
33
+ attr_reader :raw_type
34
+
29
35
  #: (Module[top] raw_type, Module[top] underlying_type) -> void
30
36
  def initialize(raw_type, underlying_type)
31
- super(raw_type)
37
+ super()
32
38
 
39
+ @raw_type = raw_type
33
40
  @underlying_type = underlying_type #: Module[top]
34
41
  end
35
42
 
@@ -38,6 +45,24 @@ module Tapioca
38
45
  def valid?(obj)
39
46
  obj.is_a?(@underlying_type)
40
47
  end
48
+
49
+ # @override
50
+ #: -> String
51
+ def name
52
+ T.must(@raw_type.name)
53
+ end
54
+
55
+ # @override
56
+ #: -> nil
57
+ def build_type
58
+ nil
59
+ end
60
+
61
+ # Matches the always-true `<=` we define on the clone in `create_generic_type`.
62
+ #: (T::Types::Base type) -> bool
63
+ private def subtype_of_single?(type)
64
+ true
65
+ end
41
66
  end
42
67
 
43
68
  class << self
@@ -45,8 +70,9 @@ module Tapioca
45
70
  # and cloning the given constant so that we can return a type that is the same
46
71
  # as the current type but is a different instance and has a different name method.
47
72
  #
48
- # We cache those cloned instances by their name in `@generic_instances`, so that
49
- # we don't keep instantiating a new type every single time it is referenced.
73
+ # We cache those cloned instances by their original constant and their name in
74
+ # `@generic_instances`, so that we don't keep instantiating a new type every single
75
+ # time it is referenced.
50
76
  # For example, `[Foo[Integer], Foo[Integer], Foo[Integer], Foo[String]]` will only
51
77
  # result in 2 clones (1 for `Foo[Integer]` and another for `Foo[String]`) and
52
78
  # 2 hash lookups (for the other two `Foo[Integer]`s).
@@ -64,12 +90,15 @@ module Tapioca
64
90
  #
65
91
  # Also, we try to memoize the generic type based on the name, so that
66
92
  # we don't have to keep recreating them all the time.
67
- @generic_instances[name] ||= create_generic_type(constant, name)
93
+ generic_instances = @generic_instances[constant] ||= {}
94
+ generic_instances[name] ||= create_generic_type(constant, name)
68
95
  end
69
96
 
70
97
  #: (Object instance) -> bool
71
98
  def generic_type_instance?(instance)
72
- @generic_instances.values.any? { |generic_type| generic_type === instance }
99
+ @generic_instances.values.any? do |generic_instances|
100
+ generic_instances.values.any? { |generic_type| generic_type === instance }
101
+ end
73
102
  end
74
103
 
75
104
  #: (Module[top] constant) -> Array[TypeVariableModule]?
@@ -88,7 +117,7 @@ module Tapioca
88
117
  # can return it from the original methods as well.
89
118
  #: (untyped constant, TypeVariableModule type_variable) -> void
90
119
  def register_type_variable(constant, type_variable)
91
- type_variables = lookup_or_initialize_type_variables(constant)
120
+ type_variables = @type_variables[constant] ||= []
92
121
 
93
122
  type_variables << type_variable
94
123
  end
@@ -163,11 +192,6 @@ module Tapioca
163
192
  owner.send(:define_method, :inherited, inherited_method)
164
193
  end
165
194
  end
166
-
167
- #: (Module[top] constant) -> Array[TypeVariableModule]
168
- def lookup_or_initialize_type_variables(constant)
169
- @type_variables[constant] ||= []
170
- end
171
195
  end
172
196
  end
173
197
  end
@@ -125,7 +125,24 @@ module Tapioca
125
125
 
126
126
  #: ((UnboundMethod | Method) method) -> untyped
127
127
  def signature_of!(method)
128
- T::Utils.signature_for_method(method)
128
+ signature = T::Utils.signature_for_method(method)
129
+ return signature if signature
130
+
131
+ # Walk the super method chain to evaluate pending signatures that may have been hidden by `prepend`.
132
+ # During that walk, Sorbet may register a signature on the requested wrapper, so check it again.
133
+ # See https://github.com/Shopify/tapioca/issues/2710 for details.
134
+ current_method = method.super_method #: (UnboundMethod | Method)?
135
+ while current_method
136
+ # force evaluation of the signature
137
+ _ = T::Utils.signature_for_method(current_method)
138
+
139
+ evaluated_signature = T::Utils.signature_for_method(method)
140
+ return evaluated_signature if evaluated_signature
141
+
142
+ current_method = current_method.super_method
143
+ end
144
+
145
+ nil
129
146
  rescue LoadError, StandardError
130
147
  Kernel.raise SignatureBlockError
131
148
  end
@@ -82,26 +82,6 @@ module T
82
82
  prepend GenericPatch
83
83
  end
84
84
  end
85
-
86
- module Utils
87
- module Private
88
- module PrivateCoercePatch
89
- def coerce_and_check_module_types(val, check_val, check_module_type)
90
- if val.is_a?(Tapioca::TypeVariableModule)
91
- val.coerce_to_type_variable
92
- elsif val.respond_to?(:__tapioca_override_type)
93
- val.__tapioca_override_type
94
- else
95
- super
96
- end
97
- end
98
- end
99
-
100
- class << self
101
- prepend(PrivateCoercePatch)
102
- end
103
- end
104
- end
105
85
  end
106
86
 
107
87
  module Tapioca
@@ -0,0 +1,48 @@
1
+ # typed: true
2
+ # frozen_string_literal: true
3
+
4
+ module T
5
+ module Utils
6
+ module Private
7
+ # Preserve Tapioca's generic type variables and instantiated generic
8
+ # names when Sorbet coerces them into runtime types.
9
+ module TapiocaGenericTypeCoercePatch
10
+ def coerce_and_check_module_types(val, check_val, check_module_type)
11
+ if val.is_a?(Tapioca::TypeVariableModule)
12
+ val.coerce_to_type_variable
13
+ elsif val.respond_to?(:__tapioca_override_type)
14
+ val.__tapioca_override_type
15
+ else
16
+ super
17
+ end
18
+ end
19
+ end
20
+
21
+ class << self
22
+ prepend(TapiocaGenericTypeCoercePatch)
23
+ end
24
+ end
25
+ end
26
+
27
+ module Private
28
+ module Casts
29
+ module TapiocaGenericTypeCastPatch
30
+ # https://github.com/sorbet/sorbet/commit/b8d64c7fd9a08e2b9159b5d592bc2de6d586b44a
31
+ # inlines the Module fast path in `T.let`, `T.cast`, `T.bind`, and
32
+ # `T.assert_type!`, so generic module clones can reach this cast path
33
+ # without going through `T::Utils::Private::TapiocaGenericTypeCoercePatch`.
34
+ def cast(value, type, cast_method)
35
+ if type.respond_to?(:__tapioca_override_type)
36
+ type = type.__tapioca_override_type
37
+ end
38
+
39
+ super(value, type, cast_method)
40
+ end
41
+ end
42
+
43
+ class << self
44
+ prepend(TapiocaGenericTypeCastPatch)
45
+ end
46
+ end
47
+ end
48
+ end
@@ -2,5 +2,5 @@
2
2
  # frozen_string_literal: true
3
3
 
4
4
  module Tapioca
5
- VERSION = "0.19.1"
5
+ VERSION = "0.20.0"
6
6
  end
data/lib/tapioca.rb CHANGED
@@ -11,18 +11,18 @@ module Tapioca
11
11
 
12
12
  LIB_ROOT_DIR = T.must(__dir__) #: String
13
13
  SORBET_DIR = "sorbet" #: String
14
- SORBET_CONFIG_FILE = "#{SORBET_DIR}/config" #: String
15
- TAPIOCA_DIR = "#{SORBET_DIR}/tapioca" #: String
16
- TAPIOCA_CONFIG_FILE = "#{TAPIOCA_DIR}/config.yml" #: String
14
+ SORBET_CONFIG_FILE = "#{SORBET_DIR}/config".freeze #: String
15
+ TAPIOCA_DIR = "#{SORBET_DIR}/tapioca".freeze #: String
16
+ TAPIOCA_CONFIG_FILE = "#{TAPIOCA_DIR}/config.yml".freeze #: String
17
17
 
18
18
  BINARY_FILE = "bin/tapioca" #: String
19
- DEFAULT_POSTREQUIRE_FILE = "#{TAPIOCA_DIR}/require.rb" #: String
20
- DEFAULT_RBI_DIR = "#{SORBET_DIR}/rbi" #: String
21
- DEFAULT_DSL_DIR = "#{DEFAULT_RBI_DIR}/dsl" #: String
22
- DEFAULT_GEM_DIR = "#{DEFAULT_RBI_DIR}/gems" #: String
23
- DEFAULT_SHIM_DIR = "#{DEFAULT_RBI_DIR}/shims" #: String
24
- DEFAULT_TODO_FILE = "#{DEFAULT_RBI_DIR}/todo.rbi" #: String
25
- DEFAULT_ANNOTATIONS_DIR = "#{DEFAULT_RBI_DIR}/annotations" #: String
19
+ DEFAULT_POSTREQUIRE_FILE = "#{TAPIOCA_DIR}/require.rb".freeze #: String
20
+ DEFAULT_RBI_DIR = "#{SORBET_DIR}/rbi".freeze #: String
21
+ DEFAULT_DSL_DIR = "#{DEFAULT_RBI_DIR}/dsl".freeze #: String
22
+ DEFAULT_GEM_DIR = "#{DEFAULT_RBI_DIR}/gems".freeze #: String
23
+ DEFAULT_SHIM_DIR = "#{DEFAULT_RBI_DIR}/shims".freeze #: String
24
+ DEFAULT_TODO_FILE = "#{DEFAULT_RBI_DIR}/todo.rbi".freeze #: String
25
+ DEFAULT_ANNOTATIONS_DIR = "#{DEFAULT_RBI_DIR}/annotations".freeze #: String
26
26
 
27
27
  DEFAULT_OVERRIDES = {
28
28
  # ActiveSupport overrides some core methods with different signatures
@@ -32,6 +32,7 @@ module Tapioca
32
32
 
33
33
  DEFAULT_RBI_MAX_LINE_LENGTH = 120
34
34
  DEFAULT_ENVIRONMENT = "development"
35
+ DEFAULT_MAX_DIFF_LINES = 250
35
36
 
36
37
  CENTRAL_REPO_ROOT_URI = "https://raw.githubusercontent.com/Shopify/rbi-central/main"
37
38
  CENTRAL_REPO_INDEX_PATH = "index.json"
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.19.1
4
+ version: 0.20.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ufuk Kayserilioglu
@@ -130,28 +130,28 @@ dependencies:
130
130
  requirements:
131
131
  - - ">="
132
132
  - !ruby/object:Gem::Version
133
- version: 0.3.7
133
+ version: 0.4.1
134
134
  type: :runtime
135
135
  prerelease: false
136
136
  version_requirements: !ruby/object:Gem::Requirement
137
137
  requirements:
138
138
  - - ">="
139
139
  - !ruby/object:Gem::Version
140
- version: 0.3.7
140
+ version: 0.4.1
141
141
  - !ruby/object:Gem::Dependency
142
142
  name: spoom
143
143
  requirement: !ruby/object:Gem::Requirement
144
144
  requirements:
145
145
  - - ">="
146
146
  - !ruby/object:Gem::Version
147
- version: 1.7.9
147
+ version: 1.7.16
148
148
  type: :runtime
149
149
  prerelease: false
150
150
  version_requirements: !ruby/object:Gem::Requirement
151
151
  requirements:
152
152
  - - ">="
153
153
  - !ruby/object:Gem::Version
154
- version: 1.7.9
154
+ version: 1.7.16
155
155
  - !ruby/object:Gem::Dependency
156
156
  name: tsort
157
157
  requirement: !ruby/object:Gem::Requirement
@@ -273,6 +273,7 @@ files:
273
273
  - lib/tapioca/helpers/cli_helper.rb
274
274
  - lib/tapioca/helpers/config_helper.rb
275
275
  - lib/tapioca/helpers/env_helper.rb
276
+ - lib/tapioca/helpers/file_helper.rb
276
277
  - lib/tapioca/helpers/gem_helper.rb
277
278
  - lib/tapioca/helpers/git_attributes.rb
278
279
  - lib/tapioca/helpers/package_url.rb
@@ -289,6 +290,7 @@ files:
289
290
  - lib/tapioca/loaders/loader.rb
290
291
  - lib/tapioca/rbi_ext/model.rb
291
292
  - lib/tapioca/rbi_formatter.rb
293
+ - lib/tapioca/rbs/bootsnap_cache.rb
292
294
  - lib/tapioca/rbs/rewriter.rb
293
295
  - lib/tapioca/repo_index.rb
294
296
  - lib/tapioca/runtime/dynamic_mixin_compiler.rb
@@ -305,6 +307,7 @@ files:
305
307
  - lib/tapioca/runtime/trackers/tracker.rb
306
308
  - lib/tapioca/sorbet_ext/backcompat_patches.rb
307
309
  - lib/tapioca/sorbet_ext/generic_name_patch.rb
310
+ - lib/tapioca/sorbet_ext/generic_type_patch.rb
308
311
  - lib/tapioca/sorbet_ext/name_patch.rb
309
312
  - lib/tapioca/sorbet_ext/proc_bind_patch.rb
310
313
  - lib/tapioca/sorbet_ext/void_patch.rb
@@ -324,7 +327,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
324
327
  requirements:
325
328
  - - ">="
326
329
  - !ruby/object:Gem::Version
327
- version: '3.2'
330
+ version: '3.3'
328
331
  required_rubygems_version: !ruby/object:Gem::Requirement
329
332
  requirements:
330
333
  - - ">="