tapioca 0.6.4 → 0.7.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile +8 -2
- data/README.md +27 -15
- data/Rakefile +10 -14
- data/lib/tapioca/cli.rb +65 -80
- data/lib/tapioca/{generators/base.rb → commands/command.rb} +16 -9
- data/lib/tapioca/{generators → commands}/dsl.rb +59 -45
- data/lib/tapioca/{generators → commands}/gem.rb +93 -30
- data/lib/tapioca/{generators → commands}/init.rb +9 -13
- data/lib/tapioca/{generators → commands}/require.rb +8 -10
- data/lib/tapioca/commands/todo.rb +84 -0
- data/lib/tapioca/commands.rb +13 -0
- data/lib/tapioca/dsl/compiler.rb +185 -0
- data/lib/tapioca/{compilers/dsl → dsl/compilers}/aasm.rb +12 -9
- data/lib/tapioca/{compilers/dsl → dsl/compilers}/action_controller_helpers.rb +13 -20
- data/lib/tapioca/{compilers/dsl → dsl/compilers}/action_mailer.rb +10 -8
- data/lib/tapioca/{compilers/dsl → dsl/compilers}/active_job.rb +11 -9
- data/lib/tapioca/{compilers/dsl → dsl/compilers}/active_model_attributes.rb +13 -11
- data/lib/tapioca/{compilers/dsl → dsl/compilers}/active_model_secure_password.rb +10 -12
- data/lib/tapioca/{compilers/dsl → dsl/compilers}/active_record_associations.rb +28 -34
- data/lib/tapioca/{compilers/dsl → dsl/compilers}/active_record_columns.rb +18 -16
- data/lib/tapioca/{compilers/dsl → dsl/compilers}/active_record_enum.rb +14 -12
- data/lib/tapioca/{compilers/dsl → dsl/compilers}/active_record_fixtures.rb +10 -8
- data/lib/tapioca/dsl/compilers/active_record_relations.rb +712 -0
- data/lib/tapioca/{compilers/dsl → dsl/compilers}/active_record_scope.rb +21 -20
- data/lib/tapioca/{compilers/dsl → dsl/compilers}/active_record_typed_store.rb +11 -16
- data/lib/tapioca/{compilers/dsl → dsl/compilers}/active_resource.rb +10 -8
- data/lib/tapioca/{compilers/dsl → dsl/compilers}/active_storage.rb +11 -11
- data/lib/tapioca/{compilers/dsl → dsl/compilers}/active_support_concern.rb +19 -14
- data/lib/tapioca/{compilers/dsl → dsl/compilers}/active_support_current_attributes.rb +16 -21
- data/lib/tapioca/{compilers/dsl → dsl/compilers}/config.rb +10 -8
- data/lib/tapioca/{compilers/dsl → dsl/compilers}/frozen_record.rb +13 -11
- data/lib/tapioca/{compilers/dsl → dsl/compilers}/identity_cache.rb +23 -22
- data/lib/tapioca/{compilers/dsl → dsl/compilers}/mixed_in_class_attributes.rb +12 -10
- data/lib/tapioca/{compilers/dsl → dsl/compilers}/protobuf.rb +10 -8
- data/lib/tapioca/{compilers/dsl → dsl/compilers}/rails_generators.rb +12 -13
- data/lib/tapioca/{compilers/dsl → dsl/compilers}/sidekiq_worker.rb +14 -13
- data/lib/tapioca/{compilers/dsl → dsl/compilers}/smart_properties.rb +11 -9
- data/lib/tapioca/{compilers/dsl → dsl/compilers}/state_machines.rb +12 -10
- data/lib/tapioca/{compilers/dsl → dsl/compilers}/url_helpers.rb +16 -14
- data/lib/tapioca/dsl/compilers.rb +31 -0
- data/lib/tapioca/{compilers/dsl → dsl}/extensions/frozen_record.rb +2 -2
- data/lib/tapioca/dsl/helpers/active_record_column_type_helper.rb +114 -0
- data/lib/tapioca/dsl/helpers/active_record_constants_helper.rb +29 -0
- data/lib/tapioca/{compilers/dsl → dsl/helpers}/param_helper.rb +2 -2
- data/lib/tapioca/{compilers/dsl_compiler.rb → dsl/pipeline.rb} +41 -33
- data/lib/tapioca/gem/events.rb +120 -0
- data/lib/tapioca/gem/listeners/base.rb +48 -0
- data/lib/tapioca/gem/listeners/dynamic_mixins.rb +32 -0
- data/lib/tapioca/gem/listeners/methods.rb +183 -0
- data/lib/tapioca/gem/listeners/mixins.rb +101 -0
- data/lib/tapioca/gem/listeners/remove_empty_payload_scopes.rb +21 -0
- data/lib/tapioca/gem/listeners/sorbet_enums.rb +26 -0
- data/lib/tapioca/gem/listeners/sorbet_helpers.rb +29 -0
- data/lib/tapioca/gem/listeners/sorbet_props.rb +33 -0
- data/lib/tapioca/gem/listeners/sorbet_required_ancestors.rb +23 -0
- data/lib/tapioca/gem/listeners/sorbet_signatures.rb +79 -0
- data/lib/tapioca/gem/listeners/sorbet_type_variables.rb +51 -0
- data/lib/tapioca/gem/listeners/subconstants.rb +37 -0
- data/lib/tapioca/gem/listeners/yard_doc.rb +96 -0
- data/lib/tapioca/gem/listeners.rb +16 -0
- data/lib/tapioca/gem/pipeline.rb +365 -0
- data/lib/tapioca/helpers/cli_helper.rb +7 -0
- data/lib/tapioca/helpers/config_helper.rb +5 -8
- data/lib/tapioca/helpers/rbi_helper.rb +17 -0
- data/lib/tapioca/helpers/shims_helper.rb +87 -0
- data/lib/tapioca/helpers/sorbet_helper.rb +57 -0
- data/lib/tapioca/helpers/test/dsl_compiler.rb +118 -0
- data/lib/tapioca/helpers/test/isolation.rb +1 -1
- data/lib/tapioca/helpers/test/template.rb +13 -2
- data/lib/tapioca/internal.rb +17 -10
- data/lib/tapioca/rbi_ext/model.rb +2 -48
- data/lib/tapioca/rbi_formatter.rb +37 -0
- data/lib/tapioca/runtime/dynamic_mixin_compiler.rb +227 -0
- data/lib/tapioca/runtime/generic_type_registry.rb +166 -0
- data/lib/tapioca/runtime/loader.rb +123 -0
- data/lib/tapioca/runtime/reflection.rb +153 -0
- data/lib/tapioca/runtime/trackers/autoload.rb +72 -0
- data/lib/tapioca/runtime/trackers/constant_definition.rb +44 -0
- data/lib/tapioca/runtime/trackers/mixin.rb +80 -0
- data/lib/tapioca/runtime/trackers/required_ancestor.rb +50 -0
- data/lib/tapioca/{trackers.rb → runtime/trackers.rb} +4 -3
- data/lib/tapioca/sorbet_ext/generic_name_patch.rb +33 -15
- data/lib/tapioca/sorbet_ext/name_patch.rb +7 -1
- data/lib/tapioca/{compilers → static}/requires_compiler.rb +2 -2
- data/lib/tapioca/static/symbol_loader.rb +83 -0
- data/lib/tapioca/static/symbol_table_parser.rb +63 -0
- data/lib/tapioca/version.rb +1 -1
- data/lib/tapioca.rb +2 -7
- metadata +80 -60
- data/lib/tapioca/compilers/dsl/active_record_relations.rb +0 -720
- data/lib/tapioca/compilers/dsl/base.rb +0 -195
- data/lib/tapioca/compilers/dsl/helper/active_record_constants.rb +0 -27
- data/lib/tapioca/compilers/dynamic_mixin_compiler.rb +0 -223
- data/lib/tapioca/compilers/sorbet.rb +0 -59
- data/lib/tapioca/compilers/symbol_table/symbol_generator.rb +0 -780
- data/lib/tapioca/compilers/symbol_table/symbol_loader.rb +0 -90
- data/lib/tapioca/compilers/symbol_table_compiler.rb +0 -17
- data/lib/tapioca/compilers/todos_compiler.rb +0 -32
- data/lib/tapioca/generators/todo.rb +0 -76
- data/lib/tapioca/generators.rb +0 -9
- data/lib/tapioca/generic_type_registry.rb +0 -164
- data/lib/tapioca/helpers/active_record_column_type_helper.rb +0 -108
- data/lib/tapioca/loader.rb +0 -119
- data/lib/tapioca/reflection.rb +0 -151
- data/lib/tapioca/trackers/autoload.rb +0 -70
- data/lib/tapioca/trackers/constant_definition.rb +0 -42
- data/lib/tapioca/trackers/mixin.rb +0 -78
@@ -7,12 +7,12 @@ rescue LoadError
|
|
7
7
|
return
|
8
8
|
end
|
9
9
|
|
10
|
-
require "tapioca/
|
10
|
+
require "tapioca/dsl/helpers/active_record_constants_helper"
|
11
11
|
|
12
12
|
module Tapioca
|
13
|
-
module
|
14
|
-
module
|
15
|
-
# `Tapioca::Compilers::
|
13
|
+
module Dsl
|
14
|
+
module Compilers
|
15
|
+
# `Tapioca::Dsl::Compilers::ActiveRecordScope` decorates RBI files for
|
16
16
|
# subclasses of `ActiveRecord::Base` which declare
|
17
17
|
# [`scope` fields](https://api.rubyonrails.org/classes/ActiveRecord/Scoping/Named/ClassMethods.html#method-i-scope).
|
18
18
|
#
|
@@ -25,7 +25,7 @@ module Tapioca
|
|
25
25
|
# end
|
26
26
|
# ~~~
|
27
27
|
#
|
28
|
-
# this
|
28
|
+
# this compiler will produce the RBI file `post.rbi` with the following content:
|
29
29
|
#
|
30
30
|
# ~~~rbi
|
31
31
|
# # post.rbi
|
@@ -42,23 +42,20 @@ module Tapioca
|
|
42
42
|
# end
|
43
43
|
# end
|
44
44
|
# ~~~
|
45
|
-
class ActiveRecordScope <
|
45
|
+
class ActiveRecordScope < Compiler
|
46
46
|
extend T::Sig
|
47
|
-
include
|
47
|
+
include Helpers::ActiveRecordConstantsHelper
|
48
48
|
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
end
|
55
|
-
def decorate(root, constant)
|
56
|
-
method_names = scope_method_names(constant)
|
49
|
+
ConstantType = type_member(fixed: T.class_of(::ActiveRecord::Base))
|
50
|
+
|
51
|
+
sig { override.void }
|
52
|
+
def decorate
|
53
|
+
method_names = scope_method_names
|
57
54
|
|
58
55
|
return if method_names.empty?
|
59
56
|
|
60
57
|
root.create_path(constant) do |model|
|
61
|
-
relations_enabled =
|
58
|
+
relations_enabled = compiler_enabled?("ActiveRecordRelations")
|
62
59
|
|
63
60
|
relation_methods_module = model.create_module(RelationMethodsModuleName)
|
64
61
|
assoc_relation_methods_mod = model.create_module(AssociationRelationMethodsModuleName) if relations_enabled
|
@@ -84,22 +81,26 @@ module Tapioca
|
|
84
81
|
end
|
85
82
|
|
86
83
|
sig { override.returns(T::Enumerable[Module]) }
|
87
|
-
def gather_constants
|
84
|
+
def self.gather_constants
|
88
85
|
descendants_of(::ActiveRecord::Base).reject(&:abstract_class?)
|
89
86
|
end
|
90
87
|
|
91
88
|
private
|
92
89
|
|
93
|
-
sig {
|
94
|
-
def scope_method_names
|
90
|
+
sig { returns(T::Array[Symbol]) }
|
91
|
+
def scope_method_names
|
95
92
|
scope_methods = T.let([], T::Array[Symbol])
|
93
|
+
constant = self.constant
|
96
94
|
|
97
95
|
# Keep gathering scope methods until we hit "ActiveRecord::Base"
|
98
96
|
until constant == ActiveRecord::Base
|
99
97
|
scope_methods.concat(constant.send(:generated_relation_methods).instance_methods(false))
|
100
98
|
|
99
|
+
superclass = superclass_of(constant)
|
100
|
+
break unless superclass
|
101
|
+
|
101
102
|
# we are guaranteed to have a superclass that is of type "ActiveRecord::Base"
|
102
|
-
constant = T.cast(
|
103
|
+
constant = T.cast(superclass, T.class_of(ActiveRecord::Base))
|
103
104
|
end
|
104
105
|
|
105
106
|
scope_methods
|
@@ -5,14 +5,14 @@ begin
|
|
5
5
|
require "activerecord-typedstore"
|
6
6
|
rescue LoadError
|
7
7
|
# means ActiveRecord::TypedStore is not installed,
|
8
|
-
# so let's not even define the
|
8
|
+
# so let's not even define the compiler.
|
9
9
|
return
|
10
10
|
end
|
11
11
|
|
12
12
|
module Tapioca
|
13
|
-
module
|
14
|
-
module
|
15
|
-
# `Tapioca::Compilers::
|
13
|
+
module Dsl
|
14
|
+
module Compilers
|
15
|
+
# `Tapioca::Dsl::Compilers::ActiveRecordTypedStore` generates RBI files for Active Record models that use
|
16
16
|
# [`ActiveRecord::TypedStore`](https://github.com/byroot/activerecord-typedstore) features.
|
17
17
|
#
|
18
18
|
# For example, with the following ActiveRecord class:
|
@@ -28,7 +28,7 @@ module Tapioca
|
|
28
28
|
# end
|
29
29
|
# ~~~
|
30
30
|
#
|
31
|
-
# this
|
31
|
+
# this compiler will produce the RBI file `post.rbi` with the following content:
|
32
32
|
#
|
33
33
|
# ~~~rbi
|
34
34
|
# # post.rbi
|
@@ -87,18 +87,13 @@ module Tapioca
|
|
87
87
|
# end
|
88
88
|
# end
|
89
89
|
# ~~~
|
90
|
-
class ActiveRecordTypedStore <
|
90
|
+
class ActiveRecordTypedStore < Compiler
|
91
91
|
extend T::Sig
|
92
92
|
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
constant: T.class_of(::ActiveRecord::Base)
|
98
|
-
)
|
99
|
-
.void
|
100
|
-
end
|
101
|
-
def decorate(root, constant)
|
93
|
+
ConstantType = type_member(fixed: T.class_of(::ActiveRecord::Base))
|
94
|
+
|
95
|
+
sig { override.void }
|
96
|
+
def decorate
|
102
97
|
stores = constant.typed_stores
|
103
98
|
return if stores.values.flat_map(&:accessors).empty?
|
104
99
|
|
@@ -118,7 +113,7 @@ module Tapioca
|
|
118
113
|
end
|
119
114
|
|
120
115
|
sig { override.returns(T::Enumerable[Module]) }
|
121
|
-
def gather_constants
|
116
|
+
def self.gather_constants
|
122
117
|
descendants_of(::ActiveRecord::Base).select do |klass|
|
123
118
|
klass.include?(ActiveRecord::TypedStore::Behavior)
|
124
119
|
end
|
@@ -8,9 +8,9 @@ rescue LoadError
|
|
8
8
|
end
|
9
9
|
|
10
10
|
module Tapioca
|
11
|
-
module
|
12
|
-
module
|
13
|
-
# `Tapioca::Compilers::
|
11
|
+
module Dsl
|
12
|
+
module Compilers
|
13
|
+
# `Tapioca::Dsl::Compilers::ActiveResource` decorates RBI files for subclasses of
|
14
14
|
# [`ActiveResource::Base`](https://github.com/rails/activeresource) which declare
|
15
15
|
# `schema` fields.
|
16
16
|
#
|
@@ -24,7 +24,7 @@ module Tapioca
|
|
24
24
|
# end
|
25
25
|
# ~~~
|
26
26
|
#
|
27
|
-
# this
|
27
|
+
# this compiler will produce the RBI file `post.rbi` with the following content:
|
28
28
|
#
|
29
29
|
# ~~~rbi
|
30
30
|
# # post.rbi
|
@@ -58,11 +58,13 @@ module Tapioca
|
|
58
58
|
# def year?; end
|
59
59
|
# end
|
60
60
|
# ~~~
|
61
|
-
class ActiveResource <
|
61
|
+
class ActiveResource < Compiler
|
62
62
|
extend T::Sig
|
63
63
|
|
64
|
-
|
65
|
-
|
64
|
+
ConstantType = type_member(fixed: T.class_of(::ActiveResource::Base))
|
65
|
+
|
66
|
+
sig { override.void }
|
67
|
+
def decorate
|
66
68
|
return if constant.schema.blank?
|
67
69
|
|
68
70
|
root.create_path(constant) do |resource|
|
@@ -73,7 +75,7 @@ module Tapioca
|
|
73
75
|
end
|
74
76
|
|
75
77
|
sig { override.returns(T::Enumerable[Module]) }
|
76
|
-
def gather_constants
|
78
|
+
def self.gather_constants
|
77
79
|
descendants_of(::ActiveResource::Base)
|
78
80
|
end
|
79
81
|
|
@@ -9,9 +9,9 @@ rescue LoadError
|
|
9
9
|
end
|
10
10
|
|
11
11
|
module Tapioca
|
12
|
-
module
|
13
|
-
module
|
14
|
-
# `Tapioca::Compilers::
|
12
|
+
module Dsl
|
13
|
+
module Compilers
|
14
|
+
# `Tapioca::Dsl::Compilers::ActiveStorage` decorates RBI files for subclasses of
|
15
15
|
# `ActiveRecord::Base` that declare [one](https://edgeguides.rubyonrails.org/active_storage_overview.html#has-one-attached)
|
16
16
|
# or [many](https://edgeguides.rubyonrails.org/active_storage_overview.html#has-many-attached) attachments.
|
17
17
|
#
|
@@ -24,7 +24,7 @@ module Tapioca
|
|
24
24
|
# end
|
25
25
|
# ~~~
|
26
26
|
#
|
27
|
-
# this
|
27
|
+
# this compiler will produce the RBI file `post.rbi` with the following content:
|
28
28
|
#
|
29
29
|
# ~~~rbi
|
30
30
|
# # typed: strong
|
@@ -43,14 +43,14 @@ module Tapioca
|
|
43
43
|
# def photo=(attachable); end
|
44
44
|
# end
|
45
45
|
# ~~~
|
46
|
-
class ActiveStorage <
|
46
|
+
class ActiveStorage < Compiler
|
47
47
|
extend T::Sig
|
48
48
|
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
def decorate
|
49
|
+
ConstantType = type_member(fixed: T.all(Module,
|
50
|
+
::ActiveStorage::Reflection::ActiveRecordExtensions::ClassMethods))
|
51
|
+
|
52
|
+
sig { override.void }
|
53
|
+
def decorate
|
54
54
|
return if constant.reflect_on_all_attachments.empty?
|
55
55
|
|
56
56
|
root.create_path(constant) do |scope|
|
@@ -71,7 +71,7 @@ module Tapioca
|
|
71
71
|
end
|
72
72
|
|
73
73
|
sig { override.returns(T::Enumerable[Module]) }
|
74
|
-
def gather_constants
|
74
|
+
def self.gather_constants
|
75
75
|
descendants_of(::ActiveRecord::Base)
|
76
76
|
.reject(&:abstract_class?)
|
77
77
|
.grep(::ActiveStorage::Reflection::ActiveRecordExtensions::ClassMethods)
|
@@ -1,8 +1,6 @@
|
|
1
1
|
# typed: strict
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
|
-
require "tapioca/compilers/sorbet"
|
5
|
-
|
6
4
|
begin
|
7
5
|
require "active_support"
|
8
6
|
rescue LoadError
|
@@ -10,9 +8,9 @@ rescue LoadError
|
|
10
8
|
end
|
11
9
|
|
12
10
|
module Tapioca
|
13
|
-
module
|
14
|
-
module
|
15
|
-
# `Tapioca::Compilers::
|
11
|
+
module Dsl
|
12
|
+
module Compilers
|
13
|
+
# `Tapioca::Dsl::Compilers::ActiveSupportConcern` generates RBI files for classes that both `extend`
|
16
14
|
# `ActiveSupport::Concern` and `include` another class that extends `ActiveSupport::Concern`
|
17
15
|
#
|
18
16
|
# For example for the following hierarchy:
|
@@ -35,7 +33,7 @@ module Tapioca
|
|
35
33
|
# end
|
36
34
|
# ~~~
|
37
35
|
#
|
38
|
-
# this
|
36
|
+
# this compiler will produce the RBI file `concern.rbi` with the following content:
|
39
37
|
#
|
40
38
|
# ~~~rbi
|
41
39
|
# # typed: true
|
@@ -43,12 +41,14 @@ module Tapioca
|
|
43
41
|
# mixes_in_class_methods(::Foo::ClassMethods)
|
44
42
|
# end
|
45
43
|
# ~~~
|
46
|
-
class ActiveSupportConcern <
|
44
|
+
class ActiveSupportConcern < Compiler
|
47
45
|
extend T::Sig
|
48
46
|
|
49
|
-
|
50
|
-
|
51
|
-
|
47
|
+
ConstantType = type_member(fixed: Module)
|
48
|
+
|
49
|
+
sig { override.void }
|
50
|
+
def decorate
|
51
|
+
dependencies = linearized_dependencies
|
52
52
|
|
53
53
|
mixed_in_class_methods = dependencies
|
54
54
|
.uniq # Deduplicate
|
@@ -67,7 +67,7 @@ module Tapioca
|
|
67
67
|
end
|
68
68
|
|
69
69
|
sig { override.returns(T::Enumerable[Module]) }
|
70
|
-
def gather_constants
|
70
|
+
def self.gather_constants
|
71
71
|
# Find all Modules that are:
|
72
72
|
all_modules.select do |mod|
|
73
73
|
# named (i.e. not anonymous)
|
@@ -81,15 +81,20 @@ module Tapioca
|
|
81
81
|
end
|
82
82
|
end
|
83
83
|
|
84
|
+
sig { params(concern: Module).returns(T::Array[Module]) }
|
85
|
+
def self.dependencies_of(concern)
|
86
|
+
concern.instance_variable_get(:@_dependencies)
|
87
|
+
end
|
88
|
+
|
84
89
|
private
|
85
90
|
|
86
91
|
sig { params(concern: Module).returns(T::Array[Module]) }
|
87
92
|
def dependencies_of(concern)
|
88
|
-
|
93
|
+
self.class.dependencies_of(concern)
|
89
94
|
end
|
90
95
|
|
91
96
|
sig { params(concern: Module).returns(T::Array[Module]) }
|
92
|
-
def
|
97
|
+
def linearized_dependencies(concern = constant)
|
93
98
|
# Grab all the dependencies of the concern
|
94
99
|
dependencies = dependencies_of(concern)
|
95
100
|
|
@@ -97,7 +102,7 @@ module Tapioca
|
|
97
102
|
dependencies.flat_map do |dependency|
|
98
103
|
# Linearize dependencies of the current dependency,
|
99
104
|
# which, itself, is a concern
|
100
|
-
|
105
|
+
linearized_dependencies(dependency) << dependency
|
101
106
|
end
|
102
107
|
end
|
103
108
|
end
|
@@ -10,9 +10,9 @@ rescue LoadError
|
|
10
10
|
end
|
11
11
|
|
12
12
|
module Tapioca
|
13
|
-
module
|
14
|
-
module
|
15
|
-
# `Tapioca::Compilers::
|
13
|
+
module Dsl
|
14
|
+
module Compilers
|
15
|
+
# `Tapioca::Dsl::Compilers::ActiveSupportCurrentAttributes` decorates RBI files for all
|
16
16
|
# subclasses of
|
17
17
|
# [`ActiveSupport::CurrentAttributes`](https://api.rubyonrails.org/classes/ActiveSupport/CurrentAttributes.html).
|
18
18
|
#
|
@@ -35,7 +35,7 @@ module Tapioca
|
|
35
35
|
# end
|
36
36
|
# ~~~
|
37
37
|
#
|
38
|
-
# this
|
38
|
+
# this compiler will produce an RBI file with the following content:
|
39
39
|
# ~~~rbi
|
40
40
|
# # typed: true
|
41
41
|
#
|
@@ -59,20 +59,15 @@ module Tapioca
|
|
59
59
|
# def self.helper; end
|
60
60
|
# end
|
61
61
|
# ~~~
|
62
|
-
class ActiveSupportCurrentAttributes <
|
62
|
+
class ActiveSupportCurrentAttributes < Compiler
|
63
63
|
extend T::Sig
|
64
64
|
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
.void
|
72
|
-
end
|
73
|
-
def decorate(root, constant)
|
74
|
-
dynamic_methods = dynamic_methods_for(constant)
|
75
|
-
instance_methods = instance_methods_for(constant) - dynamic_methods
|
65
|
+
ConstantType = type_member(fixed: T.class_of(::ActiveSupport::CurrentAttributes))
|
66
|
+
|
67
|
+
sig { override.void }
|
68
|
+
def decorate
|
69
|
+
dynamic_methods = dynamic_methods_of_constant
|
70
|
+
instance_methods = instance_methods_of_constant - dynamic_methods
|
76
71
|
return if dynamic_methods.empty? && instance_methods.empty?
|
77
72
|
|
78
73
|
root.create_path(constant) do |current_attributes|
|
@@ -94,19 +89,19 @@ module Tapioca
|
|
94
89
|
end
|
95
90
|
|
96
91
|
sig { override.returns(T::Enumerable[Module]) }
|
97
|
-
def gather_constants
|
92
|
+
def self.gather_constants
|
98
93
|
descendants_of(::ActiveSupport::CurrentAttributes)
|
99
94
|
end
|
100
95
|
|
101
96
|
private
|
102
97
|
|
103
|
-
sig {
|
104
|
-
def
|
98
|
+
sig { returns(T::Array[Symbol]) }
|
99
|
+
def dynamic_methods_of_constant
|
105
100
|
constant.instance_variable_get(:@generated_attribute_methods)&.instance_methods(false) || []
|
106
101
|
end
|
107
102
|
|
108
|
-
sig {
|
109
|
-
def
|
103
|
+
sig { returns(T::Array[Symbol]) }
|
104
|
+
def instance_methods_of_constant
|
110
105
|
constant.instance_methods(false)
|
111
106
|
end
|
112
107
|
|
@@ -8,9 +8,9 @@ rescue LoadError
|
|
8
8
|
end
|
9
9
|
|
10
10
|
module Tapioca
|
11
|
-
module
|
12
|
-
module
|
13
|
-
# `Tapioca::Compilers::
|
11
|
+
module Dsl
|
12
|
+
module Compilers
|
13
|
+
# `Tapioca::Dsl::Compilers::Config` generates RBI files for classes generated by the
|
14
14
|
# [`config`](https://github.com/rubyconfig/config) gem.
|
15
15
|
#
|
16
16
|
# The gem creates a `Config::Options` instance based on the settings files and/or
|
@@ -32,7 +32,7 @@ module Tapioca
|
|
32
32
|
# config.const_name = "AppSettings"
|
33
33
|
# end
|
34
34
|
# ```
|
35
|
-
# this
|
35
|
+
# this compiler will produce the following RBI file:
|
36
36
|
# ```rbi
|
37
37
|
# AppSettings = T.let(T.unsafe(nil), AppSettingsConfigOptions)
|
38
38
|
#
|
@@ -44,13 +44,15 @@ module Tapioca
|
|
44
44
|
# def github=(value); end
|
45
45
|
# end
|
46
46
|
# ```
|
47
|
-
class Config <
|
47
|
+
class Config < Compiler
|
48
48
|
extend T::Sig
|
49
49
|
|
50
50
|
CONFIG_OPTIONS_SUFFIX = "ConfigOptions"
|
51
51
|
|
52
|
-
|
53
|
-
|
52
|
+
ConstantType = type_member(fixed: Module)
|
53
|
+
|
54
|
+
sig { override.void }
|
55
|
+
def decorate
|
54
56
|
# The constant we are given is the specialized config options type
|
55
57
|
option_class_name = constant.name
|
56
58
|
return unless option_class_name
|
@@ -95,7 +97,7 @@ module Tapioca
|
|
95
97
|
end
|
96
98
|
|
97
99
|
sig { override.returns(T::Enumerable[Module]) }
|
98
|
-
def gather_constants
|
100
|
+
def self.gather_constants
|
99
101
|
name = ::Config.const_name
|
100
102
|
return [] unless Object.const_defined?(name)
|
101
103
|
|
@@ -8,9 +8,9 @@ rescue LoadError
|
|
8
8
|
end
|
9
9
|
|
10
10
|
module Tapioca
|
11
|
-
module
|
12
|
-
module
|
13
|
-
# `Tapioca::Compilers::
|
11
|
+
module Dsl
|
12
|
+
module Compilers
|
13
|
+
# `Tapioca::Dsl::Compilers::FrozenRecord` generates RBI files for subclasses of
|
14
14
|
# [`FrozenRecord::Base`](https://github.com/byroot/frozen_record).
|
15
15
|
#
|
16
16
|
# For example, with the following FrozenRecord class:
|
@@ -33,7 +33,7 @@ module Tapioca
|
|
33
33
|
# last_name: Lord
|
34
34
|
# ~~~
|
35
35
|
#
|
36
|
-
# this
|
36
|
+
# this compiler will produce the RBI file `student.rbi` with the following content:
|
37
37
|
#
|
38
38
|
# ~~~rbi
|
39
39
|
# # Student.rbi
|
@@ -62,11 +62,13 @@ module Tapioca
|
|
62
62
|
# end
|
63
63
|
# end
|
64
64
|
# ~~~
|
65
|
-
class FrozenRecord <
|
65
|
+
class FrozenRecord < Compiler
|
66
66
|
extend T::Sig
|
67
67
|
|
68
|
-
|
69
|
-
|
68
|
+
ConstantType = type_member(fixed: T.class_of(::FrozenRecord::Base))
|
69
|
+
|
70
|
+
sig { override.void }
|
71
|
+
def decorate
|
70
72
|
attributes = constant.attributes
|
71
73
|
return if attributes.empty?
|
72
74
|
|
@@ -82,19 +84,19 @@ module Tapioca
|
|
82
84
|
|
83
85
|
record.create_include(module_name)
|
84
86
|
|
85
|
-
decorate_scopes(
|
87
|
+
decorate_scopes(record)
|
86
88
|
end
|
87
89
|
end
|
88
90
|
|
89
91
|
sig { override.returns(T::Enumerable[Module]) }
|
90
|
-
def gather_constants
|
92
|
+
def self.gather_constants
|
91
93
|
descendants_of(::FrozenRecord::Base).reject(&:abstract_class?)
|
92
94
|
end
|
93
95
|
|
94
96
|
private
|
95
97
|
|
96
|
-
sig { params(
|
97
|
-
def decorate_scopes(
|
98
|
+
sig { params(record: RBI::Scope).void }
|
99
|
+
def decorate_scopes(record)
|
98
100
|
scopes = T.unsafe(constant).__tapioca_scope_names
|
99
101
|
return if scopes.nil?
|
100
102
|
|
@@ -5,14 +5,16 @@ begin
|
|
5
5
|
require "identity_cache"
|
6
6
|
rescue LoadError
|
7
7
|
# means IdentityCache is not installed,
|
8
|
-
# so let's not even define the
|
8
|
+
# so let's not even define the compiler.
|
9
9
|
return
|
10
10
|
end
|
11
11
|
|
12
|
+
require "tapioca/dsl/helpers/active_record_column_type_helper"
|
13
|
+
|
12
14
|
module Tapioca
|
13
|
-
module
|
14
|
-
module
|
15
|
-
# `Tapioca::Compilers::
|
15
|
+
module Dsl
|
16
|
+
module Compilers
|
17
|
+
# `Tapioca::Dsl::Compilers::IdentityCache` generates RBI files for Active Record models
|
16
18
|
# that use `include IdentityCache`.
|
17
19
|
# [`IdentityCache`](https://github.com/Shopify/identity_cache) is a blob level caching solution
|
18
20
|
# to plug into Active Record.
|
@@ -31,7 +33,7 @@ module Tapioca
|
|
31
33
|
# end
|
32
34
|
# ~~~
|
33
35
|
#
|
34
|
-
# this
|
36
|
+
# this compiler will produce the RBI file `post.rbi` with the following content:
|
35
37
|
#
|
36
38
|
# ~~~rbi
|
37
39
|
# # post.rbi
|
@@ -59,7 +61,7 @@ module Tapioca
|
|
59
61
|
# def fetch_by_title_and_review_date(title, review_date, includes: nil); end
|
60
62
|
# end
|
61
63
|
# ~~~
|
62
|
-
class IdentityCache <
|
64
|
+
class IdentityCache < Compiler
|
63
65
|
extend T::Sig
|
64
66
|
|
65
67
|
COLLECTION_TYPE = T.let(
|
@@ -67,8 +69,10 @@ module Tapioca
|
|
67
69
|
T.proc.params(type: T.any(Module, String)).returns(String)
|
68
70
|
)
|
69
71
|
|
70
|
-
|
71
|
-
|
72
|
+
ConstantType = type_member(fixed: T.class_of(::ActiveRecord::Base))
|
73
|
+
|
74
|
+
sig { override.void }
|
75
|
+
def decorate
|
72
76
|
caches = constant.send(:all_cached_associations)
|
73
77
|
cache_indexes = constant.send(:cache_indexes)
|
74
78
|
return if caches.empty? && cache_indexes.empty?
|
@@ -79,7 +83,7 @@ module Tapioca
|
|
79
83
|
cache_belongs = constant.send(:cached_belongs_tos)
|
80
84
|
|
81
85
|
cache_indexes.each do |field|
|
82
|
-
create_fetch_by_methods(field, model
|
86
|
+
create_fetch_by_methods(field, model)
|
83
87
|
end
|
84
88
|
|
85
89
|
cache_manys.values.each do |field|
|
@@ -97,7 +101,7 @@ module Tapioca
|
|
97
101
|
end
|
98
102
|
|
99
103
|
sig { override.returns(T::Enumerable[Module]) }
|
100
|
-
def gather_constants
|
104
|
+
def self.gather_constants
|
101
105
|
descendants_of(::ActiveRecord::Base).select do |klass|
|
102
106
|
klass < ::IdentityCache::WithoutPrimaryIndex
|
103
107
|
end
|
@@ -144,28 +148,26 @@ module Tapioca
|
|
144
148
|
sig do
|
145
149
|
params(
|
146
150
|
field: T.untyped,
|
147
|
-
klass: RBI::Scope
|
148
|
-
constant: T.class_of(::ActiveRecord::Base),
|
151
|
+
klass: RBI::Scope
|
149
152
|
).void
|
150
153
|
end
|
151
|
-
def create_fetch_by_methods(field, klass
|
154
|
+
def create_fetch_by_methods(field, klass)
|
152
155
|
is_cache_index = field.instance_variable_defined?(:@attribute_proc)
|
153
156
|
|
154
157
|
# Both `cache_index` and `cache_attribute` generate aliased methods
|
155
|
-
create_aliased_fetch_by_methods(field, klass
|
158
|
+
create_aliased_fetch_by_methods(field, klass)
|
156
159
|
|
157
160
|
# If the method used was `cache_index` a few extra methods are created
|
158
|
-
create_index_fetch_by_methods(field, klass
|
161
|
+
create_index_fetch_by_methods(field, klass) if is_cache_index
|
159
162
|
end
|
160
163
|
|
161
164
|
sig do
|
162
165
|
params(
|
163
166
|
field: T.untyped,
|
164
|
-
klass: RBI::Scope
|
165
|
-
constant: T.class_of(::ActiveRecord::Base),
|
167
|
+
klass: RBI::Scope
|
166
168
|
).void
|
167
169
|
end
|
168
|
-
def create_index_fetch_by_methods(field, klass
|
170
|
+
def create_index_fetch_by_methods(field, klass)
|
169
171
|
field_length = field.key_fields.length
|
170
172
|
fields_name = field.key_fields.join("_and_")
|
171
173
|
name = "fetch_by_#{fields_name}"
|
@@ -215,12 +217,11 @@ module Tapioca
|
|
215
217
|
sig do
|
216
218
|
params(
|
217
219
|
field: T.untyped,
|
218
|
-
klass: RBI::Scope
|
219
|
-
constant: T.class_of(::ActiveRecord::Base),
|
220
|
+
klass: RBI::Scope
|
220
221
|
).void
|
221
222
|
end
|
222
|
-
def create_aliased_fetch_by_methods(field, klass
|
223
|
-
type, _ = ActiveRecordColumnTypeHelper.new(constant).type_for(field.alias_name.to_s)
|
223
|
+
def create_aliased_fetch_by_methods(field, klass)
|
224
|
+
type, _ = Helpers::ActiveRecordColumnTypeHelper.new(constant).type_for(field.alias_name.to_s)
|
224
225
|
multi_type = type.delete_prefix("T.nilable(").delete_suffix(")").delete_prefix("::")
|
225
226
|
length = field.key_fields.length
|
226
227
|
suffix = field.send(:fetch_method_suffix)
|