tapioca 0.4.6 → 0.4.11
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/Gemfile +5 -1
- data/README.md +9 -7
- data/lib/tapioca/cli.rb +8 -1
- data/lib/tapioca/compilers/dsl/action_controller_helpers.rb +38 -39
- data/lib/tapioca/compilers/dsl/action_mailer.rb +4 -4
- data/lib/tapioca/compilers/dsl/active_record_associations.rb +52 -51
- data/lib/tapioca/compilers/dsl/active_record_columns.rb +60 -65
- data/lib/tapioca/compilers/dsl/active_record_enum.rb +27 -23
- data/lib/tapioca/compilers/dsl/active_record_scope.rb +18 -17
- data/lib/tapioca/compilers/dsl/active_record_typed_store.rb +8 -7
- data/lib/tapioca/compilers/dsl/active_resource.rb +5 -4
- data/lib/tapioca/compilers/dsl/active_support_current_attributes.rb +6 -7
- data/lib/tapioca/compilers/dsl/base.rb +14 -10
- data/lib/tapioca/compilers/dsl/frozen_record.rb +25 -25
- data/lib/tapioca/compilers/dsl/{active_record_identity_cache.rb → identity_cache.rb} +11 -10
- data/lib/tapioca/compilers/dsl/protobuf.rb +1 -1
- data/lib/tapioca/compilers/dsl/sidekiq_worker.rb +83 -0
- data/lib/tapioca/compilers/dsl/smart_properties.rb +1 -1
- data/lib/tapioca/compilers/dsl/state_machines.rb +75 -73
- data/lib/tapioca/compilers/dsl/url_helpers.rb +9 -5
- data/lib/tapioca/compilers/dsl_compiler.rb +5 -5
- data/lib/tapioca/compilers/requires_compiler.rb +34 -6
- data/lib/tapioca/compilers/sorbet.rb +1 -1
- data/lib/tapioca/compilers/symbol_table/symbol_generator.rb +69 -33
- data/lib/tapioca/compilers/symbol_table/symbol_loader.rb +1 -1
- data/lib/tapioca/compilers/symbol_table_compiler.rb +1 -1
- data/lib/tapioca/compilers/todos_compiler.rb +1 -1
- data/lib/tapioca/core_ext/class.rb +8 -3
- data/lib/tapioca/gemfile.rb +1 -1
- data/lib/tapioca/generator.rb +1 -1
- data/lib/tapioca/loader.rb +1 -1
- data/lib/tapioca/version.rb +1 -1
- metadata +4 -3
@@ -15,8 +15,7 @@ module Tapioca
|
|
15
15
|
module Compilers
|
16
16
|
module Dsl
|
17
17
|
# `Tapioca::Compilers::Dsl::ActiveRecordEnum` decorates RBI files for subclasses of
|
18
|
-
# `ActiveRecord::Base` which declare `enum` fields
|
19
|
-
# (see https://api.rubyonrails.org/classes/ActiveRecord/Enum.html).
|
18
|
+
# `ActiveRecord::Base` which declare [`enum` fields](https://api.rubyonrails.org/classes/ActiveRecord/Enum.html).
|
20
19
|
#
|
21
20
|
# For example, with the following `ActiveRecord::Base` subclass:
|
22
21
|
#
|
@@ -32,26 +31,30 @@ module Tapioca
|
|
32
31
|
# # post.rbi
|
33
32
|
# # typed: true
|
34
33
|
# class Post
|
35
|
-
#
|
36
|
-
# def all_title!; end
|
34
|
+
# include EnumMethodsModule
|
37
35
|
#
|
38
|
-
#
|
39
|
-
#
|
36
|
+
# module EnumMethodsModule
|
37
|
+
# sig { void }
|
38
|
+
# def all_title!; end
|
40
39
|
#
|
41
|
-
#
|
42
|
-
#
|
40
|
+
# sig { returns(T::Boolean) }
|
41
|
+
# def all_title?; end
|
43
42
|
#
|
44
|
-
#
|
45
|
-
#
|
43
|
+
# sig { returns(T::Hash[T.any(String, Symbol), Integer]) }
|
44
|
+
# def self.title_types; end
|
46
45
|
#
|
47
|
-
#
|
48
|
-
#
|
46
|
+
# sig { void }
|
47
|
+
# def book_title!; end
|
49
48
|
#
|
50
|
-
#
|
51
|
-
#
|
49
|
+
# sig { returns(T::Boolean) }
|
50
|
+
# def book_title?; end
|
52
51
|
#
|
53
|
-
#
|
54
|
-
#
|
52
|
+
# sig { void }
|
53
|
+
# def web_title!; end
|
54
|
+
#
|
55
|
+
# sig { returns(T::Boolean) }
|
56
|
+
# def web_title?; end
|
57
|
+
# end
|
55
58
|
# end
|
56
59
|
# ~~~
|
57
60
|
class ActiveRecordEnum < Base
|
@@ -61,17 +64,18 @@ module Tapioca
|
|
61
64
|
def decorate(root, constant)
|
62
65
|
return if constant.defined_enums.empty?
|
63
66
|
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
67
|
+
root.path(constant) do |model|
|
68
|
+
module_name = "EnumMethodsModule"
|
69
|
+
|
70
|
+
model.create_module(module_name) do |mod|
|
71
|
+
generate_instance_methods(constant, mod)
|
72
|
+
end
|
68
73
|
|
69
|
-
|
70
|
-
k.create_include(module_name)
|
74
|
+
model.create_include(module_name)
|
71
75
|
|
72
76
|
constant.defined_enums.each do |name, enum_map|
|
73
77
|
type = type_for_enum(enum_map)
|
74
|
-
create_method(
|
78
|
+
create_method(model, name.pluralize, class_method: true, return_type: type)
|
75
79
|
end
|
76
80
|
end
|
77
81
|
end
|
@@ -12,9 +12,9 @@ end
|
|
12
12
|
module Tapioca
|
13
13
|
module Compilers
|
14
14
|
module Dsl
|
15
|
-
# `Tapioca::Compilers::Dsl::ActiveRecordScope` decorates RBI files for
|
16
|
-
# `ActiveRecord::Base` which declare
|
17
|
-
# (
|
15
|
+
# `Tapioca::Compilers::Dsl::ActiveRecordScope` decorates RBI files for
|
16
|
+
# subclasses of `ActiveRecord::Base` which declare
|
17
|
+
# [`scope` fields](https://api.rubyonrails.org/classes/ActiveRecord/Scoping/Named/ClassMethods.html#method-i-scope).
|
18
18
|
#
|
19
19
|
# For example, with the following `ActiveRecord::Base` subclass:
|
20
20
|
#
|
@@ -31,15 +31,15 @@ module Tapioca
|
|
31
31
|
# # post.rbi
|
32
32
|
# # typed: true
|
33
33
|
# class Post
|
34
|
-
# extend
|
35
|
-
# end
|
34
|
+
# extend GeneratedRelationMethods
|
36
35
|
#
|
37
|
-
#
|
38
|
-
#
|
39
|
-
#
|
36
|
+
# module GeneratedRelationMethods
|
37
|
+
# sig { params(args: T.untyped, blk: T.untyped).returns(T.untyped) }
|
38
|
+
# def private_kind(*args, &blk); end
|
40
39
|
#
|
41
|
-
#
|
42
|
-
#
|
40
|
+
# sig { params(args: T.untyped, blk: T.untyped).returns(T.untyped) }
|
41
|
+
# def public_kind(*args, &blk); end
|
42
|
+
# end
|
43
43
|
# end
|
44
44
|
# ~~~
|
45
45
|
class ActiveRecordScope < Base
|
@@ -55,15 +55,16 @@ module Tapioca
|
|
55
55
|
scope_method_names = constant.send(:generated_relation_methods).instance_methods(false)
|
56
56
|
return if scope_method_names.empty?
|
57
57
|
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
58
|
+
root.path(constant) do |model|
|
59
|
+
module_name = "GeneratedRelationMethods"
|
60
|
+
|
61
|
+
model.create_module(module_name) do |mod|
|
62
|
+
scope_method_names.each do |scope_method|
|
63
|
+
generate_scope_method(scope_method, mod)
|
64
|
+
end
|
62
65
|
end
|
63
|
-
end
|
64
66
|
|
65
|
-
|
66
|
-
k.create_extend(module_name)
|
67
|
+
model.create_extend(module_name)
|
67
68
|
end
|
68
69
|
end
|
69
70
|
|
@@ -15,8 +15,8 @@ end
|
|
15
15
|
module Tapioca
|
16
16
|
module Compilers
|
17
17
|
module Dsl
|
18
|
-
# `Tapioca::Compilers::DSL::ActiveRecordTypedStore` generates RBI files for
|
19
|
-
# `ActiveRecord::TypedStore`
|
18
|
+
# `Tapioca::Compilers::DSL::ActiveRecordTypedStore` generates RBI files for Active Record models that use
|
19
|
+
# [`ActiveRecord::TypedStore`](https://github.com/byroot/activerecord-typedstore) features.
|
20
20
|
#
|
21
21
|
# For example, with the following ActiveRecord class:
|
22
22
|
#
|
@@ -101,13 +101,14 @@ module Tapioca
|
|
101
101
|
stores = constant.typed_stores
|
102
102
|
return if stores.values.flat_map(&:accessors).empty?
|
103
103
|
|
104
|
-
root.path(constant) do |
|
104
|
+
root.path(constant) do |model|
|
105
105
|
stores.values.each do |store_data|
|
106
106
|
store_data.accessors.each do |accessor|
|
107
107
|
field = store_data.fields[accessor]
|
108
108
|
type = type_for(field.type_sym)
|
109
109
|
type = "T.nilable(#{type})" if field.null && type != "T.untyped"
|
110
|
-
|
110
|
+
|
111
|
+
generate_methods(model, field.name.to_s, type)
|
111
112
|
end
|
112
113
|
end
|
113
114
|
end
|
@@ -141,13 +142,13 @@ module Tapioca
|
|
141
142
|
|
142
143
|
sig do
|
143
144
|
params(
|
145
|
+
klass: Parlour::RbiGenerator::Namespace,
|
144
146
|
name: String,
|
145
|
-
type: String
|
146
|
-
klass: Parlour::RbiGenerator::Namespace
|
147
|
+
type: String
|
147
148
|
)
|
148
149
|
.void
|
149
150
|
end
|
150
|
-
def generate_methods(name, type
|
151
|
+
def generate_methods(klass, name, type)
|
151
152
|
klass.create_method(
|
152
153
|
"#{name}=",
|
153
154
|
parameters: [Parlour::RbiGenerator::Parameter.new(name, type: type)],
|
@@ -13,8 +13,8 @@ module Tapioca
|
|
13
13
|
module Compilers
|
14
14
|
module Dsl
|
15
15
|
# `Tapioca::Compilers::Dsl::ActiveResource` decorates RBI files for subclasses of
|
16
|
-
# `ActiveResource::Base` which declare
|
17
|
-
#
|
16
|
+
# [`ActiveResource::Base`](https://github.com/rails/activeresource) which declare
|
17
|
+
# `schema` fields.
|
18
18
|
#
|
19
19
|
# For example, with the following `ActiveResource::Base` subclass:
|
20
20
|
#
|
@@ -71,9 +71,10 @@ module Tapioca
|
|
71
71
|
end
|
72
72
|
def decorate(root, constant)
|
73
73
|
return if constant.schema.blank?
|
74
|
-
|
74
|
+
|
75
|
+
root.path(constant) do |resource|
|
75
76
|
constant.schema.each do |attribute, type|
|
76
|
-
create_schema_methods(
|
77
|
+
create_schema_methods(resource, attribute, type)
|
77
78
|
end
|
78
79
|
end
|
79
80
|
end
|
@@ -13,9 +13,8 @@ module Tapioca
|
|
13
13
|
module Compilers
|
14
14
|
module Dsl
|
15
15
|
# `Tapioca::Compilers::Dsl::ActiveSupportCurrentAttributes` decorates RBI files for all
|
16
|
-
# subclasses of
|
17
|
-
#
|
18
|
-
# To add attributes see https://api.rubyonrails.org/classes/ActiveSupport/CurrentAttributes.html
|
16
|
+
# subclasses of
|
17
|
+
# [`ActiveSupport::CurrentAttributes`](https://api.rubyonrails.org/classes/ActiveSupport/CurrentAttributes.html).
|
19
18
|
#
|
20
19
|
# For example, with the following singleton class
|
21
20
|
#
|
@@ -76,20 +75,20 @@ module Tapioca
|
|
76
75
|
instance_methods = instance_methods_for(constant) - dynamic_methods
|
77
76
|
return if dynamic_methods.empty? && instance_methods.empty?
|
78
77
|
|
79
|
-
root.path(constant) do |
|
78
|
+
root.path(constant) do |current_attributes|
|
80
79
|
dynamic_methods.each do |method|
|
81
80
|
method = method.to_s
|
82
81
|
# We want to generate each method both on the class
|
83
|
-
generate_method(
|
82
|
+
generate_method(current_attributes, method, class_method: true)
|
84
83
|
# and on the instance
|
85
|
-
generate_method(
|
84
|
+
generate_method(current_attributes, method, class_method: false)
|
86
85
|
end
|
87
86
|
|
88
87
|
instance_methods.each do |method|
|
89
88
|
# instance methods are only elevated to class methods
|
90
89
|
# no need to add separate instance methods for them
|
91
90
|
method = constant.instance_method(method)
|
92
|
-
create_method_from_def(
|
91
|
+
create_method_from_def(current_attributes, method, class_method: true)
|
93
92
|
end
|
94
93
|
end
|
95
94
|
end
|
@@ -92,24 +92,28 @@ module Tapioca
|
|
92
92
|
method_def = signature.nil? ? method_def : signature.method
|
93
93
|
method_types = parameters_types_from_signature(method_def, signature)
|
94
94
|
|
95
|
-
method_def.parameters.each_with_index.map do |(type, name),
|
96
|
-
|
97
|
-
|
95
|
+
method_def.parameters.each_with_index.map do |(type, name), index|
|
96
|
+
fallback_arg_name = "_arg#{index}"
|
97
|
+
|
98
|
+
name ||= fallback_arg_name
|
99
|
+
name = name.to_s.gsub(/&|\*/, fallback_arg_name) # avoid incorrect names from `delegate`
|
100
|
+
method_type = method_types[index]
|
101
|
+
|
98
102
|
case type
|
99
103
|
when :req
|
100
|
-
::Parlour::RbiGenerator::Parameter.new(name, type:
|
104
|
+
::Parlour::RbiGenerator::Parameter.new(name, type: method_type)
|
101
105
|
when :opt
|
102
|
-
::Parlour::RbiGenerator::Parameter.new(name, type:
|
106
|
+
::Parlour::RbiGenerator::Parameter.new(name, type: method_type, default: 'T.unsafe(nil)')
|
103
107
|
when :rest
|
104
|
-
::Parlour::RbiGenerator::Parameter.new("*#{name}", type:
|
108
|
+
::Parlour::RbiGenerator::Parameter.new("*#{name}", type: method_type)
|
105
109
|
when :keyreq
|
106
|
-
::Parlour::RbiGenerator::Parameter.new("#{name}:", type:
|
110
|
+
::Parlour::RbiGenerator::Parameter.new("#{name}:", type: method_type)
|
107
111
|
when :key
|
108
|
-
::Parlour::RbiGenerator::Parameter.new("#{name}:", type:
|
112
|
+
::Parlour::RbiGenerator::Parameter.new("#{name}:", type: method_type, default: 'T.unsafe(nil)')
|
109
113
|
when :keyrest
|
110
|
-
::Parlour::RbiGenerator::Parameter.new("**#{name}", type:
|
114
|
+
::Parlour::RbiGenerator::Parameter.new("**#{name}", type: method_type)
|
111
115
|
when :block
|
112
|
-
::Parlour::RbiGenerator::Parameter.new("&#{name}", type:
|
116
|
+
::Parlour::RbiGenerator::Parameter.new("&#{name}", type: method_type)
|
113
117
|
else
|
114
118
|
raise "Unknown type `#{type}`."
|
115
119
|
end
|
@@ -12,8 +12,8 @@ end
|
|
12
12
|
module Tapioca
|
13
13
|
module Compilers
|
14
14
|
module Dsl
|
15
|
-
# `Tapioca::Compilers::Dsl::FrozenRecord` generates RBI files for subclasses of
|
16
|
-
# (
|
15
|
+
# `Tapioca::Compilers::Dsl::FrozenRecord` generates RBI files for subclasses of
|
16
|
+
# [`FrozenRecord::Base`](https://github.com/byroot/frozen_record).
|
17
17
|
#
|
18
18
|
# For example, with the following FrozenRecord class:
|
19
19
|
#
|
@@ -41,27 +41,27 @@ module Tapioca
|
|
41
41
|
# # Student.rbi
|
42
42
|
# # typed: strong
|
43
43
|
# class Student
|
44
|
-
# include
|
45
|
-
# end
|
44
|
+
# include FrozenRecordAttributeMethods
|
46
45
|
#
|
47
|
-
#
|
48
|
-
#
|
49
|
-
#
|
46
|
+
# module FrozenRecordAttributeMethods
|
47
|
+
# sig { returns(T.untyped) }
|
48
|
+
# def first_name; end
|
50
49
|
#
|
51
|
-
#
|
52
|
-
#
|
50
|
+
# sig { returns(T::Boolean) }
|
51
|
+
# def first_name?; end
|
53
52
|
#
|
54
|
-
#
|
55
|
-
#
|
53
|
+
# sig { returns(T.untyped) }
|
54
|
+
# def id; end
|
56
55
|
#
|
57
|
-
#
|
58
|
-
#
|
56
|
+
# sig { returns(T::Boolean) }
|
57
|
+
# def id?; end
|
59
58
|
#
|
60
|
-
#
|
61
|
-
#
|
59
|
+
# sig { returns(T.untyped) }
|
60
|
+
# def last_name; end
|
62
61
|
#
|
63
|
-
#
|
64
|
-
#
|
62
|
+
# sig { returns(T::Boolean) }
|
63
|
+
# def last_name?; end
|
64
|
+
# end
|
65
65
|
# end
|
66
66
|
# ~~~
|
67
67
|
class FrozenRecord < Base
|
@@ -72,17 +72,17 @@ module Tapioca
|
|
72
72
|
attributes = constant.attributes
|
73
73
|
return if attributes.empty?
|
74
74
|
|
75
|
-
|
75
|
+
root.path(constant) do |record|
|
76
|
+
module_name = "FrozenRecordAttributeMethods"
|
76
77
|
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
78
|
+
record.create_module(module_name) do |mod|
|
79
|
+
attributes.each do |attribute|
|
80
|
+
create_method(mod, "#{attribute}?", return_type: 'T::Boolean')
|
81
|
+
create_method(mod, attribute.to_s, return_type: 'T.untyped')
|
82
|
+
end
|
81
83
|
end
|
82
|
-
end
|
83
84
|
|
84
|
-
|
85
|
-
klass.create_include(module_name)
|
85
|
+
record.create_include(module_name)
|
86
86
|
end
|
87
87
|
end
|
88
88
|
|
@@ -15,11 +15,12 @@ end
|
|
15
15
|
module Tapioca
|
16
16
|
module Compilers
|
17
17
|
module Dsl
|
18
|
-
# `Tapioca::Compilers::DSL::
|
18
|
+
# `Tapioca::Compilers::DSL::IdentityCache` generates RBI files for Active Record models
|
19
19
|
# that use `include IdentityCache`.
|
20
|
-
# `IdentityCache` is a blob level caching solution
|
20
|
+
# [`IdentityCache`](https://github.com/Shopify/identity_cache) is a blob level caching solution
|
21
|
+
# to plug into Active Record.
|
21
22
|
#
|
22
|
-
# For example, with the following
|
23
|
+
# For example, with the following Active Record class:
|
23
24
|
#
|
24
25
|
# ~~~rb
|
25
26
|
# # post.rb
|
@@ -61,7 +62,7 @@ module Tapioca
|
|
61
62
|
# def fetch_by_title_and_review_date(title, review_date, includes: nil); end
|
62
63
|
# end
|
63
64
|
# ~~~
|
64
|
-
class
|
65
|
+
class IdentityCache < Base
|
65
66
|
extend T::Sig
|
66
67
|
|
67
68
|
COLLECTION_TYPE = T.let(
|
@@ -82,25 +83,25 @@ module Tapioca
|
|
82
83
|
cache_indexes = constant.send(:cache_indexes)
|
83
84
|
return if caches.empty? && cache_indexes.empty?
|
84
85
|
|
85
|
-
root.path(constant) do |
|
86
|
+
root.path(constant) do |model|
|
86
87
|
cache_manys = constant.send(:cached_has_manys)
|
87
88
|
cache_ones = constant.send(:cached_has_ones)
|
88
89
|
cache_belongs = constant.send(:cached_belongs_tos)
|
89
90
|
|
90
91
|
cache_indexes.each do |field|
|
91
|
-
create_fetch_by_methods(field,
|
92
|
+
create_fetch_by_methods(field, model, constant)
|
92
93
|
end
|
93
94
|
|
94
95
|
cache_manys.values.each do |field|
|
95
|
-
create_fetch_field_methods(field,
|
96
|
+
create_fetch_field_methods(field, model, returns_collection: true)
|
96
97
|
end
|
97
98
|
|
98
99
|
cache_ones.values.each do |field|
|
99
|
-
create_fetch_field_methods(field,
|
100
|
+
create_fetch_field_methods(field, model, returns_collection: false)
|
100
101
|
end
|
101
102
|
|
102
103
|
cache_belongs.values.each do |field|
|
103
|
-
create_fetch_field_methods(field,
|
104
|
+
create_fetch_field_methods(field, model, returns_collection: false)
|
104
105
|
end
|
105
106
|
end
|
106
107
|
end
|
@@ -108,7 +109,7 @@ module Tapioca
|
|
108
109
|
sig { override.returns(T::Enumerable[Module]) }
|
109
110
|
def gather_constants
|
110
111
|
::ActiveRecord::Base.descendants.select do |klass|
|
111
|
-
klass < IdentityCache
|
112
|
+
klass < ::IdentityCache::WithoutPrimaryIndex
|
112
113
|
end
|
113
114
|
end
|
114
115
|
|
@@ -12,7 +12,7 @@ module Tapioca
|
|
12
12
|
module Compilers
|
13
13
|
module Dsl
|
14
14
|
# `Tapioca::Compilers::Dsl::Protobuf` decorates RBI files for subclasses of
|
15
|
-
# `Google::Protobuf::MessageExts`
|
15
|
+
# [`Google::Protobuf::MessageExts`](https://github.com/protocolbuffers/protobuf/tree/master/ruby).
|
16
16
|
#
|
17
17
|
# For example, with the following "cart.rb" file:
|
18
18
|
#
|
@@ -0,0 +1,83 @@
|
|
1
|
+
# typed: strict
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
require "parlour"
|
5
|
+
|
6
|
+
begin
|
7
|
+
require "sidekiq"
|
8
|
+
rescue LoadError
|
9
|
+
return
|
10
|
+
end
|
11
|
+
|
12
|
+
module Tapioca
|
13
|
+
module Compilers
|
14
|
+
module Dsl
|
15
|
+
# `Tapioca::Compilers::Dsl::SidekiqWorker` generates RBI files classes that include
|
16
|
+
# [`Sidekiq::Worker`](https://github.com/mperham/sidekiq/wiki/Getting-Started).
|
17
|
+
#
|
18
|
+
# For example, with the following class that includes `Sidekiq::Worker`:
|
19
|
+
#
|
20
|
+
# ~~~rb
|
21
|
+
# class NotifierWorker
|
22
|
+
# include Sidekiq::Worker
|
23
|
+
# def perform(customer_id)
|
24
|
+
# # ...
|
25
|
+
# end
|
26
|
+
# end
|
27
|
+
# ~~~
|
28
|
+
#
|
29
|
+
# this generator will produce the RBI file `notifier_worker.rbi` with the following content:
|
30
|
+
#
|
31
|
+
# ~~~rbi
|
32
|
+
# # notifier_worker.rbi
|
33
|
+
# # typed: true
|
34
|
+
# class NotifierWorker
|
35
|
+
# sig { params(customer_id: T.untyped).returns(String) }
|
36
|
+
# def self.perform_async(customer_id); end
|
37
|
+
#
|
38
|
+
# sig { params(interval: T.any(DateTime, Time), customer_id: T.untyped).returns(String) }
|
39
|
+
# def self.perform_at(interval, customer_id); end
|
40
|
+
#
|
41
|
+
# sig { params(interval: Numeric, customer_id: T.untyped).returns(String) }
|
42
|
+
# def self.perform_in(interval, customer_id); end
|
43
|
+
# end
|
44
|
+
# ~~~
|
45
|
+
class SidekiqWorker < Base
|
46
|
+
extend T::Sig
|
47
|
+
|
48
|
+
sig { override.params(root: Parlour::RbiGenerator::Namespace, constant: T.class_of(::Sidekiq::Worker)).void }
|
49
|
+
def decorate(root, constant)
|
50
|
+
return unless constant.instance_methods.include?(:perform)
|
51
|
+
|
52
|
+
root.path(constant) do |worker|
|
53
|
+
method_def = constant.instance_method(:perform)
|
54
|
+
|
55
|
+
async_params = compile_method_parameters_to_parlour(method_def)
|
56
|
+
|
57
|
+
# `perform_at` and is just an alias for `perform_in` so both methods technically
|
58
|
+
# accept a datetime, time, or numeric but we're typing them differently so they
|
59
|
+
# semantically make sense.
|
60
|
+
at_params = [
|
61
|
+
Parlour::RbiGenerator::Parameter.new('interval', type: 'T.any(DateTime, Time)'),
|
62
|
+
*async_params,
|
63
|
+
]
|
64
|
+
in_params = [
|
65
|
+
Parlour::RbiGenerator::Parameter.new('interval', type: 'Numeric'),
|
66
|
+
*async_params,
|
67
|
+
]
|
68
|
+
|
69
|
+
create_method(worker, 'perform_async', parameters: async_params, return_type: 'String', class_method: true)
|
70
|
+
create_method(worker, 'perform_at', parameters: at_params, return_type: 'String', class_method: true)
|
71
|
+
create_method(worker, 'perform_in', parameters: in_params, return_type: 'String', class_method: true)
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
sig { override.returns(T::Enumerable[Module]) }
|
76
|
+
def gather_constants
|
77
|
+
classes = T.cast(ObjectSpace.each_object(Class), T::Enumerable[Class])
|
78
|
+
classes.select { |c| c < Sidekiq::Worker }
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|