tapioca 0.10.1 → 0.10.3
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 +4 -4
- data/README.md +9 -3
- data/lib/tapioca/cli.rb +24 -12
- data/lib/tapioca/commands/annotations.rb +2 -2
- data/lib/tapioca/commands/check_shims.rb +13 -21
- data/lib/tapioca/commands/command.rb +2 -2
- data/lib/tapioca/commands/command_without_tracker.rb +18 -0
- data/lib/tapioca/commands/configure.rb +3 -3
- data/lib/tapioca/commands/dsl.rb +16 -11
- data/lib/tapioca/commands/gem.rb +5 -5
- data/lib/tapioca/commands/require.rb +2 -2
- data/lib/tapioca/commands/todo.rb +2 -2
- data/lib/tapioca/commands.rb +1 -0
- data/lib/tapioca/dsl/compiler.rb +3 -3
- data/lib/tapioca/dsl/compilers/aasm.rb +4 -4
- data/lib/tapioca/dsl/compilers/action_controller_helpers.rb +1 -1
- data/lib/tapioca/dsl/compilers/action_mailer.rb +1 -1
- data/lib/tapioca/dsl/compilers/active_job.rb +2 -2
- data/lib/tapioca/dsl/compilers/active_model_attributes.rb +1 -1
- data/lib/tapioca/dsl/compilers/active_record_associations.rb +48 -13
- data/lib/tapioca/dsl/compilers/active_record_columns.rb +22 -22
- data/lib/tapioca/dsl/compilers/active_record_fixtures.rb +1 -1
- data/lib/tapioca/dsl/compilers/active_record_relations.rb +52 -48
- data/lib/tapioca/dsl/compilers/active_record_scope.rb +3 -3
- data/lib/tapioca/dsl/compilers/active_record_typed_store.rb +2 -2
- data/lib/tapioca/dsl/compilers/active_storage.rb +2 -2
- data/lib/tapioca/dsl/compilers/active_support_current_attributes.rb +1 -1
- data/lib/tapioca/dsl/compilers/config.rb +2 -2
- data/lib/tapioca/dsl/compilers/graphql_input_object.rb +1 -0
- data/lib/tapioca/dsl/compilers/graphql_mutation.rb +1 -0
- data/lib/tapioca/dsl/compilers/identity_cache.rb +12 -12
- data/lib/tapioca/dsl/compilers/protobuf.rb +21 -10
- data/lib/tapioca/dsl/compilers/rails_generators.rb +2 -2
- data/lib/tapioca/dsl/compilers/sidekiq_worker.rb +1 -1
- data/lib/tapioca/dsl/compilers/smart_properties.rb +2 -2
- data/lib/tapioca/dsl/compilers/state_machines.rb +24 -24
- data/lib/tapioca/dsl/compilers/url_helpers.rb +1 -1
- data/lib/tapioca/dsl/compilers.rb +1 -1
- data/lib/tapioca/dsl/helpers/active_record_column_type_helper.rb +19 -0
- data/lib/tapioca/dsl/helpers/graphql_type_helper.rb +1 -1
- data/lib/tapioca/dsl/pipeline.rb +5 -4
- data/lib/tapioca/executor.rb +2 -2
- data/lib/tapioca/gem/events.rb +1 -1
- data/lib/tapioca/gem/listeners/foreign_constants.rb +3 -2
- data/lib/tapioca/gem/listeners/methods.rb +3 -3
- data/lib/tapioca/gem/listeners/mixins.rb +3 -7
- data/lib/tapioca/gem/listeners/source_location.rb +1 -1
- data/lib/tapioca/gem/listeners/subconstants.rb +1 -1
- data/lib/tapioca/gem/listeners/yard_doc.rb +1 -1
- data/lib/tapioca/gem/pipeline.rb +11 -9
- data/lib/tapioca/gemfile.rb +4 -4
- data/lib/tapioca/helpers/config_helper.rb +4 -4
- data/lib/tapioca/helpers/env_helper.rb +1 -0
- data/lib/tapioca/helpers/gem_helper.rb +17 -5
- data/lib/tapioca/helpers/rbi_files_helper.rb +3 -3
- data/lib/tapioca/helpers/rbi_helper.rb +5 -13
- data/lib/tapioca/helpers/sorbet_helper.rb +3 -5
- data/lib/tapioca/helpers/source_uri.rb +1 -1
- data/lib/tapioca/helpers/test/dsl_compiler.rb +1 -1
- data/lib/tapioca/loaders/dsl.rb +9 -7
- data/lib/tapioca/loaders/gem.rb +2 -2
- data/lib/tapioca/loaders/loader.rb +6 -6
- data/lib/tapioca/rbi_ext/model.rb +8 -5
- data/lib/tapioca/rbi_formatter.rb +2 -2
- data/lib/tapioca/runtime/generic_type_registry.rb +22 -2
- data/lib/tapioca/runtime/reflection.rb +63 -2
- data/lib/tapioca/runtime/trackers/autoload.rb +3 -0
- data/lib/tapioca/runtime/trackers/constant_definition.rb +13 -5
- data/lib/tapioca/runtime/trackers/mixin.rb +37 -36
- data/lib/tapioca/runtime/trackers/required_ancestor.rb +17 -4
- data/lib/tapioca/runtime/trackers/tracker.rb +45 -0
- data/lib/tapioca/runtime/trackers.rb +27 -1
- data/lib/tapioca/sorbet_ext/generic_name_patch.rb +17 -6
- data/lib/tapioca/static/symbol_loader.rb +3 -3
- data/lib/tapioca/static/symbol_table_parser.rb +6 -0
- data/lib/tapioca/version.rb +1 -1
- data/lib/tapioca.rb +0 -10
- metadata +8 -20
@@ -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).
|
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 =
|
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
|
|
@@ -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
|
data/lib/tapioca/gem/pipeline.rb
CHANGED
@@ -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
|
@@ -341,7 +342,7 @@ module Tapioca
|
|
341
342
|
|
342
343
|
sig { params(constant: Module, strict: T::Boolean).returns(T::Boolean) }
|
343
344
|
def defined_in_gem?(constant, strict: true)
|
344
|
-
files =
|
345
|
+
files = get_file_candidates(constant)
|
345
346
|
.merge(Runtime::Trackers::ConstantDefinition.files_for(constant))
|
346
347
|
|
347
348
|
return !strict if files.empty?
|
@@ -351,13 +352,11 @@ module Tapioca
|
|
351
352
|
end
|
352
353
|
end
|
353
354
|
|
354
|
-
sig { params(constant: Module).returns(T::
|
355
|
+
sig { params(constant: Module).returns(T::Set[String]) }
|
355
356
|
def get_file_candidates(constant)
|
356
|
-
|
357
|
-
|
358
|
-
wrapped_module.send(:method_candidates).flatten.filter_map(&:source_file).uniq
|
357
|
+
file_candidates_for(constant)
|
359
358
|
rescue ArgumentError, NameError
|
360
|
-
|
359
|
+
Set.new
|
361
360
|
end
|
362
361
|
|
363
362
|
sig { params(name: String).void }
|
@@ -390,6 +389,9 @@ module Tapioca
|
|
390
389
|
type_variables = Runtime::GenericTypeRegistry.lookup_type_variables(constant)
|
391
390
|
return type_name unless type_variables
|
392
391
|
|
392
|
+
type_variables = type_variables.reject(&:fixed?)
|
393
|
+
return type_name if type_variables.empty?
|
394
|
+
|
393
395
|
type_variable_names = type_variables.map { "T.untyped" }.join(", ")
|
394
396
|
|
395
397
|
"#{type_name}[#{type_variable_names}]"
|
data/lib/tapioca/gemfile.rb
CHANGED
@@ -8,7 +8,7 @@ module Tapioca
|
|
8
8
|
Spec = T.type_alias do
|
9
9
|
T.any(
|
10
10
|
::Bundler::StubSpecification,
|
11
|
-
::Gem::Specification
|
11
|
+
::Gem::Specification,
|
12
12
|
)
|
13
13
|
end
|
14
14
|
|
@@ -147,7 +147,7 @@ module Tapioca
|
|
147
147
|
.flat_map do |spec|
|
148
148
|
spec.files.filter_map { |file| [file.realpath.to_s, spec] if file.exist? }
|
149
149
|
end.to_h,
|
150
|
-
T.nilable(T::Hash[String, Gemfile::GemSpec])
|
150
|
+
T.nilable(T::Hash[String, Gemfile::GemSpec]),
|
151
151
|
)
|
152
152
|
end
|
153
153
|
end
|
@@ -157,7 +157,7 @@ module Tapioca
|
|
157
157
|
"sorbet", "sorbet-static", "sorbet-runtime", "sorbet-static-and-runtime",
|
158
158
|
"debug", "fakefs",
|
159
159
|
].freeze,
|
160
|
-
T::Array[String]
|
160
|
+
T::Array[String],
|
161
161
|
)
|
162
162
|
|
163
163
|
sig { returns(String) }
|
@@ -201,7 +201,7 @@ module Tapioca
|
|
201
201
|
if default_gem?
|
202
202
|
files.any? { |file| file.to_s == to_realpath(path) }
|
203
203
|
else
|
204
|
-
to_realpath(path)
|
204
|
+
path_in_dir?(to_realpath(path), full_gem_path) || has_parent_gemspec?(path)
|
205
205
|
end
|
206
206
|
end
|
207
207
|
|
@@ -96,7 +96,7 @@ module Tapioca
|
|
96
96
|
params(
|
97
97
|
command_options: T::Hash[Symbol, Thor::Option],
|
98
98
|
config_key: String,
|
99
|
-
config_options: T::Hash[T.untyped, T.untyped]
|
99
|
+
config_options: T::Hash[T.untyped, T.untyped],
|
100
100
|
).returns(T::Array[ConfigError])
|
101
101
|
end
|
102
102
|
def validate_config_options(command_options, config_key, config_options)
|
@@ -157,18 +157,18 @@ module Tapioca
|
|
157
157
|
if match
|
158
158
|
ConfigErrorMessagePart.new(
|
159
159
|
message: "#{match[1]}#{match[2]}",
|
160
|
-
colors: [:bold, :blue]
|
160
|
+
colors: [:bold, :blue],
|
161
161
|
)
|
162
162
|
else
|
163
163
|
ConfigErrorMessagePart.new(
|
164
164
|
message: part,
|
165
|
-
colors: [:yellow]
|
165
|
+
colors: [:yellow],
|
166
166
|
)
|
167
167
|
end
|
168
168
|
end
|
169
169
|
|
170
170
|
ConfigError.new(
|
171
|
-
message_parts: message_parts
|
171
|
+
message_parts: message_parts,
|
172
172
|
)
|
173
173
|
end
|
174
174
|
|
@@ -11,6 +11,7 @@ module Tapioca
|
|
11
11
|
sig { params(options: T::Hash[Symbol, T.untyped]).void }
|
12
12
|
def set_environment(options) # rubocop:disable Naming/AccessorMethodName
|
13
13
|
ENV["RAILS_ENV"] = ENV["RACK_ENV"] = options[:environment]
|
14
|
+
ENV["RUBY_DEBUG_ENABLE"] = "0"
|
14
15
|
end
|
15
16
|
end
|
16
17
|
end
|
@@ -5,15 +5,17 @@ module Tapioca
|
|
5
5
|
module GemHelper
|
6
6
|
extend T::Sig
|
7
7
|
|
8
|
-
sig { params(
|
9
|
-
def gem_in_app_dir?(
|
10
|
-
|
11
|
-
|
8
|
+
sig { params(app_dir: String, full_gem_path: String).returns(T::Boolean) }
|
9
|
+
def gem_in_app_dir?(app_dir, full_gem_path)
|
10
|
+
app_dir = to_realpath(app_dir)
|
11
|
+
full_gem_path = to_realpath(full_gem_path)
|
12
|
+
|
13
|
+
!gem_in_bundle_path?(full_gem_path) && path_in_dir?(full_gem_path, app_dir)
|
12
14
|
end
|
13
15
|
|
14
16
|
sig { params(full_gem_path: String).returns(T::Boolean) }
|
15
17
|
def gem_in_bundle_path?(full_gem_path)
|
16
|
-
|
18
|
+
path_in_dir?(full_gem_path, Bundler.bundle_path) || path_in_dir?(full_gem_path, Bundler.app_cache)
|
17
19
|
end
|
18
20
|
|
19
21
|
sig { params(path: T.any(String, Pathname)).returns(String) }
|
@@ -22,5 +24,15 @@ module Tapioca
|
|
22
24
|
path_string = File.realpath(path_string) if File.exist?(path_string)
|
23
25
|
path_string
|
24
26
|
end
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
sig { params(path: T.any(Pathname, String), dir: T.any(Pathname, String)).returns(T::Boolean) }
|
31
|
+
def path_in_dir?(path, dir)
|
32
|
+
dir = Pathname.new(dir)
|
33
|
+
path = Pathname.new(path)
|
34
|
+
|
35
|
+
path.ascend.any?(dir)
|
36
|
+
end
|
25
37
|
end
|
26
38
|
end
|
@@ -42,7 +42,7 @@ module Tapioca
|
|
42
42
|
params(
|
43
43
|
index: RBI::Index,
|
44
44
|
shim_rbi_dir: String,
|
45
|
-
todo_rbi_file: String
|
45
|
+
todo_rbi_file: String,
|
46
46
|
).returns(T::Hash[String, T::Array[RBI::Node]])
|
47
47
|
end
|
48
48
|
def duplicated_nodes_from_index(index, shim_rbi_dir:, todo_rbi_file:)
|
@@ -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[Class],
|
84
84
|
).void
|
85
85
|
end
|
86
86
|
def validate_rbi_files(command:, gem_dir:, dsl_dir:, auto_strictness:, gems: [], compilers: [])
|
@@ -92,7 +92,7 @@ module Tapioca
|
|
92
92
|
"--error-url-base=#{error_url_base}",
|
93
93
|
"--stop-after namer",
|
94
94
|
dsl_dir,
|
95
|
-
gem_dir
|
95
|
+
gem_dir,
|
96
96
|
)
|
97
97
|
say(" Done", :green)
|
98
98
|
|
@@ -17,28 +17,20 @@ module Tapioca
|
|
17
17
|
variance: Symbol,
|
18
18
|
fixed: T.nilable(String),
|
19
19
|
upper: T.nilable(String),
|
20
|
-
lower: T.nilable(String)
|
20
|
+
lower: T.nilable(String),
|
21
21
|
).returns(String)
|
22
22
|
end
|
23
23
|
def serialize_type_variable(type, variance, fixed, upper, lower)
|
24
24
|
variance = nil if variance == :invariant
|
25
25
|
|
26
|
-
bounds = []
|
27
|
-
bounds << "fixed: #{fixed}" if fixed
|
28
|
-
bounds << "lower: #{lower}" if lower
|
29
|
-
bounds << "upper: #{upper}" if upper
|
30
|
-
|
31
|
-
parameters = []
|
32
26
|
block = []
|
27
|
+
block << "fixed: #{fixed}" if fixed
|
28
|
+
block << "lower: #{lower}" if lower
|
29
|
+
block << "upper: #{upper}" if upper
|
33
30
|
|
31
|
+
parameters = []
|
34
32
|
parameters << ":#{variance}" if variance
|
35
33
|
|
36
|
-
if sorbet_supports?(:type_variable_block_syntax)
|
37
|
-
block = bounds
|
38
|
-
else
|
39
|
-
parameters.concat(bounds)
|
40
|
-
end
|
41
|
-
|
42
34
|
serialized = type.dup
|
43
35
|
serialized << "(#{parameters.join(", ")})" unless parameters.empty?
|
44
36
|
serialized << " { { #{block.join(", ")} } }" unless block.empty?
|
@@ -7,12 +7,12 @@ module Tapioca
|
|
7
7
|
|
8
8
|
SORBET_GEM_SPEC = T.let(
|
9
9
|
::Gem::Specification.find_by_name("sorbet-static"),
|
10
|
-
::Gem::Specification
|
10
|
+
::Gem::Specification,
|
11
11
|
)
|
12
12
|
|
13
13
|
SORBET_BIN = T.let(
|
14
14
|
Pathname.new(SORBET_GEM_SPEC.full_gem_path) / "libexec" / "sorbet",
|
15
|
-
Pathname
|
15
|
+
Pathname,
|
16
16
|
)
|
17
17
|
|
18
18
|
SORBET_EXE_PATH_ENV_VAR = "TAPIOCA_SORBET_EXE"
|
@@ -20,9 +20,7 @@ module Tapioca
|
|
20
20
|
SORBET_PAYLOAD_URL = "https://github.com/sorbet/sorbet/tree/master/rbi"
|
21
21
|
|
22
22
|
FEATURE_REQUIREMENTS = T.let({
|
23
|
-
|
24
|
-
print_payload_sources: ::Gem::Requirement.new(">= 0.5.9818"), # https://github.com/sorbet/sorbet/pull/5504
|
25
|
-
type_variable_block_syntax: ::Gem::Requirement.new(">= 0.5.9892"), # https://github.com/sorbet/sorbet/pull/5639
|
23
|
+
# feature_name: ::Gem::Requirement.new(">= ___"), # https://github.com/sorbet/sorbet/pull/___
|
26
24
|
}.freeze, T::Hash[Symbol, ::Gem::Requirement])
|
27
25
|
|
28
26
|
sig { params(sorbet_args: String).returns(Spoom::ExecResult) }
|
data/lib/tapioca/loaders/dsl.rb
CHANGED
@@ -9,9 +9,9 @@ module Tapioca
|
|
9
9
|
class << self
|
10
10
|
extend T::Sig
|
11
11
|
|
12
|
-
sig { params(tapioca_path: String, eager_load: T::Boolean).void }
|
13
|
-
def load_application(tapioca_path:, eager_load: true)
|
14
|
-
loader = new(tapioca_path: tapioca_path)
|
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, app_root: app_root)
|
15
15
|
loader.load
|
16
16
|
end
|
17
17
|
end
|
@@ -26,12 +26,13 @@ module Tapioca
|
|
26
26
|
|
27
27
|
protected
|
28
28
|
|
29
|
-
sig { params(tapioca_path: String, eager_load: T::Boolean).void }
|
30
|
-
def initialize(tapioca_path:, eager_load: true)
|
29
|
+
sig { params(tapioca_path: String, eager_load: T::Boolean, app_root: String).void }
|
30
|
+
def initialize(tapioca_path:, eager_load: true, app_root: ".")
|
31
31
|
super()
|
32
32
|
|
33
33
|
@tapioca_path = tapioca_path
|
34
34
|
@eager_load = eager_load
|
35
|
+
@app_root = app_root
|
35
36
|
end
|
36
37
|
|
37
38
|
sig { void }
|
@@ -63,7 +64,8 @@ module Tapioca
|
|
63
64
|
|
64
65
|
load_rails_application(
|
65
66
|
environment_load: true,
|
66
|
-
eager_load: @eager_load
|
67
|
+
eager_load: @eager_load,
|
68
|
+
app_root: @app_root,
|
67
69
|
)
|
68
70
|
|
69
71
|
say("Done", :green)
|
@@ -71,7 +73,7 @@ module Tapioca
|
|
71
73
|
|
72
74
|
sig { void }
|
73
75
|
def abort_if_pending_migrations!
|
74
|
-
return unless File.exist?("config/application.rb")
|
76
|
+
return unless File.exist?("#{@app_root}/config/application.rb")
|
75
77
|
return unless defined?(::Rake)
|
76
78
|
|
77
79
|
Rails.application.load_tasks
|
data/lib/tapioca/loaders/gem.rb
CHANGED
@@ -14,7 +14,7 @@ module Tapioca
|
|
14
14
|
bundle: Gemfile,
|
15
15
|
prerequire: T.nilable(String),
|
16
16
|
postrequire: String,
|
17
|
-
default_command: String
|
17
|
+
default_command: String,
|
18
18
|
).void
|
19
19
|
end
|
20
20
|
def load_application(bundle:, prerequire:, postrequire:, default_command:)
|
@@ -38,7 +38,7 @@ module Tapioca
|
|
38
38
|
bundle: Gemfile,
|
39
39
|
prerequire: T.nilable(String),
|
40
40
|
postrequire: String,
|
41
|
-
default_command: String
|
41
|
+
default_command: String,
|
42
42
|
).void
|
43
43
|
end
|
44
44
|
def initialize(bundle:, prerequire:, postrequire:, default_command:)
|
@@ -33,16 +33,16 @@ module Tapioca
|
|
33
33
|
load_rails_engines
|
34
34
|
end
|
35
35
|
|
36
|
-
sig { params(environment_load: T::Boolean, eager_load: T::Boolean).void }
|
37
|
-
def load_rails_application(environment_load: false, eager_load: false)
|
38
|
-
return unless File.exist?("config/application.rb")
|
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: ".")
|
38
|
+
return unless File.exist?("#{app_root}/config/application.rb")
|
39
39
|
|
40
40
|
silence_deprecations
|
41
41
|
|
42
42
|
if environment_load
|
43
|
-
require "
|
43
|
+
require "./#{app_root}/config/environment"
|
44
44
|
else
|
45
|
-
require "
|
45
|
+
require "./#{app_root}/config/application"
|
46
46
|
end
|
47
47
|
|
48
48
|
eager_load_rails_app if eager_load
|
@@ -113,7 +113,7 @@ module Tapioca
|
|
113
113
|
if Object.const_defined?("ActiveSupport")
|
114
114
|
Object.const_get("ActiveSupport").run_load_hooks(
|
115
115
|
:before_eager_load,
|
116
|
-
application
|
116
|
+
application,
|
117
117
|
)
|
118
118
|
end
|
119
119
|
|
@@ -32,7 +32,7 @@ module RBI
|
|
32
32
|
params(
|
33
33
|
name: String,
|
34
34
|
superclass_name: T.nilable(String),
|
35
|
-
block: T.nilable(T.proc.params(scope: RBI::Scope).void)
|
35
|
+
block: T.nilable(T.proc.params(scope: RBI::Scope).void),
|
36
36
|
).returns(Scope)
|
37
37
|
end
|
38
38
|
def create_class(name, superclass_name: nil, &block)
|
@@ -68,7 +68,7 @@ module RBI
|
|
68
68
|
variance: Symbol,
|
69
69
|
fixed: T.nilable(String),
|
70
70
|
upper: T.nilable(String),
|
71
|
-
lower: T.nilable(String)
|
71
|
+
lower: T.nilable(String),
|
72
72
|
).void
|
73
73
|
end
|
74
74
|
def create_type_variable(name, type:, variance: :invariant, fixed: nil, upper: nil, lower: nil)
|
@@ -82,14 +82,17 @@ module RBI
|
|
82
82
|
parameters: T::Array[TypedParam],
|
83
83
|
return_type: String,
|
84
84
|
class_method: T::Boolean,
|
85
|
-
visibility: RBI::Visibility
|
85
|
+
visibility: RBI::Visibility,
|
86
|
+
comments: T::Array[RBI::Comment],
|
86
87
|
).void
|
87
88
|
end
|
88
|
-
def create_method(name, parameters: [], return_type: "T.untyped", class_method: false, visibility: RBI::Public.new
|
89
|
+
def create_method(name, parameters: [], return_type: "T.untyped", class_method: false, visibility: RBI::Public.new,
|
90
|
+
comments: [])
|
89
91
|
return unless Tapioca::RBIHelper.valid_method_name?(name)
|
90
92
|
|
91
93
|
sig = RBI::Sig.new(return_type: return_type)
|
92
|
-
method = RBI::Method.new(name, sigs: [sig], is_singleton: class_method, visibility: visibility
|
94
|
+
method = RBI::Method.new(name, sigs: [sig], is_singleton: class_method, visibility: visibility,
|
95
|
+
comments: comments)
|
93
96
|
parameters.each do |param|
|
94
97
|
method << param.param
|
95
98
|
sig << RBI::SigParam.new(param.param.name, param.type)
|
@@ -9,7 +9,7 @@ module Tapioca
|
|
9
9
|
params(
|
10
10
|
file: RBI::File,
|
11
11
|
command: String,
|
12
|
-
reason: T.nilable(String)
|
12
|
+
reason: T.nilable(String),
|
13
13
|
).void
|
14
14
|
end
|
15
15
|
def write_header!(file, command, reason: nil)
|
@@ -32,6 +32,6 @@ module Tapioca
|
|
32
32
|
max_line_length: nil,
|
33
33
|
nest_singleton_methods: true,
|
34
34
|
nest_non_public_methods: true,
|
35
|
-
sort_nodes: true
|
35
|
+
sort_nodes: true,
|
36
36
|
), RBIFormatter)
|
37
37
|
end
|
@@ -23,14 +23,30 @@ module Tapioca
|
|
23
23
|
module GenericTypeRegistry
|
24
24
|
@generic_instances = T.let(
|
25
25
|
{},
|
26
|
-
T::Hash[String, Module]
|
26
|
+
T::Hash[String, Module],
|
27
27
|
)
|
28
28
|
|
29
29
|
@type_variables = T.let(
|
30
30
|
{}.compare_by_identity,
|
31
|
-
T::Hash[Module, T::Array[TypeVariableModule]]
|
31
|
+
T::Hash[Module, T::Array[TypeVariableModule]],
|
32
32
|
)
|
33
33
|
|
34
|
+
class GenericType < T::Types::Simple
|
35
|
+
extend T::Sig
|
36
|
+
|
37
|
+
sig { params(raw_type: Module, underlying_type: Module).void }
|
38
|
+
def initialize(raw_type, underlying_type)
|
39
|
+
super(raw_type)
|
40
|
+
|
41
|
+
@underlying_type = T.let(underlying_type, Module)
|
42
|
+
end
|
43
|
+
|
44
|
+
sig { params(obj: T.untyped).returns(T::Boolean) }
|
45
|
+
def valid?(obj)
|
46
|
+
obj.is_a?(@underlying_type)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
34
50
|
class << self
|
35
51
|
extend T::Sig
|
36
52
|
|
@@ -116,6 +132,10 @@ module Tapioca
|
|
116
132
|
generic_type.define_singleton_method(:name, name_proc)
|
117
133
|
generic_type.define_singleton_method(:to_s, name_proc)
|
118
134
|
|
135
|
+
override_type = GenericType.new(generic_type, constant)
|
136
|
+
override_type_proc = -> { override_type }
|
137
|
+
generic_type.define_singleton_method(:__tapioca_override_type, override_type_proc)
|
138
|
+
|
119
139
|
# We need to define a `<=` method on the cloned constant, so that Sorbet
|
120
140
|
# can do covariance/contravariance checks on the type variables.
|
121
141
|
#
|