tapioca 0.4.24 → 0.5.1
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 +14 -14
- data/README.md +2 -2
- data/Rakefile +5 -7
- data/exe/tapioca +2 -2
- data/lib/tapioca/cli.rb +256 -2
- data/lib/tapioca/compilers/dsl/aasm.rb +122 -0
- data/lib/tapioca/compilers/dsl/action_controller_helpers.rb +52 -12
- data/lib/tapioca/compilers/dsl/action_mailer.rb +6 -9
- data/lib/tapioca/compilers/dsl/active_job.rb +8 -12
- data/lib/tapioca/compilers/dsl/active_model_attributes.rb +131 -0
- data/lib/tapioca/compilers/dsl/active_record_associations.rb +33 -54
- data/lib/tapioca/compilers/dsl/active_record_columns.rb +10 -105
- data/lib/tapioca/compilers/dsl/active_record_enum.rb +8 -10
- data/lib/tapioca/compilers/dsl/active_record_scope.rb +7 -10
- data/lib/tapioca/compilers/dsl/active_record_typed_store.rb +5 -8
- data/lib/tapioca/compilers/dsl/active_resource.rb +9 -37
- data/lib/tapioca/compilers/dsl/active_storage.rb +98 -0
- data/lib/tapioca/compilers/dsl/active_support_concern.rb +108 -0
- data/lib/tapioca/compilers/dsl/active_support_current_attributes.rb +13 -8
- data/lib/tapioca/compilers/dsl/base.rb +96 -82
- data/lib/tapioca/compilers/dsl/config.rb +111 -0
- data/lib/tapioca/compilers/dsl/frozen_record.rb +5 -7
- data/lib/tapioca/compilers/dsl/identity_cache.rb +66 -29
- data/lib/tapioca/compilers/dsl/protobuf.rb +19 -69
- data/lib/tapioca/compilers/dsl/sidekiq_worker.rb +25 -12
- data/lib/tapioca/compilers/dsl/smart_properties.rb +19 -31
- data/lib/tapioca/compilers/dsl/state_machines.rb +56 -78
- data/lib/tapioca/compilers/dsl/url_helpers.rb +7 -10
- data/lib/tapioca/compilers/dsl_compiler.rb +22 -38
- data/lib/tapioca/compilers/requires_compiler.rb +2 -2
- data/lib/tapioca/compilers/sorbet.rb +26 -5
- data/lib/tapioca/compilers/symbol_table/symbol_generator.rb +139 -154
- data/lib/tapioca/compilers/symbol_table/symbol_loader.rb +4 -4
- data/lib/tapioca/compilers/symbol_table_compiler.rb +1 -1
- data/lib/tapioca/compilers/todos_compiler.rb +1 -1
- data/lib/tapioca/config.rb +2 -0
- data/lib/tapioca/config_builder.rb +4 -2
- data/lib/tapioca/constant_locator.rb +6 -8
- data/lib/tapioca/gemfile.rb +26 -19
- data/lib/tapioca/generator.rb +127 -43
- data/lib/tapioca/generic_type_registry.rb +25 -98
- data/lib/tapioca/helpers/active_record_column_type_helper.rb +98 -0
- data/lib/tapioca/internal.rb +1 -9
- data/lib/tapioca/loader.rb +14 -48
- data/lib/tapioca/rbi_ext/model.rb +122 -0
- data/lib/tapioca/reflection.rb +131 -0
- data/lib/tapioca/sorbet_ext/fixed_hash_patch.rb +1 -1
- data/lib/tapioca/sorbet_ext/generic_name_patch.rb +72 -4
- data/lib/tapioca/sorbet_ext/name_patch.rb +1 -1
- data/lib/tapioca/version.rb +1 -1
- data/lib/tapioca.rb +2 -0
- metadata +34 -22
- data/lib/tapioca/cli/main.rb +0 -146
- data/lib/tapioca/core_ext/class.rb +0 -28
- data/lib/tapioca/core_ext/string.rb +0 -18
- data/lib/tapioca/rbi/model.rb +0 -405
- data/lib/tapioca/rbi/printer.rb +0 -410
- data/lib/tapioca/rbi/rewriters/group_nodes.rb +0 -106
- data/lib/tapioca/rbi/rewriters/nest_non_public_methods.rb +0 -65
- data/lib/tapioca/rbi/rewriters/nest_singleton_methods.rb +0 -42
- data/lib/tapioca/rbi/rewriters/sort_nodes.rb +0 -86
- data/lib/tapioca/rbi/visitor.rb +0 -21
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0f8af6316243d26a0446636e00af5c9210296f5e5ac1f6065506af426d72c066
|
4
|
+
data.tar.gz: 7124feeb9e7ecc16c2de3897ae9dd2bd3a432be6295d66ab5c440c4377f6d1e1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 720a2022478adcffea11b8a52b486dec808544611c9792c8508224c8565a3a4aaaed9f0a512bf51417da1259275ba6dbbd09b318f5e8e438544ae54558e0e028
|
7
|
+
data.tar.gz: 8b5148ed02e2105b0c44134b98c99cb0e2c03144e8eca2293c8cf558b8dcff3141a5812141cb369e83cd830acb847a540f14303d2472ba7877518d4de55545ca
|
data/Gemfile
CHANGED
@@ -18,21 +18,21 @@ group(:deployment, :development) do
|
|
18
18
|
end
|
19
19
|
|
20
20
|
group(:development, :test) do
|
21
|
-
gem("smart_properties",
|
22
|
-
gem("frozen_record",
|
23
|
-
gem("sprockets",
|
24
|
-
gem("rails",
|
25
|
-
gem("state_machines",
|
26
|
-
gem("activerecord-typedstore",
|
21
|
+
gem("smart_properties", require: false)
|
22
|
+
gem("frozen_record", require: false)
|
23
|
+
gem("sprockets", require: false)
|
24
|
+
gem("rails", require: false)
|
25
|
+
gem("state_machines", require: false)
|
26
|
+
gem("activerecord-typedstore", require: false)
|
27
27
|
gem("sqlite3")
|
28
|
-
gem("identity_cache",
|
28
|
+
gem("identity_cache", require: false)
|
29
29
|
gem("cityhash", git: "https://github.com/csfrancis/cityhash.git",
|
30
30
|
ref: "3cfc7d01f333c01811d5e834f1495eaa29f87c36", require: false)
|
31
|
-
gem("
|
32
|
-
gem("
|
33
|
-
gem("
|
34
|
-
|
35
|
-
gem("
|
36
|
-
gem("
|
37
|
-
gem("
|
31
|
+
gem("activeresource", require: false)
|
32
|
+
gem("google-protobuf", require: false)
|
33
|
+
gem("shopify-money", require: false)
|
34
|
+
gem("sidekiq", require: false)
|
35
|
+
gem("nokogiri", require: false)
|
36
|
+
gem("config", require: false)
|
37
|
+
gem("aasm", require: false)
|
38
38
|
end
|
data/README.md
CHANGED
@@ -117,8 +117,8 @@ This will generate DSL RBIs for specified constants (or for all handled constant
|
|
117
117
|
|
118
118
|
## Contributing
|
119
119
|
|
120
|
-
Bug reports and pull requests are welcome on GitHub at https://github.com/Shopify/tapioca. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](https://github.com/Shopify/tapioca/blob/
|
120
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/Shopify/tapioca. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](https://github.com/Shopify/tapioca/blob/main/CODE_OF_CONDUCT.md) code of conduct.
|
121
121
|
|
122
122
|
## License
|
123
123
|
|
124
|
-
The gem is available as open source under the terms of the [MIT License](https://github.com/Shopify/tapioca/blob/
|
124
|
+
The gem is available as open source under the terms of the [MIT License](https://github.com/Shopify/tapioca/blob/main/LICENSE.txt).
|
data/Rakefile
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
require "bundler/gem_tasks"
|
4
4
|
require "rake/testtask"
|
5
|
-
Dir[
|
5
|
+
Dir["tasks/**/*.rake"].each { |t| load t }
|
6
6
|
|
7
7
|
Rake.application.options.trace = false
|
8
8
|
|
@@ -10,15 +10,13 @@ Rake::TestTask.new do |t|
|
|
10
10
|
t.libs << "lib"
|
11
11
|
t.libs << "spec"
|
12
12
|
t.warning = false
|
13
|
-
t.test_files = FileList[
|
13
|
+
t.test_files = FileList["spec/**/*_spec.rb"]
|
14
14
|
end
|
15
15
|
|
16
16
|
task(:spec) do
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
exit(1)
|
21
|
-
end
|
17
|
+
Rake::Task[:test].execute
|
18
|
+
rescue RuntimeError
|
19
|
+
exit(1)
|
22
20
|
end
|
23
21
|
|
24
22
|
task(default: :spec)
|
data/exe/tapioca
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
#! /usr/bin/env ruby
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
|
-
require
|
4
|
+
require "sorbet-runtime"
|
5
5
|
|
6
6
|
begin
|
7
7
|
T::Configuration.default_checked_level = :never
|
@@ -20,4 +20,4 @@ end
|
|
20
20
|
|
21
21
|
require_relative "../lib/tapioca/internal"
|
22
22
|
|
23
|
-
Tapioca::Cli
|
23
|
+
Tapioca::Cli.start(ARGV)
|
data/lib/tapioca/cli.rb
CHANGED
@@ -1,8 +1,262 @@
|
|
1
1
|
# typed: true
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
|
-
require
|
4
|
+
require "thor"
|
5
5
|
|
6
6
|
module Tapioca
|
7
|
-
|
7
|
+
class Cli < Thor
|
8
|
+
include(Thor::Actions)
|
9
|
+
|
10
|
+
class_option :outdir,
|
11
|
+
aliases: ["--out", "-o"],
|
12
|
+
banner: "directory",
|
13
|
+
desc: "The output directory for generated RBI files"
|
14
|
+
class_option :generate_command,
|
15
|
+
aliases: ["--cmd", "-c"],
|
16
|
+
banner: "command",
|
17
|
+
desc: "The command to run to regenerate RBI files"
|
18
|
+
class_option :file_header,
|
19
|
+
type: :boolean,
|
20
|
+
default: true,
|
21
|
+
desc: "Add a \"This file is generated\" header on top of each generated RBI file"
|
22
|
+
class_option :verbose,
|
23
|
+
aliases: ["-V"],
|
24
|
+
type: :boolean,
|
25
|
+
default: false,
|
26
|
+
desc: "Verbose output for debugging purposes"
|
27
|
+
|
28
|
+
map T.unsafe(["--version", "-v"] => :__print_version)
|
29
|
+
|
30
|
+
desc "init", "initializes folder structure"
|
31
|
+
def init
|
32
|
+
create_config
|
33
|
+
create_post_require
|
34
|
+
generate_binstub
|
35
|
+
end
|
36
|
+
|
37
|
+
desc "require", "generate the list of files to be required by tapioca"
|
38
|
+
def require
|
39
|
+
Tapioca.silence_warnings do
|
40
|
+
generator.build_requires
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
desc "todo", "generate the list of unresolved constants"
|
45
|
+
def todo
|
46
|
+
Tapioca.silence_warnings do
|
47
|
+
generator.build_todos
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
desc "dsl [constant...]", "generate RBIs for dynamic methods"
|
52
|
+
option :generators,
|
53
|
+
type: :array,
|
54
|
+
aliases: ["--gen", "-g"],
|
55
|
+
banner: "generator [generator ...]",
|
56
|
+
desc: "Only run supplied DSL generators"
|
57
|
+
option :exclude_generators,
|
58
|
+
type: :array,
|
59
|
+
banner: "generator [generator ...]",
|
60
|
+
desc: "Exclude supplied DSL generators"
|
61
|
+
option :verify,
|
62
|
+
type: :boolean,
|
63
|
+
default: false,
|
64
|
+
desc: "Verifies RBIs are up-to-date"
|
65
|
+
option :quiet,
|
66
|
+
aliases: ["-q"],
|
67
|
+
type: :boolean,
|
68
|
+
desc: "Supresses file creation output"
|
69
|
+
def dsl(*constants)
|
70
|
+
Tapioca.silence_warnings do
|
71
|
+
generator.build_dsl(
|
72
|
+
constants,
|
73
|
+
should_verify: options[:verify],
|
74
|
+
quiet: options[:quiet],
|
75
|
+
verbose: options[:verbose]
|
76
|
+
)
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
desc "gem [gem...]", "generate RBIs from gems"
|
81
|
+
option :all,
|
82
|
+
type: :boolean,
|
83
|
+
default: false,
|
84
|
+
desc: "Regenerate RBI files for all gems"
|
85
|
+
option :prerequire,
|
86
|
+
aliases: ["--pre", "-b"],
|
87
|
+
banner: "file",
|
88
|
+
desc: "A file to be required before Bundler.require is called"
|
89
|
+
option :postrequire,
|
90
|
+
aliases: ["--post", "-a"],
|
91
|
+
banner: "file",
|
92
|
+
desc: "A file to be required after Bundler.require is called"
|
93
|
+
option :exclude,
|
94
|
+
aliases: ["-x"],
|
95
|
+
type: :array,
|
96
|
+
banner: "gem [gem ...]",
|
97
|
+
desc: "Excludes the given gem(s) from RBI generation"
|
98
|
+
option :typed_overrides,
|
99
|
+
aliases: ["--typed", "-t"],
|
100
|
+
type: :hash,
|
101
|
+
banner: "gem:level [gem:level ...]",
|
102
|
+
desc: "Overrides for typed sigils for generated gem RBIs"
|
103
|
+
option :verify,
|
104
|
+
type: :boolean,
|
105
|
+
default: false,
|
106
|
+
desc: "Verifies RBIs are up-to-date"
|
107
|
+
def gem(*gems)
|
108
|
+
Tapioca.silence_warnings do
|
109
|
+
all = options[:all]
|
110
|
+
verify = options[:verify]
|
111
|
+
|
112
|
+
raise MalformattedArgumentError, "Options '--all' and '--verify' are mutually exclusive" if all && verify
|
113
|
+
|
114
|
+
unless gems.empty?
|
115
|
+
raise MalformattedArgumentError, "Option '--all' must be provided without any other arguments" if all
|
116
|
+
raise MalformattedArgumentError, "Option '--verify' must be provided without any other arguments" if verify
|
117
|
+
end
|
118
|
+
|
119
|
+
if gems.empty? && !all
|
120
|
+
generator.sync_rbis_with_gemfile(should_verify: verify)
|
121
|
+
else
|
122
|
+
generator.build_gem_rbis(all ? [] : gems)
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
desc "generate [gem...]", "DEPRECATED: generate RBIs from gems"
|
128
|
+
option :prerequire,
|
129
|
+
aliases: ["--pre", "-b"],
|
130
|
+
banner: "file",
|
131
|
+
desc: "A file to be required before Bundler.require is called"
|
132
|
+
option :postrequire,
|
133
|
+
aliases: ["--post", "-a"],
|
134
|
+
banner: "file",
|
135
|
+
desc: "A file to be required after Bundler.require is called"
|
136
|
+
option :exclude,
|
137
|
+
aliases: ["-x"],
|
138
|
+
type: :array,
|
139
|
+
banner: "gem [gem ...]",
|
140
|
+
desc: "Excludes the given gem(s) from RBI generation"
|
141
|
+
option :typed_overrides,
|
142
|
+
aliases: ["--typed", "-t"],
|
143
|
+
type: :hash,
|
144
|
+
banner: "gem:level [gem:level ...]",
|
145
|
+
desc: "Overrides for typed sigils for generated gem RBIs"
|
146
|
+
def generate(*gems)
|
147
|
+
gem_names = if gems.empty?
|
148
|
+
"--all"
|
149
|
+
else
|
150
|
+
gems.join(" ")
|
151
|
+
end
|
152
|
+
deprecation_message = <<~MSG
|
153
|
+
DEPRECATION: The `generate` command will be removed in a future release.
|
154
|
+
|
155
|
+
Start using `bin/tapioca gem #{gem_names}` instead.
|
156
|
+
MSG
|
157
|
+
|
158
|
+
say(deprecation_message, :red)
|
159
|
+
say("")
|
160
|
+
|
161
|
+
Tapioca.silence_warnings do
|
162
|
+
generator.build_gem_rbis(gems)
|
163
|
+
end
|
164
|
+
|
165
|
+
say("")
|
166
|
+
say(deprecation_message, :red)
|
167
|
+
end
|
168
|
+
|
169
|
+
desc "sync", "DEPRECATED: sync RBIs to Gemfile"
|
170
|
+
option :prerequire,
|
171
|
+
aliases: ["--pre", "-b"],
|
172
|
+
banner: "file",
|
173
|
+
desc: "A file to be required before Bundler.require is called"
|
174
|
+
option :postrequire,
|
175
|
+
aliases: ["--post", "-a"],
|
176
|
+
banner: "file",
|
177
|
+
desc: "A file to be required after Bundler.require is called"
|
178
|
+
option :exclude,
|
179
|
+
aliases: ["-x"],
|
180
|
+
type: :array,
|
181
|
+
banner: "gem [gem ...]",
|
182
|
+
desc: "Excludes the given gem(s) from RBI generation"
|
183
|
+
option :typed_overrides,
|
184
|
+
aliases: ["--typed", "-t"],
|
185
|
+
type: :hash,
|
186
|
+
banner: "gem:level [gem:level ...]",
|
187
|
+
desc: "Overrides for typed sigils for generated gem RBIs"
|
188
|
+
option :verify,
|
189
|
+
type: :boolean,
|
190
|
+
default: false,
|
191
|
+
desc: "Verifies RBIs are up-to-date"
|
192
|
+
def sync
|
193
|
+
deprecation_message = <<~MSG
|
194
|
+
DEPRECATION: The `sync` command will be removed in a future release.
|
195
|
+
|
196
|
+
Start using `bin/tapioca gem` instead.
|
197
|
+
MSG
|
198
|
+
|
199
|
+
say(deprecation_message, :red)
|
200
|
+
say("")
|
201
|
+
|
202
|
+
Tapioca.silence_warnings do
|
203
|
+
generator.sync_rbis_with_gemfile(should_verify: options[:verify])
|
204
|
+
end
|
205
|
+
|
206
|
+
say("")
|
207
|
+
say(deprecation_message, :red)
|
208
|
+
end
|
209
|
+
|
210
|
+
desc "--version, -v", "show version"
|
211
|
+
def __print_version
|
212
|
+
puts "Tapioca v#{Tapioca::VERSION}"
|
213
|
+
end
|
214
|
+
|
215
|
+
private
|
216
|
+
|
217
|
+
def create_config
|
218
|
+
create_file(Config::SORBET_CONFIG, skip: true) do
|
219
|
+
<<~CONTENT
|
220
|
+
--dir
|
221
|
+
.
|
222
|
+
CONTENT
|
223
|
+
end
|
224
|
+
end
|
225
|
+
|
226
|
+
def create_post_require
|
227
|
+
create_file(Config::DEFAULT_POSTREQUIRE, skip: true) do
|
228
|
+
<<~CONTENT
|
229
|
+
# typed: true
|
230
|
+
# frozen_string_literal: true
|
231
|
+
|
232
|
+
# Add your extra requires here (`tapioca require` can be used to boostrap this list)
|
233
|
+
CONTENT
|
234
|
+
end
|
235
|
+
end
|
236
|
+
|
237
|
+
def generate_binstub
|
238
|
+
bin_stub_exists = File.exist?("bin/tapioca")
|
239
|
+
installer = Bundler::Installer.new(Bundler.root, Bundler.definition)
|
240
|
+
spec = Bundler.definition.specs.find { |s| s.name == "tapioca" }
|
241
|
+
installer.generate_bundler_executable_stubs(spec, { force: true })
|
242
|
+
if bin_stub_exists
|
243
|
+
shell.say_status(:force, "bin/tapioca", :yellow)
|
244
|
+
else
|
245
|
+
shell.say_status(:create, "bin/tapioca", :green)
|
246
|
+
end
|
247
|
+
end
|
248
|
+
|
249
|
+
no_commands do
|
250
|
+
def self.exit_on_failure?
|
251
|
+
true
|
252
|
+
end
|
253
|
+
|
254
|
+
def generator
|
255
|
+
current_command = T.must(current_command_chain.first)
|
256
|
+
@generator ||= Generator.new(
|
257
|
+
ConfigBuilder.from_options(current_command, options)
|
258
|
+
)
|
259
|
+
end
|
260
|
+
end
|
261
|
+
end
|
8
262
|
end
|
@@ -0,0 +1,122 @@
|
|
1
|
+
# typed: strict
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
begin
|
5
|
+
require "active_record"
|
6
|
+
require "aasm"
|
7
|
+
rescue LoadError
|
8
|
+
return
|
9
|
+
end
|
10
|
+
|
11
|
+
module Tapioca
|
12
|
+
module Compilers
|
13
|
+
module Dsl
|
14
|
+
# `Tapioca::Compilers::Dsl::AASM` generate types for AASM state machines.
|
15
|
+
# This gem dynamically defines constants and methods at runtime. For
|
16
|
+
# example, given a class:
|
17
|
+
#
|
18
|
+
# class MyClass
|
19
|
+
# include AASM
|
20
|
+
#
|
21
|
+
# aasm do
|
22
|
+
# state :sleeping, initial: true
|
23
|
+
# state :running, :cleaning
|
24
|
+
#
|
25
|
+
# event :run do
|
26
|
+
# transitions from: :sleeping, to: :running
|
27
|
+
# end
|
28
|
+
# end
|
29
|
+
# end
|
30
|
+
#
|
31
|
+
# This will result in the following constants being defined:
|
32
|
+
#
|
33
|
+
# STATE_SLEEPING, STATE_RUNNING, STATE_CLEANING
|
34
|
+
#
|
35
|
+
# and the following methods being defined:
|
36
|
+
#
|
37
|
+
# sleeping?, running?, cleaning?
|
38
|
+
# run, run!, run_without_validation!, may_run?
|
39
|
+
#
|
40
|
+
class AASM < Tapioca::Compilers::Dsl::Base
|
41
|
+
extend T::Sig
|
42
|
+
|
43
|
+
# Taken directly from the AASM::Core::Event class, here:
|
44
|
+
# https://github.com/aasm/aasm/blob/0e03746/lib/aasm/core/event.rb#L21-L29
|
45
|
+
EVENT_CALLBACKS =
|
46
|
+
T.let(
|
47
|
+
["after", "after_commit", "after_transaction", "before", "before_transaction", "ensure", "error",
|
48
|
+
"before_success", "success"].freeze,
|
49
|
+
T::Array[String]
|
50
|
+
)
|
51
|
+
|
52
|
+
sig { override.params(root: RBI::Tree, constant: T.all(::AASM::ClassMethods, Class)).void }
|
53
|
+
def decorate(root, constant)
|
54
|
+
aasm = constant.aasm
|
55
|
+
return if !aasm || aasm.states.empty?
|
56
|
+
|
57
|
+
root.create_path(constant) do |model|
|
58
|
+
# Create all of the constants and methods for each state
|
59
|
+
aasm.states.each do |state|
|
60
|
+
model.create_constant("STATE_#{state.name.upcase}", value: "T.let(T.unsafe(nil), Symbol)")
|
61
|
+
model.create_method("#{state.name}?", return_type: "T::Boolean")
|
62
|
+
end
|
63
|
+
|
64
|
+
# Create all of the methods for each event
|
65
|
+
parameters = [create_rest_param("opts", type: "T.untyped")]
|
66
|
+
aasm.events.each do |event|
|
67
|
+
model.create_method(event.name.to_s, parameters: parameters)
|
68
|
+
model.create_method("#{event.name}!", parameters: parameters)
|
69
|
+
model.create_method("#{event.name}_without_validation!", parameters: parameters)
|
70
|
+
model.create_method("may_#{event.name}?", return_type: "T::Boolean")
|
71
|
+
end
|
72
|
+
|
73
|
+
# Create the overall state machine method, which will return an
|
74
|
+
# instance of the PrivateAASMMachine class.
|
75
|
+
model.create_method(
|
76
|
+
"aasm",
|
77
|
+
parameters: [
|
78
|
+
create_rest_param("args", type: "T.untyped"),
|
79
|
+
create_block_param("block", type: "T.nilable(T.proc.bind(PrivateAASMMachine).void)"),
|
80
|
+
],
|
81
|
+
return_type: "PrivateAASMMachine",
|
82
|
+
class_method: true
|
83
|
+
)
|
84
|
+
|
85
|
+
# Create a private machine class that we can pass around for the
|
86
|
+
# purpose of binding various procs passed to methods without having
|
87
|
+
# to explicitly bind self in each one.
|
88
|
+
model.create_class("PrivateAASMMachine", superclass_name: "AASM::Base") do |machine|
|
89
|
+
machine.create_method(
|
90
|
+
"event",
|
91
|
+
parameters: [
|
92
|
+
create_param("name", type: "T.untyped"),
|
93
|
+
create_opt_param("options", default: "nil", type: "T.untyped"),
|
94
|
+
create_block_param("block", type: "T.proc.bind(PrivateAASMEvent).void"),
|
95
|
+
]
|
96
|
+
)
|
97
|
+
|
98
|
+
# Create a private event class that we can pass around for the
|
99
|
+
# purpose of binding all of the callbacks without having to
|
100
|
+
# explicitly bind self in each one.
|
101
|
+
machine.create_class("PrivateAASMEvent", superclass_name: "AASM::Core::Event") do |event|
|
102
|
+
EVENT_CALLBACKS.each do |method|
|
103
|
+
event.create_method(
|
104
|
+
method,
|
105
|
+
parameters: [
|
106
|
+
create_block_param("block", type: "T.proc.bind(#{constant.name}).void"),
|
107
|
+
]
|
108
|
+
)
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
sig { override.returns(T::Enumerable[Module]) }
|
116
|
+
def gather_constants
|
117
|
+
T.cast(ObjectSpace.each_object(::AASM::ClassMethods), T::Enumerable[Module])
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|