tapioca 0.16.9 → 0.17.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 +4 -4
- data/README.md +21 -0
- data/exe/tapioca +6 -1
- data/lib/ruby_lsp/tapioca/addon.rb +73 -43
- data/lib/ruby_lsp/tapioca/run_gem_rbi_check.rb +43 -43
- data/lib/ruby_lsp/tapioca/server_addon.rb +13 -10
- data/lib/tapioca/bundler_ext/auto_require_hook.rb +6 -14
- data/lib/tapioca/cli.rb +16 -8
- data/lib/tapioca/commands/abstract_dsl.rb +39 -66
- data/lib/tapioca/commands/abstract_gem.rb +25 -46
- data/lib/tapioca/commands/annotations.rb +28 -34
- data/lib/tapioca/commands/check_shims.rb +6 -15
- data/lib/tapioca/commands/command.rb +12 -26
- data/lib/tapioca/commands/command_without_tracker.rb +2 -5
- data/lib/tapioca/commands/configure.rb +11 -16
- data/lib/tapioca/commands/dsl_compiler_list.rb +2 -1
- data/lib/tapioca/commands/dsl_generate.rb +2 -1
- data/lib/tapioca/commands/dsl_verify.rb +2 -1
- data/lib/tapioca/commands/gem_generate.rb +5 -9
- data/lib/tapioca/commands/gem_sync.rb +2 -1
- data/lib/tapioca/commands/gem_verify.rb +3 -2
- data/lib/tapioca/commands/require.rb +3 -7
- data/lib/tapioca/commands/todo.rb +6 -10
- data/lib/tapioca/dsl/compiler.rb +36 -63
- data/lib/tapioca/dsl/compilers/aasm.rb +33 -44
- data/lib/tapioca/dsl/compilers/action_controller_helpers.rb +8 -7
- data/lib/tapioca/dsl/compilers/action_mailer.rb +6 -5
- data/lib/tapioca/dsl/compilers/action_text.rb +6 -5
- data/lib/tapioca/dsl/compilers/active_job.rb +6 -10
- data/lib/tapioca/dsl/compilers/active_model_attributes.rb +10 -11
- data/lib/tapioca/dsl/compilers/active_model_secure_password.rb +5 -6
- data/lib/tapioca/dsl/compilers/active_model_validations_confirmation.rb +5 -12
- data/lib/tapioca/dsl/compilers/active_record_associations.rb +17 -44
- data/lib/tapioca/dsl/compilers/active_record_columns.rb +20 -26
- data/lib/tapioca/dsl/compilers/active_record_delegated_types.rb +9 -8
- data/lib/tapioca/dsl/compilers/active_record_enum.rb +7 -6
- data/lib/tapioca/dsl/compilers/active_record_fixtures.rb +54 -62
- data/lib/tapioca/dsl/compilers/active_record_relations.rb +148 -209
- data/lib/tapioca/dsl/compilers/active_record_scope.rb +8 -13
- data/lib/tapioca/dsl/compilers/active_record_secure_token.rb +5 -4
- data/lib/tapioca/dsl/compilers/active_record_store.rb +5 -4
- data/lib/tapioca/dsl/compilers/active_record_typed_store.rb +19 -28
- data/lib/tapioca/dsl/compilers/active_resource.rb +19 -21
- data/lib/tapioca/dsl/compilers/active_storage.rb +6 -14
- data/lib/tapioca/dsl/compilers/active_support_concern.rb +9 -8
- data/lib/tapioca/dsl/compilers/active_support_current_attributes.rb +8 -7
- data/lib/tapioca/dsl/compilers/active_support_time_ext.rb +5 -4
- data/lib/tapioca/dsl/compilers/config.rb +5 -4
- data/lib/tapioca/dsl/compilers/frozen_record.rb +7 -11
- data/lib/tapioca/dsl/compilers/graphql_input_object.rb +9 -10
- data/lib/tapioca/dsl/compilers/graphql_mutation.rb +6 -10
- data/lib/tapioca/dsl/compilers/identity_cache.rb +11 -39
- data/lib/tapioca/dsl/compilers/json_api_client_resource.rb +9 -18
- data/lib/tapioca/dsl/compilers/kredis.rb +7 -8
- data/lib/tapioca/dsl/compilers/mixed_in_class_attributes.rb +5 -4
- data/lib/tapioca/dsl/compilers/protobuf.rb +13 -26
- data/lib/tapioca/dsl/compilers/rails_generators.rb +9 -11
- data/lib/tapioca/dsl/compilers/sidekiq_worker.rb +23 -13
- data/lib/tapioca/dsl/compilers/smart_properties.rb +32 -38
- data/lib/tapioca/dsl/compilers/state_machines.rb +15 -26
- data/lib/tapioca/dsl/compilers/url_helpers.rb +10 -9
- data/lib/tapioca/dsl/compilers.rb +4 -7
- data/lib/tapioca/dsl/helpers/active_model_type_helper.rb +13 -16
- data/lib/tapioca/dsl/helpers/active_record_column_type_helper.rb +13 -28
- data/lib/tapioca/dsl/helpers/active_record_constants_helper.rb +19 -15
- data/lib/tapioca/dsl/helpers/graphql_type_helper.rb +5 -24
- data/lib/tapioca/dsl/pipeline.rb +30 -58
- data/lib/tapioca/executor.rb +6 -12
- data/lib/tapioca/gem/events.rb +24 -34
- data/lib/tapioca/gem/listeners/base.rb +7 -10
- data/lib/tapioca/gem/listeners/dynamic_mixins.rb +4 -2
- data/lib/tapioca/gem/listeners/foreign_constants.rb +5 -7
- data/lib/tapioca/gem/listeners/methods.rb +36 -47
- data/lib/tapioca/gem/listeners/mixins.rb +6 -18
- data/lib/tapioca/gem/listeners/remove_empty_payload_scopes.rb +4 -2
- data/lib/tapioca/gem/listeners/sorbet_enums.rb +4 -2
- data/lib/tapioca/gem/listeners/sorbet_helpers.rb +4 -2
- data/lib/tapioca/gem/listeners/sorbet_props.rb +4 -2
- data/lib/tapioca/gem/listeners/sorbet_required_ancestors.rb +4 -2
- data/lib/tapioca/gem/listeners/sorbet_signatures.rb +7 -5
- data/lib/tapioca/gem/listeners/sorbet_type_variables.rb +6 -4
- data/lib/tapioca/gem/listeners/source_location.rb +15 -8
- data/lib/tapioca/gem/listeners/subconstants.rb +5 -4
- data/lib/tapioca/gem/listeners/yard_doc.rb +30 -23
- data/lib/tapioca/gem/pipeline.rb +107 -91
- data/lib/tapioca/gem_info.rb +1 -1
- data/lib/tapioca/gemfile.rb +64 -73
- data/lib/tapioca/helpers/cli_helper.rb +4 -7
- data/lib/tapioca/helpers/config_helper.rb +17 -29
- data/lib/tapioca/helpers/env_helper.rb +2 -5
- data/lib/tapioca/helpers/gem_helper.rb +5 -5
- data/lib/tapioca/helpers/git_attributes.rb +3 -3
- data/lib/tapioca/helpers/rbi_files_helper.rb +76 -73
- data/lib/tapioca/helpers/rbi_helper.rb +14 -22
- data/lib/tapioca/helpers/sorbet_helper.rb +9 -18
- data/lib/tapioca/helpers/source_uri.rb +15 -25
- data/lib/tapioca/helpers/test/content.rb +7 -10
- data/lib/tapioca/helpers/test/dsl_compiler.rb +20 -33
- data/lib/tapioca/helpers/test/isolation.rb +10 -14
- data/lib/tapioca/helpers/test/template.rb +6 -11
- data/lib/tapioca/internal.rb +18 -8
- data/lib/tapioca/loaders/dsl.rb +11 -19
- data/lib/tapioca/loaders/gem.rb +6 -21
- data/lib/tapioca/loaders/loader.rb +21 -39
- data/lib/tapioca/rbi_ext/model.rb +12 -37
- data/lib/tapioca/rbi_formatter.rb +10 -19
- data/lib/tapioca/rbs/rewriter.rb +55 -0
- data/lib/tapioca/repo_index.rb +7 -9
- data/lib/tapioca/runtime/attached_class_of_32.rb +1 -1
- data/lib/tapioca/runtime/attached_class_of_legacy.rb +2 -5
- data/lib/tapioca/runtime/dynamic_mixin_compiler.rb +23 -23
- data/lib/tapioca/runtime/generic_type_registry.rb +13 -23
- data/lib/tapioca/runtime/reflection.rb +81 -60
- data/lib/tapioca/runtime/source_location.rb +44 -0
- data/lib/tapioca/runtime/trackers/autoload.rb +7 -9
- data/lib/tapioca/runtime/trackers/constant_definition.rb +18 -14
- data/lib/tapioca/runtime/trackers/method_definition.rb +65 -0
- data/lib/tapioca/runtime/trackers/mixin.rb +8 -11
- data/lib/tapioca/runtime/trackers/required_ancestor.rb +3 -3
- data/lib/tapioca/runtime/trackers/tracker.rb +3 -6
- data/lib/tapioca/runtime/trackers.rb +5 -8
- data/lib/tapioca/sorbet_ext/generic_name_patch.rb +9 -15
- data/lib/tapioca/sorbet_ext/name_patch.rb +2 -2
- data/lib/tapioca/sorbet_ext/proc_bind_patch.rb +1 -1
- data/lib/tapioca/static/requires_compiler.rb +6 -6
- data/lib/tapioca/static/symbol_loader.rb +14 -16
- data/lib/tapioca/static/symbol_table_parser.rb +8 -8
- data/lib/tapioca/version.rb +1 -1
- data/lib/tapioca.rb +22 -29
- metadata +27 -10
|
@@ -10,7 +10,7 @@ module Tapioca
|
|
|
10
10
|
|
|
11
11
|
# Returns the type indicated by the custom ActiveModel::Type::Value.
|
|
12
12
|
# Accepts subclasses of ActiveModel::Type::Value as well as classes that implement similar methods.
|
|
13
|
-
|
|
13
|
+
#: (untyped type_value) -> String
|
|
14
14
|
def type_for(type_value)
|
|
15
15
|
return "T.untyped" if Runtime::GenericTypeRegistry.generic_type_instance?(type_value)
|
|
16
16
|
|
|
@@ -23,34 +23,31 @@ module Tapioca
|
|
|
23
23
|
type.to_s
|
|
24
24
|
end
|
|
25
25
|
|
|
26
|
-
|
|
26
|
+
#: (untyped type_value) -> bool
|
|
27
27
|
def assume_nilable?(type_value)
|
|
28
28
|
!type_value.respond_to?(:__tapioca_type)
|
|
29
29
|
end
|
|
30
30
|
|
|
31
31
|
private
|
|
32
32
|
|
|
33
|
-
MEANINGLESS_TYPES =
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
].freeze,
|
|
40
|
-
T::Array[Object],
|
|
41
|
-
)
|
|
33
|
+
MEANINGLESS_TYPES = [
|
|
34
|
+
T.untyped,
|
|
35
|
+
T.noreturn,
|
|
36
|
+
T::Private::Types::Void,
|
|
37
|
+
T::Private::Types::NotTyped,
|
|
38
|
+
].freeze #: Array[Object]
|
|
42
39
|
|
|
43
|
-
|
|
40
|
+
#: (untyped type) -> bool
|
|
44
41
|
def meaningful_type?(type)
|
|
45
42
|
!MEANINGLESS_TYPES.include?(type)
|
|
46
43
|
end
|
|
47
44
|
|
|
48
|
-
|
|
45
|
+
#: (untyped obj) -> T::Types::Base?
|
|
49
46
|
def lookup_tapioca_type(obj)
|
|
50
47
|
T::Utils.coerce(obj.__tapioca_type) if obj.respond_to?(:__tapioca_type)
|
|
51
48
|
end
|
|
52
49
|
|
|
53
|
-
|
|
50
|
+
#: (untyped obj, Symbol method) -> T::Types::Base?
|
|
54
51
|
def lookup_return_type_of_method(obj, method)
|
|
55
52
|
return_type = lookup_signature_of_method(obj, method)&.return_type
|
|
56
53
|
return unless return_type && meaningful_type?(return_type)
|
|
@@ -58,7 +55,7 @@ module Tapioca
|
|
|
58
55
|
return_type
|
|
59
56
|
end
|
|
60
57
|
|
|
61
|
-
|
|
58
|
+
#: (untyped obj, Symbol method) -> T::Types::Base?
|
|
62
59
|
def lookup_arg_type_of_method(obj, method)
|
|
63
60
|
# Arg types is an array of [name, type] entries, so we dig into first entry (index 0)
|
|
64
61
|
# and then into the type which is the last element (index 1)
|
|
@@ -68,7 +65,7 @@ module Tapioca
|
|
|
68
65
|
first_arg_type
|
|
69
66
|
end
|
|
70
67
|
|
|
71
|
-
|
|
68
|
+
#: (untyped obj, Symbol method) -> untyped
|
|
72
69
|
def lookup_signature_of_method(obj, method)
|
|
73
70
|
Runtime::Reflection.signature_of(obj.method(method))
|
|
74
71
|
rescue NameError
|
|
@@ -22,12 +22,7 @@ module Tapioca
|
|
|
22
22
|
class << self
|
|
23
23
|
extend T::Sig
|
|
24
24
|
|
|
25
|
-
|
|
26
|
-
params(
|
|
27
|
-
options: T::Hash[String, T.untyped],
|
|
28
|
-
block: T.proc.params(value: String, default_column_type_option: ColumnTypeOption).void,
|
|
29
|
-
).returns(ColumnTypeOption)
|
|
30
|
-
end
|
|
25
|
+
#: (Hash[String, untyped] options) { (String value, ColumnTypeOption default_column_type_option) -> void } -> ColumnTypeOption
|
|
31
26
|
def from_options(options, &block)
|
|
32
27
|
column_type_option = Persisted
|
|
33
28
|
value = options["ActiveRecordColumnTypes"]
|
|
@@ -44,39 +39,29 @@ module Tapioca
|
|
|
44
39
|
end
|
|
45
40
|
end
|
|
46
41
|
|
|
47
|
-
|
|
42
|
+
#: -> bool
|
|
48
43
|
def persisted?
|
|
49
44
|
self == ColumnTypeOption::Persisted
|
|
50
45
|
end
|
|
51
46
|
|
|
52
|
-
|
|
47
|
+
#: -> bool
|
|
53
48
|
def nilable?
|
|
54
49
|
self == ColumnTypeOption::Nilable
|
|
55
50
|
end
|
|
56
51
|
|
|
57
|
-
|
|
52
|
+
#: -> bool
|
|
58
53
|
def untyped?
|
|
59
54
|
self == ColumnTypeOption::Untyped
|
|
60
55
|
end
|
|
61
56
|
end
|
|
62
57
|
|
|
63
|
-
|
|
64
|
-
params(
|
|
65
|
-
constant: T.class_of(ActiveRecord::Base),
|
|
66
|
-
column_type_option: ColumnTypeOption,
|
|
67
|
-
).void
|
|
68
|
-
end
|
|
58
|
+
#: (singleton(ActiveRecord::Base) constant, ?column_type_option: ColumnTypeOption) -> void
|
|
69
59
|
def initialize(constant, column_type_option: ColumnTypeOption::Persisted)
|
|
70
60
|
@constant = constant
|
|
71
61
|
@column_type_option = column_type_option
|
|
72
62
|
end
|
|
73
63
|
|
|
74
|
-
|
|
75
|
-
params(
|
|
76
|
-
attribute_name: String,
|
|
77
|
-
column_name: String,
|
|
78
|
-
).returns([String, String])
|
|
79
|
-
end
|
|
64
|
+
#: (String attribute_name, ?String column_name) -> [String, String]
|
|
80
65
|
def type_for(attribute_name, column_name = attribute_name)
|
|
81
66
|
return id_type if attribute_name == "id"
|
|
82
67
|
|
|
@@ -85,7 +70,7 @@ module Tapioca
|
|
|
85
70
|
|
|
86
71
|
private
|
|
87
72
|
|
|
88
|
-
|
|
73
|
+
#: -> [String, String]
|
|
89
74
|
def id_type
|
|
90
75
|
if @constant.respond_to?(:composite_primary_key?) && T.unsafe(@constant).composite_primary_key?
|
|
91
76
|
primary_key_columns = @constant.primary_key
|
|
@@ -105,7 +90,7 @@ module Tapioca
|
|
|
105
90
|
end
|
|
106
91
|
end
|
|
107
92
|
|
|
108
|
-
|
|
93
|
+
#: (String? column_name) -> [String, String]
|
|
109
94
|
def column_type_for(column_name)
|
|
110
95
|
return ["T.untyped", "T.untyped"] if @column_type_option.untyped?
|
|
111
96
|
|
|
@@ -128,7 +113,7 @@ module Tapioca
|
|
|
128
113
|
end
|
|
129
114
|
end
|
|
130
115
|
|
|
131
|
-
|
|
116
|
+
#: (untyped column_type, column_nullability: bool) -> String
|
|
132
117
|
def type_for_activerecord_value(column_type, column_nullability:)
|
|
133
118
|
case column_type
|
|
134
119
|
when ->(type) { defined?(MoneyColumn) && MoneyColumn::ActiveRecordType === type }
|
|
@@ -229,7 +214,7 @@ module Tapioca
|
|
|
229
214
|
end
|
|
230
215
|
end
|
|
231
216
|
|
|
232
|
-
|
|
217
|
+
#: (String base_type, column_nullability: bool) -> String
|
|
233
218
|
def as_non_nilable_if_persisted_and_not_nullable(base_type, column_nullability:)
|
|
234
219
|
# It's possible that when ActiveModel::Type::Value is used, the signature being reflected on in
|
|
235
220
|
# ActiveModelTypeHelper.type_for(type_value) may say the type can be nilable. However, if the type is
|
|
@@ -239,7 +224,7 @@ module Tapioca
|
|
|
239
224
|
base_type
|
|
240
225
|
end
|
|
241
226
|
|
|
242
|
-
|
|
227
|
+
#: (ActiveRecord::Enum::EnumType column_type) -> String
|
|
243
228
|
def enum_setter_type(column_type)
|
|
244
229
|
# In Rails < 7 this method is private. When support for that is dropped we can call the method directly
|
|
245
230
|
case column_type.send(:subtype)
|
|
@@ -250,7 +235,7 @@ module Tapioca
|
|
|
250
235
|
end
|
|
251
236
|
end
|
|
252
237
|
|
|
253
|
-
|
|
238
|
+
#: (ActiveRecord::Type::Serialized column_type) -> String
|
|
254
239
|
def serialized_column_type(column_type)
|
|
255
240
|
case column_type.coder
|
|
256
241
|
when ActiveRecord::Coders::YAMLColumn
|
|
@@ -267,7 +252,7 @@ module Tapioca
|
|
|
267
252
|
end
|
|
268
253
|
end
|
|
269
254
|
|
|
270
|
-
|
|
255
|
+
#: (untyped column_type) -> bool
|
|
271
256
|
def not_nilable_serialized_column?(column_type)
|
|
272
257
|
return false unless column_type.is_a?(ActiveRecord::Type::Serialized)
|
|
273
258
|
return false unless column_type.coder.is_a?(ActiveRecord::Coders::YAMLColumn)
|
|
@@ -11,23 +11,27 @@ module Tapioca
|
|
|
11
11
|
T.any(::ActiveRecord::Reflection::ThroughReflection, ::ActiveRecord::Reflection::AssociationReflection)
|
|
12
12
|
end
|
|
13
13
|
|
|
14
|
-
|
|
15
|
-
AssociationMethodsModuleName = T.let("GeneratedAssociationMethods", String)
|
|
16
|
-
DelegatedTypesModuleName = T.let("GeneratedDelegatedTypeMethods", String)
|
|
17
|
-
SecureTokensModuleName = T.let("GeneratedSecureTokenMethods", String)
|
|
18
|
-
StoredAttributesModuleName = T.let("GeneratedStoredAttributesMethods", String)
|
|
14
|
+
# rubocop:disable Naming/ConstantName
|
|
19
15
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
16
|
+
AttributeMethodsModuleName = "GeneratedAttributeMethods" #: String
|
|
17
|
+
AssociationMethodsModuleName = "GeneratedAssociationMethods" #: String
|
|
18
|
+
DelegatedTypesModuleName = "GeneratedDelegatedTypeMethods" #: String
|
|
19
|
+
SecureTokensModuleName = "GeneratedSecureTokenMethods" #: String
|
|
20
|
+
StoredAttributesModuleName = "GeneratedStoredAttributesMethods" #: String
|
|
23
21
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
22
|
+
RelationMethodsModuleName = "GeneratedRelationMethods" #: String
|
|
23
|
+
AssociationRelationMethodsModuleName = "GeneratedAssociationRelationMethods" #: String
|
|
24
|
+
CommonRelationMethodsModuleName = "CommonRelationMethods" #: String
|
|
25
|
+
|
|
26
|
+
RelationClassName = "PrivateRelation" #: String
|
|
27
|
+
RelationGroupChainClassName = "PrivateRelationGroupChain" #: String
|
|
28
|
+
RelationWhereChainClassName = "PrivateRelationWhereChain" #: String
|
|
29
|
+
AssociationRelationClassName = "PrivateAssociationRelation" #: String
|
|
30
|
+
AssociationRelationGroupChainClassName = "PrivateAssociationRelationGroupChain" #: String
|
|
31
|
+
AssociationRelationWhereChainClassName = "PrivateAssociationRelationWhereChain" #: String
|
|
32
|
+
AssociationsCollectionProxyClassName = "PrivateCollectionProxy" #: String
|
|
33
|
+
|
|
34
|
+
# rubocop:enable Naming/ConstantName
|
|
31
35
|
end
|
|
32
36
|
end
|
|
33
37
|
end
|
|
@@ -9,12 +9,7 @@ module Tapioca
|
|
|
9
9
|
|
|
10
10
|
extend T::Sig
|
|
11
11
|
|
|
12
|
-
|
|
13
|
-
params(
|
|
14
|
-
argument: GraphQL::Schema::Argument,
|
|
15
|
-
constant: T.any(T.class_of(GraphQL::Schema::Mutation), T.class_of(GraphQL::Schema::InputObject)),
|
|
16
|
-
).returns(String)
|
|
17
|
-
end
|
|
12
|
+
#: (GraphQL::Schema::Argument argument, (singleton(GraphQL::Schema::Mutation) | singleton(GraphQL::Schema::InputObject)) constant) -> String
|
|
18
13
|
def type_for_argument(argument, constant)
|
|
19
14
|
type = if argument.loads
|
|
20
15
|
loads_type = ::GraphQL::Schema::Wrapper.new(argument.loads)
|
|
@@ -39,21 +34,7 @@ module Tapioca
|
|
|
39
34
|
)
|
|
40
35
|
end
|
|
41
36
|
|
|
42
|
-
|
|
43
|
-
params(
|
|
44
|
-
type: T.any(
|
|
45
|
-
GraphQL::Schema::Wrapper,
|
|
46
|
-
T.class_of(GraphQL::Schema::Scalar),
|
|
47
|
-
T.class_of(GraphQL::Schema::Enum),
|
|
48
|
-
T.class_of(GraphQL::Schema::Union),
|
|
49
|
-
T.class_of(GraphQL::Schema::Object),
|
|
50
|
-
T.class_of(GraphQL::Schema::Interface),
|
|
51
|
-
T.class_of(GraphQL::Schema::InputObject),
|
|
52
|
-
),
|
|
53
|
-
ignore_nilable_wrapper: T::Boolean,
|
|
54
|
-
prepare_method: T.nilable(Method),
|
|
55
|
-
).returns(String)
|
|
56
|
-
end
|
|
37
|
+
#: ((GraphQL::Schema::Wrapper | singleton(GraphQL::Schema::Scalar) | singleton(GraphQL::Schema::Enum) | singleton(GraphQL::Schema::Union) | singleton(GraphQL::Schema::Object) | singleton(GraphQL::Schema::Interface) | singleton(GraphQL::Schema::InputObject)) type, ?ignore_nilable_wrapper: bool, ?prepare_method: Method?) -> String
|
|
57
38
|
def type_for(type, ignore_nilable_wrapper: false, prepare_method: nil)
|
|
58
39
|
unwrapped_type = type.unwrap
|
|
59
40
|
|
|
@@ -116,7 +97,7 @@ module Tapioca
|
|
|
116
97
|
|
|
117
98
|
private
|
|
118
99
|
|
|
119
|
-
|
|
100
|
+
#: (Module constant) -> String
|
|
120
101
|
def type_for_constant(constant)
|
|
121
102
|
if constant.instance_methods.include?(:prepare)
|
|
122
103
|
prepare_method = constant.instance_method(:prepare)
|
|
@@ -129,12 +110,12 @@ module Tapioca
|
|
|
129
110
|
Runtime::Reflection.qualified_name_of(constant) || "T.untyped"
|
|
130
111
|
end
|
|
131
112
|
|
|
132
|
-
|
|
113
|
+
#: (GraphQL::Schema::Argument argument) -> bool
|
|
133
114
|
def has_replaceable_default?(argument)
|
|
134
115
|
!!argument.replace_null_with_default? && !argument.default_value.nil?
|
|
135
116
|
end
|
|
136
117
|
|
|
137
|
-
|
|
118
|
+
#: (T::Types::Base? return_type) -> bool
|
|
138
119
|
def valid_return_type?(return_type)
|
|
139
120
|
!!return_type && !(T::Private::Types::Void === return_type || T::Private::Types::NotTyped === return_type)
|
|
140
121
|
end
|
data/lib/tapioca/dsl/pipeline.rb
CHANGED
|
@@ -6,37 +6,25 @@ module Tapioca
|
|
|
6
6
|
class Pipeline
|
|
7
7
|
extend T::Sig
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
#: T::Enumerable[singleton(Compiler)]
|
|
10
10
|
attr_reader :active_compilers
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
#: Array[Module]
|
|
13
13
|
attr_reader :requested_constants
|
|
14
14
|
|
|
15
|
-
|
|
15
|
+
#: Array[Pathname]
|
|
16
16
|
attr_reader :requested_paths
|
|
17
17
|
|
|
18
|
-
|
|
18
|
+
#: Array[Module]
|
|
19
19
|
attr_reader :skipped_constants
|
|
20
20
|
|
|
21
|
-
|
|
21
|
+
#: ^(String error) -> void
|
|
22
22
|
attr_reader :error_handler
|
|
23
23
|
|
|
24
|
-
|
|
24
|
+
#: Array[String]
|
|
25
25
|
attr_reader :errors
|
|
26
26
|
|
|
27
|
-
|
|
28
|
-
params(
|
|
29
|
-
requested_constants: T::Array[Module],
|
|
30
|
-
requested_paths: T::Array[Pathname],
|
|
31
|
-
requested_compilers: T::Array[T.class_of(Compiler)],
|
|
32
|
-
excluded_compilers: T::Array[T.class_of(Compiler)],
|
|
33
|
-
error_handler: T.proc.params(error: String).void,
|
|
34
|
-
skipped_constants: T::Array[Module],
|
|
35
|
-
number_of_workers: T.nilable(Integer),
|
|
36
|
-
compiler_options: T::Hash[String, T.untyped],
|
|
37
|
-
lsp_addon: T::Boolean,
|
|
38
|
-
).void
|
|
39
|
-
end
|
|
27
|
+
#: (requested_constants: Array[Module], ?requested_paths: Array[Pathname], ?requested_compilers: Array[singleton(Compiler)], ?excluded_compilers: Array[singleton(Compiler)], ?error_handler: ^(String error) -> void, ?skipped_constants: Array[Module], ?number_of_workers: Integer?, ?compiler_options: Hash[String, untyped], ?lsp_addon: bool) -> void
|
|
40
28
|
def initialize(
|
|
41
29
|
requested_constants:,
|
|
42
30
|
requested_paths: [],
|
|
@@ -48,10 +36,8 @@ module Tapioca
|
|
|
48
36
|
compiler_options: {},
|
|
49
37
|
lsp_addon: false
|
|
50
38
|
)
|
|
51
|
-
@active_compilers =
|
|
52
|
-
gather_active_compilers(requested_compilers, excluded_compilers)
|
|
53
|
-
T::Enumerable[T.class_of(Compiler)],
|
|
54
|
-
)
|
|
39
|
+
@active_compilers =
|
|
40
|
+
gather_active_compilers(requested_compilers, excluded_compilers) #: Enumerable[singleton(Compiler)]
|
|
55
41
|
@requested_constants = requested_constants
|
|
56
42
|
@requested_paths = requested_paths
|
|
57
43
|
@error_handler = error_handler
|
|
@@ -59,14 +45,10 @@ module Tapioca
|
|
|
59
45
|
@number_of_workers = number_of_workers
|
|
60
46
|
@compiler_options = compiler_options
|
|
61
47
|
@lsp_addon = lsp_addon
|
|
62
|
-
@errors =
|
|
48
|
+
@errors = [] #: Array[String]
|
|
63
49
|
end
|
|
64
50
|
|
|
65
|
-
|
|
66
|
-
type_parameters(:T).params(
|
|
67
|
-
blk: T.proc.params(constant: Module, rbi: RBI::File).returns(T.type_parameter(:T)),
|
|
68
|
-
).returns(T::Array[T.type_parameter(:T)])
|
|
69
|
-
end
|
|
51
|
+
#: [T] { (Module constant, RBI::File rbi) -> T } -> Array[T]
|
|
70
52
|
def run(&blk)
|
|
71
53
|
constants_to_process = gather_constants(requested_constants, requested_paths, skipped_constants)
|
|
72
54
|
.select { |c| Module === c } # Filter value constants out
|
|
@@ -78,6 +60,7 @@ module Tapioca
|
|
|
78
60
|
No classes/modules can be matched for RBI generation.
|
|
79
61
|
Please check that the requested classes/modules include processable DSL methods.
|
|
80
62
|
ERROR
|
|
63
|
+
raise Tapioca::Error, ""
|
|
81
64
|
end
|
|
82
65
|
|
|
83
66
|
if defined?(::ActiveRecord::Base) && constants_to_process.any? { |c| ::ActiveRecord::Base > c }
|
|
@@ -94,19 +77,23 @@ module Tapioca
|
|
|
94
77
|
blk.call(constant, rbi)
|
|
95
78
|
end
|
|
96
79
|
|
|
97
|
-
errors.
|
|
98
|
-
|
|
80
|
+
if errors.any?
|
|
81
|
+
errors.each do |msg|
|
|
82
|
+
report_error(msg)
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
raise Tapioca::Error, ""
|
|
99
86
|
end
|
|
100
87
|
|
|
101
88
|
result.compact
|
|
102
89
|
end
|
|
103
90
|
|
|
104
|
-
|
|
91
|
+
#: (String error) -> void
|
|
105
92
|
def add_error(error)
|
|
106
93
|
@errors << error
|
|
107
94
|
end
|
|
108
95
|
|
|
109
|
-
|
|
96
|
+
#: (String compiler_name) -> bool
|
|
110
97
|
def compiler_enabled?(compiler_name)
|
|
111
98
|
potential_names = Compilers::NAMESPACES.map { |namespace| namespace + compiler_name }
|
|
112
99
|
|
|
@@ -115,24 +102,16 @@ module Tapioca
|
|
|
115
102
|
end
|
|
116
103
|
end
|
|
117
104
|
|
|
118
|
-
|
|
105
|
+
#: -> Array[singleton(Compiler)]
|
|
119
106
|
def compilers
|
|
120
|
-
@compilers ||=
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
end,
|
|
124
|
-
T.nilable(T::Array[T.class_of(Compiler)]),
|
|
125
|
-
)
|
|
107
|
+
@compilers ||= Runtime::Reflection.descendants_of(Compiler).sort_by do |compiler|
|
|
108
|
+
T.must(compiler.name)
|
|
109
|
+
end #: Array[singleton(Compiler)]?
|
|
126
110
|
end
|
|
127
111
|
|
|
128
112
|
private
|
|
129
113
|
|
|
130
|
-
|
|
131
|
-
params(
|
|
132
|
-
requested_compilers: T::Array[T.class_of(Compiler)],
|
|
133
|
-
excluded_compilers: T::Array[T.class_of(Compiler)],
|
|
134
|
-
).returns(T::Enumerable[T.class_of(Compiler)])
|
|
135
|
-
end
|
|
114
|
+
#: (Array[singleton(Compiler)] requested_compilers, Array[singleton(Compiler)] excluded_compilers) -> T::Enumerable[singleton(Compiler)]
|
|
136
115
|
def gather_active_compilers(requested_compilers, excluded_compilers)
|
|
137
116
|
active_compilers = compilers
|
|
138
117
|
active_compilers -= excluded_compilers
|
|
@@ -140,13 +119,7 @@ module Tapioca
|
|
|
140
119
|
active_compilers
|
|
141
120
|
end
|
|
142
121
|
|
|
143
|
-
|
|
144
|
-
params(
|
|
145
|
-
requested_constants: T::Array[Module],
|
|
146
|
-
requested_paths: T::Array[Pathname],
|
|
147
|
-
skipped_constants: T::Array[Module],
|
|
148
|
-
).returns(T::Set[Module])
|
|
149
|
-
end
|
|
122
|
+
#: (Array[Module] requested_constants, Array[Pathname] requested_paths, Array[Module] skipped_constants) -> Set[Module]
|
|
150
123
|
def gather_constants(requested_constants, requested_paths, skipped_constants)
|
|
151
124
|
Compiler.requested_constants = requested_constants
|
|
152
125
|
constants = Set.new.compare_by_identity
|
|
@@ -168,7 +141,7 @@ module Tapioca
|
|
|
168
141
|
constants
|
|
169
142
|
end
|
|
170
143
|
|
|
171
|
-
|
|
144
|
+
#: (Set[Module] constants) -> Set[Module]
|
|
172
145
|
def filter_anonymous_and_reloaded_constants(constants)
|
|
173
146
|
# Group constants by their names
|
|
174
147
|
constants_by_name = constants
|
|
@@ -197,7 +170,7 @@ module Tapioca
|
|
|
197
170
|
Set.new.compare_by_identity.merge(filtered_constants)
|
|
198
171
|
end
|
|
199
172
|
|
|
200
|
-
|
|
173
|
+
#: (Module constant) -> RBI::File?
|
|
201
174
|
def rbi_for_constant(constant)
|
|
202
175
|
file = RBI::File.new(strictness: "true")
|
|
203
176
|
|
|
@@ -216,14 +189,13 @@ module Tapioca
|
|
|
216
189
|
file
|
|
217
190
|
end
|
|
218
191
|
|
|
219
|
-
|
|
192
|
+
#: (String error) -> void
|
|
220
193
|
def report_error(error)
|
|
221
194
|
handler = error_handler
|
|
222
195
|
handler.call(error)
|
|
223
|
-
exit(1)
|
|
224
196
|
end
|
|
225
197
|
|
|
226
|
-
|
|
198
|
+
#: -> void
|
|
227
199
|
def abort_if_pending_migrations!
|
|
228
200
|
# When running within the add-on, we cannot invoke the abort if pending migrations task because that will exit
|
|
229
201
|
# the process and crash the Rails runtime server. Instead, the Rails add-on checks for pending migrations and
|
data/lib/tapioca/executor.rb
CHANGED
|
@@ -5,26 +5,20 @@ module Tapioca
|
|
|
5
5
|
class Executor
|
|
6
6
|
extend T::Sig
|
|
7
7
|
|
|
8
|
-
MINIMUM_ITEMS_PER_WORKER =
|
|
8
|
+
MINIMUM_ITEMS_PER_WORKER = 2 #: Integer
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
#: (Array[untyped] queue, ?number_of_workers: Integer?) -> void
|
|
11
11
|
def initialize(queue, number_of_workers: nil)
|
|
12
12
|
@queue = queue
|
|
13
13
|
|
|
14
14
|
# Forking workers is expensive and not worth it for a low number of gems. Here we assign the number of workers to
|
|
15
15
|
# be the minimum between the number of available processors (max) or the number of workers to make sure that each
|
|
16
16
|
# one has at least 4 items to process
|
|
17
|
-
@number_of_workers =
|
|
18
|
-
|
|
19
|
-
Integer,
|
|
20
|
-
)
|
|
17
|
+
@number_of_workers = number_of_workers ||
|
|
18
|
+
[max_processors, (queue.length.to_f / MINIMUM_ITEMS_PER_WORKER).ceil].min #: Integer
|
|
21
19
|
end
|
|
22
20
|
|
|
23
|
-
|
|
24
|
-
type_parameters(:T).params(
|
|
25
|
-
block: T.proc.params(item: T.untyped).returns(T.type_parameter(:T)),
|
|
26
|
-
).returns(T::Array[T.type_parameter(:T)])
|
|
27
|
-
end
|
|
21
|
+
#: [T] { (untyped item) -> T } -> Array[T]
|
|
28
22
|
def run_in_parallel(&block)
|
|
29
23
|
# To have the parallel gem run jobs in the parent process, you must pass 0 as the number of processes
|
|
30
24
|
number_of_processes = @number_of_workers == 1 ? 0 : @number_of_workers
|
|
@@ -33,7 +27,7 @@ module Tapioca
|
|
|
33
27
|
|
|
34
28
|
private
|
|
35
29
|
|
|
36
|
-
|
|
30
|
+
#: -> Integer
|
|
37
31
|
def max_processors
|
|
38
32
|
env_max_processors = ENV["PARALLEL_PROCESSOR_COUNT"].to_i
|
|
39
33
|
env_max_processors.positive? ? env_max_processors : Etc.nprocessors
|
data/lib/tapioca/gem/events.rb
CHANGED
|
@@ -3,20 +3,18 @@
|
|
|
3
3
|
|
|
4
4
|
module Tapioca
|
|
5
5
|
module Gem
|
|
6
|
+
# @abstract
|
|
6
7
|
class Event
|
|
7
8
|
extend T::Sig
|
|
8
|
-
extend T::Helpers
|
|
9
|
-
|
|
10
|
-
abstract!
|
|
11
9
|
end
|
|
12
10
|
|
|
13
11
|
class SymbolFound < Event
|
|
14
12
|
extend T::Sig
|
|
15
13
|
|
|
16
|
-
|
|
14
|
+
#: String
|
|
17
15
|
attr_reader :symbol
|
|
18
16
|
|
|
19
|
-
|
|
17
|
+
#: (String symbol) -> void
|
|
20
18
|
def initialize(symbol)
|
|
21
19
|
super()
|
|
22
20
|
@symbol = symbol
|
|
@@ -26,13 +24,15 @@ module Tapioca
|
|
|
26
24
|
class ConstantFound < Event
|
|
27
25
|
extend T::Sig
|
|
28
26
|
|
|
29
|
-
|
|
27
|
+
#: String
|
|
30
28
|
attr_reader :symbol
|
|
31
29
|
|
|
32
|
-
|
|
30
|
+
# @without_runtime
|
|
31
|
+
#: BasicObject
|
|
33
32
|
attr_reader :constant
|
|
34
33
|
|
|
35
|
-
|
|
34
|
+
# @without_runtime
|
|
35
|
+
#: (String symbol, BasicObject constant) -> void
|
|
36
36
|
def initialize(symbol, constant)
|
|
37
37
|
super()
|
|
38
38
|
@symbol = symbol
|
|
@@ -43,30 +43,29 @@ module Tapioca
|
|
|
43
43
|
class ForeignConstantFound < ConstantFound
|
|
44
44
|
extend T::Sig
|
|
45
45
|
|
|
46
|
-
|
|
46
|
+
# @override
|
|
47
|
+
#: -> Module
|
|
47
48
|
def constant
|
|
48
49
|
T.cast(@constant, Module)
|
|
49
50
|
end
|
|
50
51
|
|
|
51
|
-
|
|
52
|
+
#: (String symbol, Module constant) -> void
|
|
52
53
|
def initialize(symbol, constant)
|
|
53
54
|
super
|
|
54
55
|
end
|
|
55
56
|
end
|
|
56
57
|
|
|
58
|
+
# @abstract
|
|
57
59
|
class NodeAdded < Event
|
|
58
|
-
extend T::Helpers
|
|
59
60
|
extend T::Sig
|
|
60
61
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
sig { returns(String) }
|
|
62
|
+
#: String
|
|
64
63
|
attr_reader :symbol
|
|
65
64
|
|
|
66
|
-
|
|
65
|
+
#: Module
|
|
67
66
|
attr_reader :constant
|
|
68
67
|
|
|
69
|
-
|
|
68
|
+
#: (String symbol, Module constant) -> void
|
|
70
69
|
def initialize(symbol, constant)
|
|
71
70
|
super()
|
|
72
71
|
@symbol = symbol
|
|
@@ -77,10 +76,10 @@ module Tapioca
|
|
|
77
76
|
class ConstNodeAdded < NodeAdded
|
|
78
77
|
extend T::Sig
|
|
79
78
|
|
|
80
|
-
|
|
79
|
+
#: RBI::Const
|
|
81
80
|
attr_reader :node
|
|
82
81
|
|
|
83
|
-
|
|
82
|
+
#: (String symbol, Module constant, RBI::Const node) -> void
|
|
84
83
|
def initialize(symbol, constant, node)
|
|
85
84
|
super(symbol, constant)
|
|
86
85
|
@node = node
|
|
@@ -90,10 +89,10 @@ module Tapioca
|
|
|
90
89
|
class ScopeNodeAdded < NodeAdded
|
|
91
90
|
extend T::Sig
|
|
92
91
|
|
|
93
|
-
|
|
92
|
+
#: RBI::Scope
|
|
94
93
|
attr_reader :node
|
|
95
94
|
|
|
96
|
-
|
|
95
|
+
#: (String symbol, Module constant, RBI::Scope node) -> void
|
|
97
96
|
def initialize(symbol, constant, node)
|
|
98
97
|
super(symbol, constant)
|
|
99
98
|
@node = node
|
|
@@ -105,28 +104,19 @@ module Tapioca
|
|
|
105
104
|
class MethodNodeAdded < NodeAdded
|
|
106
105
|
extend T::Sig
|
|
107
106
|
|
|
108
|
-
|
|
107
|
+
#: UnboundMethod
|
|
109
108
|
attr_reader :method
|
|
110
109
|
|
|
111
|
-
|
|
110
|
+
#: RBI::Method
|
|
112
111
|
attr_reader :node
|
|
113
112
|
|
|
114
|
-
|
|
113
|
+
#: untyped
|
|
115
114
|
attr_reader :signature
|
|
116
115
|
|
|
117
|
-
|
|
116
|
+
#: Array[[Symbol, String]]
|
|
118
117
|
attr_reader :parameters
|
|
119
118
|
|
|
120
|
-
|
|
121
|
-
params(
|
|
122
|
-
symbol: String,
|
|
123
|
-
constant: Module,
|
|
124
|
-
method: UnboundMethod,
|
|
125
|
-
node: RBI::Method,
|
|
126
|
-
signature: T.untyped,
|
|
127
|
-
parameters: T::Array[[Symbol, String]],
|
|
128
|
-
).void.checked(:never)
|
|
129
|
-
end
|
|
119
|
+
#: (String symbol, Module constant, UnboundMethod method, RBI::Method node, untyped signature, Array[[Symbol, String]] parameters) -> void
|
|
130
120
|
def initialize(symbol, constant, method, node, signature, parameters) # rubocop:disable Metrics/ParameterLists
|
|
131
121
|
super(symbol, constant)
|
|
132
122
|
@node = node
|