tapioca 0.10.1 → 0.10.3
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
#
|