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
|
@@ -63,13 +63,13 @@ module Tapioca
|
|
|
63
63
|
# end
|
|
64
64
|
#
|
|
65
65
|
# ~~~
|
|
66
|
+
#: [ConstantType = (singleton(ActiveRecord::Base) & Extensions::ActiveRecord)]
|
|
66
67
|
class ActiveRecordDelegatedTypes < Compiler
|
|
67
68
|
extend T::Sig
|
|
68
69
|
include Helpers::ActiveRecordConstantsHelper
|
|
69
70
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
sig { override.void }
|
|
71
|
+
# @override
|
|
72
|
+
#: -> void
|
|
73
73
|
def decorate
|
|
74
74
|
return if constant.__tapioca_delegated_types.nil?
|
|
75
75
|
|
|
@@ -90,7 +90,8 @@ module Tapioca
|
|
|
90
90
|
class << self
|
|
91
91
|
extend T::Sig
|
|
92
92
|
|
|
93
|
-
|
|
93
|
+
# @override
|
|
94
|
+
#: -> T::Enumerable[Module]
|
|
94
95
|
def gather_constants
|
|
95
96
|
descendants_of(::ActiveRecord::Base).reject(&:abstract_class?)
|
|
96
97
|
end
|
|
@@ -98,7 +99,7 @@ module Tapioca
|
|
|
98
99
|
|
|
99
100
|
private
|
|
100
101
|
|
|
101
|
-
|
|
102
|
+
#: (RBI::Scope mod, Symbol role, Array[String] types) -> void
|
|
102
103
|
def populate_role_accessors(mod, role, types)
|
|
103
104
|
mod.create_method(
|
|
104
105
|
"#{role}_name",
|
|
@@ -115,18 +116,18 @@ module Tapioca
|
|
|
115
116
|
mod.create_method(
|
|
116
117
|
"build_#{role}",
|
|
117
118
|
parameters: [create_rest_param("args", type: "T.untyped")],
|
|
118
|
-
return_type: "T.any(#{types.join(", ")})",
|
|
119
|
+
return_type: types.size == 1 ? types.first : "T.any(#{types.join(", ")})",
|
|
119
120
|
)
|
|
120
121
|
end
|
|
121
122
|
|
|
122
|
-
|
|
123
|
+
#: (RBI::Scope mod, Symbol role, Array[String] types, Hash[Symbol, untyped] options) -> void
|
|
123
124
|
def populate_type_helpers(mod, role, types, options)
|
|
124
125
|
types.each do |type|
|
|
125
126
|
populate_type_helper(mod, role, type, options)
|
|
126
127
|
end
|
|
127
128
|
end
|
|
128
129
|
|
|
129
|
-
|
|
130
|
+
#: (RBI::Scope mod, Symbol role, String type, Hash[Symbol, untyped] options) -> void
|
|
130
131
|
def populate_type_helper(mod, role, type, options)
|
|
131
132
|
singular = type.tableize.tr("/", "_").singularize
|
|
132
133
|
query = "#{singular}?"
|
|
@@ -49,12 +49,12 @@ module Tapioca
|
|
|
49
49
|
# end
|
|
50
50
|
# end
|
|
51
51
|
# ~~~
|
|
52
|
+
#: [ConstantType = singleton(::ActiveRecord::Base)]
|
|
52
53
|
class ActiveRecordEnum < Compiler
|
|
53
54
|
extend T::Sig
|
|
54
55
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
sig { override.void }
|
|
56
|
+
# @override
|
|
57
|
+
#: -> void
|
|
58
58
|
def decorate
|
|
59
59
|
return if constant.defined_enums.empty?
|
|
60
60
|
|
|
@@ -77,7 +77,8 @@ module Tapioca
|
|
|
77
77
|
class << self
|
|
78
78
|
extend T::Sig
|
|
79
79
|
|
|
80
|
-
|
|
80
|
+
# @override
|
|
81
|
+
#: -> T::Enumerable[Module]
|
|
81
82
|
def gather_constants
|
|
82
83
|
descendants_of(::ActiveRecord::Base)
|
|
83
84
|
end
|
|
@@ -85,7 +86,7 @@ module Tapioca
|
|
|
85
86
|
|
|
86
87
|
private
|
|
87
88
|
|
|
88
|
-
|
|
89
|
+
#: (Hash[untyped, untyped] enum_map) -> String
|
|
89
90
|
def type_for_enum(enum_map)
|
|
90
91
|
value_type = enum_map.values.map { |v| v.class.name }.uniq
|
|
91
92
|
value_type = if value_type.length == 1
|
|
@@ -97,7 +98,7 @@ module Tapioca
|
|
|
97
98
|
"T::Hash[T.any(String, Symbol), #{value_type}]"
|
|
98
99
|
end
|
|
99
100
|
|
|
100
|
-
|
|
101
|
+
#: (RBI::Scope klass) -> void
|
|
101
102
|
def generate_instance_methods(klass)
|
|
102
103
|
methods = constant.send(:_enum_methods_module).instance_methods
|
|
103
104
|
|
|
@@ -33,13 +33,14 @@ module Tapioca
|
|
|
33
33
|
# def posts(fixture_name = nil, *other_fixtures); end
|
|
34
34
|
# end
|
|
35
35
|
# ~~~
|
|
36
|
+
#: [ConstantType = singleton(ActiveSupport::TestCase)]
|
|
36
37
|
class ActiveRecordFixtures < Compiler
|
|
37
38
|
extend T::Sig
|
|
38
39
|
|
|
39
|
-
ConstantType = type_member { { fixed: T.class_of(ActiveSupport::TestCase) } }
|
|
40
40
|
MISSING = Object.new
|
|
41
41
|
|
|
42
|
-
|
|
42
|
+
# @override
|
|
43
|
+
#: -> void
|
|
43
44
|
def decorate
|
|
44
45
|
method_names = if fixture_loader.respond_to?(:fixture_sets)
|
|
45
46
|
method_names_from_lazy_fixture_loader
|
|
@@ -60,7 +61,8 @@ module Tapioca
|
|
|
60
61
|
class << self
|
|
61
62
|
extend T::Sig
|
|
62
63
|
|
|
63
|
-
|
|
64
|
+
# @override
|
|
65
|
+
#: -> T::Enumerable[Module]
|
|
64
66
|
def gather_constants
|
|
65
67
|
return [] unless defined?(Rails.application) && Rails.application
|
|
66
68
|
|
|
@@ -70,35 +72,32 @@ module Tapioca
|
|
|
70
72
|
|
|
71
73
|
private
|
|
72
74
|
|
|
73
|
-
|
|
75
|
+
#: -> Class[ActiveRecord::TestFixtures]
|
|
74
76
|
def fixture_loader
|
|
75
|
-
@fixture_loader ||=
|
|
76
|
-
|
|
77
|
-
T.unsafe(self).include(ActiveRecord::TestFixtures)
|
|
78
|
-
|
|
79
|
-
if respond_to?(:fixture_paths=)
|
|
80
|
-
T.unsafe(self).fixture_paths = [Rails.root.join("test", "fixtures")]
|
|
81
|
-
else
|
|
82
|
-
T.unsafe(self).fixture_path = Rails.root.join("test", "fixtures")
|
|
83
|
-
end
|
|
77
|
+
@fixture_loader ||= Class.new do
|
|
78
|
+
T.unsafe(self).include(ActiveRecord::TestFixtures)
|
|
84
79
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
80
|
+
if respond_to?(:fixture_paths=)
|
|
81
|
+
T.unsafe(self).fixture_paths = [Rails.root.join("test", "fixtures")]
|
|
82
|
+
else
|
|
83
|
+
T.unsafe(self).fixture_path = Rails.root.join("test", "fixtures")
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
# https://github.com/rails/rails/blob/7c70791470fc517deb7c640bead9f1b47efb5539/activerecord/lib/active_record/test_fixtures.rb#L46
|
|
87
|
+
singleton_class.define_method(:file_fixture_path) do
|
|
88
|
+
Rails.root.join("test", "fixtures", "files")
|
|
89
|
+
end
|
|
89
90
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
T.nilable(T::Class[ActiveRecord::TestFixtures]),
|
|
93
|
-
)
|
|
91
|
+
T.unsafe(self).fixtures(:all)
|
|
92
|
+
end #: Class[ActiveRecord::TestFixtures]?
|
|
94
93
|
end
|
|
95
94
|
|
|
96
|
-
|
|
95
|
+
#: -> Array[String]
|
|
97
96
|
def method_names_from_lazy_fixture_loader
|
|
98
97
|
T.unsafe(fixture_loader).fixture_sets.keys
|
|
99
98
|
end
|
|
100
99
|
|
|
101
|
-
|
|
100
|
+
#: -> Array[String]
|
|
102
101
|
def method_names_from_eager_fixture_loader
|
|
103
102
|
fixture_loader.ancestors # get all ancestors from class that includes AR fixtures
|
|
104
103
|
.drop(1) # drop the anonymous class itself from the array
|
|
@@ -108,7 +107,7 @@ module Tapioca
|
|
|
108
107
|
end
|
|
109
108
|
end
|
|
110
109
|
|
|
111
|
-
|
|
110
|
+
#: (RBI::Scope mod, String name) -> void
|
|
112
111
|
def create_fixture_method(mod, name)
|
|
113
112
|
return_type = return_type_for_fixture(name)
|
|
114
113
|
mod.create_method(name) do |node|
|
|
@@ -135,7 +134,7 @@ module Tapioca
|
|
|
135
134
|
end
|
|
136
135
|
end
|
|
137
136
|
|
|
138
|
-
|
|
137
|
+
#: (String fixture_name) -> String
|
|
139
138
|
def return_type_for_fixture(fixture_name)
|
|
140
139
|
fixture_class_mapping_from_fixture_files[fixture_name] ||
|
|
141
140
|
fixture_class_from_fixture_set(fixture_name) ||
|
|
@@ -143,7 +142,7 @@ module Tapioca
|
|
|
143
142
|
"T.untyped"
|
|
144
143
|
end
|
|
145
144
|
|
|
146
|
-
|
|
145
|
+
#: (String fixture_name) -> String?
|
|
147
146
|
def fixture_class_from_fixture_set(fixture_name)
|
|
148
147
|
# only rails 7.1+ support fixture sets so this is conditional
|
|
149
148
|
return unless fixture_loader.respond_to?(:fixture_sets)
|
|
@@ -157,54 +156,47 @@ module Tapioca
|
|
|
157
156
|
model_name
|
|
158
157
|
end
|
|
159
158
|
|
|
160
|
-
|
|
159
|
+
#: -> Hash[String, String]
|
|
161
160
|
def fixture_class_from_active_record_base_class_mapping
|
|
162
|
-
@fixture_class_mapping ||=
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
class_name = model_class.name
|
|
161
|
+
@fixture_class_mapping ||=
|
|
162
|
+
ActiveRecord::Base.descendants.each_with_object({}) do |model_class, mapping|
|
|
163
|
+
class_name = model_class.name
|
|
166
164
|
|
|
167
|
-
|
|
168
|
-
|
|
165
|
+
fixture_name = class_name.underscore.gsub("/", "_")
|
|
166
|
+
fixture_name = fixture_name.pluralize if ActiveRecord::Base.pluralize_table_names
|
|
169
167
|
|
|
170
|
-
|
|
168
|
+
mapping[fixture_name] = class_name
|
|
171
169
|
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
end,
|
|
175
|
-
T.nilable(T::Hash[String, String]),
|
|
176
|
-
)
|
|
170
|
+
mapping
|
|
171
|
+
end #: Hash[String, String]?
|
|
177
172
|
end
|
|
178
173
|
|
|
179
|
-
|
|
174
|
+
#: -> Hash[String, String]
|
|
180
175
|
def fixture_class_mapping_from_fixture_files
|
|
181
|
-
@fixture_file_class_mapping ||=
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
end
|
|
176
|
+
@fixture_file_class_mapping ||= begin
|
|
177
|
+
fixture_paths = if T.unsafe(fixture_loader).respond_to?(:fixture_paths)
|
|
178
|
+
T.unsafe(fixture_loader).fixture_paths
|
|
179
|
+
else
|
|
180
|
+
T.unsafe(fixture_loader).fixture_path
|
|
181
|
+
end
|
|
188
182
|
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
183
|
+
Array(fixture_paths).each_with_object({}) do |path, mapping|
|
|
184
|
+
Dir["#{path}{.yml,/{**,*}/*.yml}"].select do |file|
|
|
185
|
+
next unless ::File.file?(file)
|
|
192
186
|
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
187
|
+
ActiveRecord::FixtureSet::File.open(file) do |fh|
|
|
188
|
+
fixture_name = file.delete_prefix(path.to_s).delete_prefix("/").delete_suffix(".yml")
|
|
189
|
+
next unless fh.model_class
|
|
196
190
|
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
end
|
|
191
|
+
mapping[fixture_name] = fh.model_class
|
|
192
|
+
rescue ActiveRecord::Fixture::FormatError
|
|
193
|
+
# For fixtures that are not associated to any models and just contain raw data or fixtures that
|
|
194
|
+
# contain invalid formatting, we want to skip them and avoid crashing
|
|
195
|
+
mapping[fixture_name] = MISSING
|
|
203
196
|
end
|
|
204
197
|
end
|
|
205
|
-
end
|
|
206
|
-
|
|
207
|
-
)
|
|
198
|
+
end
|
|
199
|
+
end #: Hash[String, String]?
|
|
208
200
|
end
|
|
209
201
|
end
|
|
210
202
|
end
|