tapioca 0.4.27 → 0.5.3

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.
Files changed (74) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +15 -15
  3. data/README.md +2 -2
  4. data/Rakefile +5 -7
  5. data/exe/tapioca +2 -2
  6. data/lib/tapioca/cli.rb +172 -2
  7. data/lib/tapioca/compilers/dsl/aasm.rb +122 -0
  8. data/lib/tapioca/compilers/dsl/action_controller_helpers.rb +52 -12
  9. data/lib/tapioca/compilers/dsl/action_mailer.rb +6 -9
  10. data/lib/tapioca/compilers/dsl/active_job.rb +8 -12
  11. data/lib/tapioca/compilers/dsl/active_model_attributes.rb +131 -0
  12. data/lib/tapioca/compilers/dsl/active_model_secure_password.rb +101 -0
  13. data/lib/tapioca/compilers/dsl/active_record_associations.rb +33 -54
  14. data/lib/tapioca/compilers/dsl/active_record_columns.rb +10 -105
  15. data/lib/tapioca/compilers/dsl/active_record_enum.rb +8 -10
  16. data/lib/tapioca/compilers/dsl/active_record_fixtures.rb +86 -0
  17. data/lib/tapioca/compilers/dsl/active_record_scope.rb +7 -10
  18. data/lib/tapioca/compilers/dsl/active_record_typed_store.rb +5 -8
  19. data/lib/tapioca/compilers/dsl/active_resource.rb +9 -37
  20. data/lib/tapioca/compilers/dsl/active_storage.rb +98 -0
  21. data/lib/tapioca/compilers/dsl/active_support_concern.rb +106 -0
  22. data/lib/tapioca/compilers/dsl/active_support_current_attributes.rb +13 -8
  23. data/lib/tapioca/compilers/dsl/base.rb +108 -82
  24. data/lib/tapioca/compilers/dsl/config.rb +111 -0
  25. data/lib/tapioca/compilers/dsl/frozen_record.rb +5 -7
  26. data/lib/tapioca/compilers/dsl/identity_cache.rb +66 -29
  27. data/lib/tapioca/compilers/dsl/mixed_in_class_attributes.rb +74 -0
  28. data/lib/tapioca/compilers/dsl/protobuf.rb +19 -69
  29. data/lib/tapioca/compilers/dsl/sidekiq_worker.rb +25 -12
  30. data/lib/tapioca/compilers/dsl/smart_properties.rb +21 -33
  31. data/lib/tapioca/compilers/dsl/state_machines.rb +56 -78
  32. data/lib/tapioca/compilers/dsl/url_helpers.rb +7 -10
  33. data/lib/tapioca/compilers/dsl_compiler.rb +25 -40
  34. data/lib/tapioca/compilers/dynamic_mixin_compiler.rb +198 -0
  35. data/lib/tapioca/compilers/requires_compiler.rb +2 -2
  36. data/lib/tapioca/compilers/sorbet.rb +25 -5
  37. data/lib/tapioca/compilers/symbol_table/symbol_generator.rb +122 -206
  38. data/lib/tapioca/compilers/symbol_table/symbol_loader.rb +4 -4
  39. data/lib/tapioca/compilers/symbol_table_compiler.rb +5 -11
  40. data/lib/tapioca/compilers/todos_compiler.rb +1 -1
  41. data/lib/tapioca/config.rb +3 -0
  42. data/lib/tapioca/config_builder.rb +5 -2
  43. data/lib/tapioca/constant_locator.rb +6 -8
  44. data/lib/tapioca/gemfile.rb +14 -11
  45. data/lib/tapioca/generators/base.rb +61 -0
  46. data/lib/tapioca/generators/dsl.rb +362 -0
  47. data/lib/tapioca/generators/gem.rb +345 -0
  48. data/lib/tapioca/generators/init.rb +79 -0
  49. data/lib/tapioca/generators/require.rb +52 -0
  50. data/lib/tapioca/generators/todo.rb +76 -0
  51. data/lib/tapioca/generators.rb +9 -0
  52. data/lib/tapioca/generic_type_registry.rb +25 -98
  53. data/lib/tapioca/helpers/active_record_column_type_helper.rb +98 -0
  54. data/lib/tapioca/internal.rb +2 -10
  55. data/lib/tapioca/loader.rb +11 -31
  56. data/lib/tapioca/rbi_ext/model.rb +166 -0
  57. data/lib/tapioca/reflection.rb +138 -0
  58. data/lib/tapioca/sorbet_ext/fixed_hash_patch.rb +1 -1
  59. data/lib/tapioca/sorbet_ext/generic_name_patch.rb +72 -4
  60. data/lib/tapioca/sorbet_ext/name_patch.rb +1 -1
  61. data/lib/tapioca/version.rb +1 -1
  62. data/lib/tapioca.rb +3 -0
  63. metadata +45 -23
  64. data/lib/tapioca/cli/main.rb +0 -146
  65. data/lib/tapioca/core_ext/class.rb +0 -28
  66. data/lib/tapioca/core_ext/string.rb +0 -18
  67. data/lib/tapioca/generator.rb +0 -633
  68. data/lib/tapioca/rbi/model.rb +0 -405
  69. data/lib/tapioca/rbi/printer.rb +0 -410
  70. data/lib/tapioca/rbi/rewriters/group_nodes.rb +0 -106
  71. data/lib/tapioca/rbi/rewriters/nest_non_public_methods.rb +0 -65
  72. data/lib/tapioca/rbi/rewriters/nest_singleton_methods.rb +0 -42
  73. data/lib/tapioca/rbi/rewriters/sort_nodes.rb +0 -86
  74. data/lib/tapioca/rbi/visitor.rb +0 -21
@@ -1,6 +1,5 @@
1
1
  # typed: strict
2
2
  # frozen_string_literal: true
3
- require "parlour"
4
3
 
5
4
  begin
6
5
  require "google/protobuf"
@@ -62,67 +61,18 @@ module Tapioca
62
61
  # end
63
62
  # ~~~
64
63
  class Protobuf < Base
65
- # Parlour doesn't support type members out of the box, so adding the
66
- # ability to do that here. This should be upstreamed.
67
- class TypeMember < Parlour::RbiGenerator::RbiObject
68
- extend T::Sig
69
-
70
- sig { params(other: Object).returns(T::Boolean) }
71
- def ==(other)
72
- TypeMember === other && name == other.name
73
- end
74
-
75
- sig do
76
- override
77
- .params(indent_level: Integer, options: Parlour::RbiGenerator::Options)
78
- .returns(T::Array[String])
79
- end
80
- def generate_rbi(indent_level, options)
81
- [options.indented(indent_level, "#{name} = type_member")]
82
- end
83
-
84
- sig do
85
- override
86
- .params(others: T::Array[Parlour::RbiGenerator::RbiObject])
87
- .returns(T::Boolean)
88
- end
89
- def mergeable?(others)
90
- others.all? { |other| self == other }
91
- end
92
-
93
- sig { override.params(others: T::Array[Parlour::RbiGenerator::RbiObject]).void }
94
- def merge_into_self(others); end
95
-
96
- sig { override.returns(String) }
97
- def describe
98
- "Type Member (#{name})"
99
- end
100
- end
101
-
102
64
  class Field < T::Struct
103
65
  prop :name, String
104
66
  prop :type, String
105
67
  prop :init_type, String
106
68
  prop :default, String
107
-
108
- extend T::Sig
109
-
110
- sig { returns(Parlour::RbiGenerator::Parameter) }
111
- def to_init
112
- Parlour::RbiGenerator::Parameter.new("#{name}:", type: init_type, default: default)
113
- end
114
69
  end
115
70
 
116
71
  extend T::Sig
117
72
 
118
- sig do
119
- override.params(
120
- root: Parlour::RbiGenerator::Namespace,
121
- constant: Module
122
- ).void
123
- end
73
+ sig { override.params(root: RBI::Tree, constant: Module).void }
124
74
  def decorate(root, constant)
125
- root.path(constant) do |klass|
75
+ root.create_path(constant) do |klass|
126
76
  if constant == Google::Protobuf::RepeatedField
127
77
  create_type_members(klass, "Elem")
128
78
  elsif constant == Google::Protobuf::Map
@@ -132,7 +82,11 @@ module Tapioca
132
82
  fields = descriptor.map { |desc| create_descriptor_method(klass, desc) }
133
83
  fields.sort_by!(&:name)
134
84
 
135
- create_method(klass, "initialize", parameters: fields.map!(&:to_init))
85
+ parameters = fields.map do |field|
86
+ create_kw_opt_param(field.name, type: field.init_type, default: field.default)
87
+ end
88
+
89
+ klass.create_method("initialize", parameters: parameters, return_type: "void")
136
90
  end
137
91
  end
138
92
  end
@@ -146,12 +100,12 @@ module Tapioca
146
100
 
147
101
  private
148
102
 
149
- sig { params(klass: Parlour::RbiGenerator::Namespace, names: String).void }
103
+ sig { params(klass: RBI::Scope, names: String).void }
150
104
  def create_type_members(klass, *names)
151
105
  klass.create_extend("T::Generic")
152
106
 
153
107
  names.each do |name|
154
- klass.children << TypeMember.new(klass.generator, name)
108
+ klass.create_type_member(name)
155
109
  end
156
110
  end
157
111
 
@@ -186,34 +140,34 @@ module Tapioca
186
140
  # how Google names map entries.
187
141
  # https://github.com/protocolbuffers/protobuf/blob/f82e26/ruby/ext/google/protobuf_c/defs.c#L1963-L1966
188
142
  if descriptor.submsg_name.to_s.end_with?("_MapEntry_#{descriptor.name}")
189
- key = descriptor.subtype.lookup('key')
190
- value = descriptor.subtype.lookup('value')
143
+ key = descriptor.subtype.lookup("key")
144
+ value = descriptor.subtype.lookup("value")
191
145
 
192
146
  key_type = type_of(key)
193
147
  value_type = type_of(value)
194
148
  type = "Google::Protobuf::Map[#{key_type}, #{value_type}]"
195
149
 
196
150
  default_args = [key.type.inspect, value.type.inspect]
197
- default_args << value_type if %i[enum message].include?(value.type)
151
+ default_args << value_type if [:enum, :message].include?(value.type)
198
152
 
199
153
  Field.new(
200
154
  name: descriptor.name,
201
155
  type: type,
202
156
  init_type: "T.any(#{type}, T::Hash[#{key_type}, #{value_type}])",
203
- default: "Google::Protobuf::Map.new(#{default_args.join(', ')})"
157
+ default: "Google::Protobuf::Map.new(#{default_args.join(", ")})"
204
158
  )
205
159
  else
206
160
  elem_type = type_of(descriptor)
207
161
  type = "Google::Protobuf::RepeatedField[#{elem_type}]"
208
162
 
209
163
  default_args = [descriptor.type.inspect]
210
- default_args << elem_type if %i[enum message].include?(descriptor.type)
164
+ default_args << elem_type if [:enum, :message].include?(descriptor.type)
211
165
 
212
166
  Field.new(
213
167
  name: descriptor.name,
214
168
  type: type,
215
169
  init_type: "T.any(#{type}, T::Array[#{elem_type}])",
216
- default: "Google::Protobuf::RepeatedField.new(#{default_args.join(', ')})"
170
+ default: "Google::Protobuf::RepeatedField.new(#{default_args.join(", ")})"
217
171
  )
218
172
  end
219
173
  else
@@ -230,25 +184,21 @@ module Tapioca
230
184
 
231
185
  sig do
232
186
  params(
233
- klass: Parlour::RbiGenerator::Namespace,
187
+ klass: RBI::Scope,
234
188
  desc: Google::Protobuf::FieldDescriptor,
235
189
  ).returns(Field)
236
190
  end
237
191
  def create_descriptor_method(klass, desc)
238
192
  field = field_of(desc)
239
193
 
240
- create_method(
241
- klass,
194
+ klass.create_method(
242
195
  field.name,
243
196
  return_type: field.type
244
197
  )
245
198
 
246
- create_method(
247
- klass,
199
+ klass.create_method(
248
200
  "#{field.name}=",
249
- parameters: [
250
- Parlour::RbiGenerator::Parameter.new("value", type: field.type),
251
- ],
201
+ parameters: [create_param("value", type: field.type)],
252
202
  return_type: field.type
253
203
  )
254
204
 
@@ -1,8 +1,6 @@
1
1
  # typed: strict
2
2
  # frozen_string_literal: true
3
3
 
4
- require "parlour"
5
-
6
4
  begin
7
5
  require "sidekiq"
8
6
  rescue LoadError
@@ -45,37 +43,52 @@ module Tapioca
45
43
  class SidekiqWorker < Base
46
44
  extend T::Sig
47
45
 
48
- sig { override.params(root: Parlour::RbiGenerator::Namespace, constant: T.class_of(::Sidekiq::Worker)).void }
46
+ sig { override.params(root: RBI::Tree, constant: T.class_of(::Sidekiq::Worker)).void }
49
47
  def decorate(root, constant)
50
48
  return unless constant.instance_methods.include?(:perform)
51
49
 
52
- root.path(constant) do |worker|
50
+ root.create_path(constant) do |worker|
53
51
  method_def = constant.instance_method(:perform)
54
52
 
55
- async_params = compile_method_parameters_to_parlour(method_def)
53
+ async_params = compile_method_parameters_to_rbi(method_def)
56
54
 
57
55
  # `perform_at` and is just an alias for `perform_in` so both methods technically
58
56
  # accept a datetime, time, or numeric but we're typing them differently so they
59
57
  # semantically make sense.
60
58
  at_params = [
61
- Parlour::RbiGenerator::Parameter.new('interval', type: 'T.any(DateTime, Time)'),
59
+ create_param("interval", type: "T.any(DateTime, Time)"),
62
60
  *async_params,
63
61
  ]
64
62
  in_params = [
65
- Parlour::RbiGenerator::Parameter.new('interval', type: 'Numeric'),
63
+ create_param("interval", type: "Numeric"),
66
64
  *async_params,
67
65
  ]
68
66
 
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)
67
+ generate_perform_method(constant, worker, "perform_async", async_params)
68
+ generate_perform_method(constant, worker, "perform_at", at_params)
69
+ generate_perform_method(constant, worker, "perform_in", in_params)
72
70
  end
73
71
  end
74
72
 
75
73
  sig { override.returns(T::Enumerable[Module]) }
76
74
  def gather_constants
77
- classes = T.cast(ObjectSpace.each_object(Class), T::Enumerable[Class])
78
- classes.select { |c| c < Sidekiq::Worker }
75
+ all_classes.select { |c| c < Sidekiq::Worker }
76
+ end
77
+
78
+ private
79
+
80
+ sig do
81
+ params(
82
+ constant: T.class_of(::Sidekiq::Worker),
83
+ worker: RBI::Scope,
84
+ method_name: String,
85
+ parameters: T::Array[RBI::TypedParam]
86
+ ).void
87
+ end
88
+ def generate_perform_method(constant, worker, method_name, parameters)
89
+ if constant.method(method_name.to_sym).owner == Sidekiq::Worker::ClassMethods
90
+ worker.create_method(method_name, parameters: parameters, return_type: "String", class_method: true)
91
+ end
79
92
  end
80
93
  end
81
94
  end
@@ -1,8 +1,6 @@
1
1
  # typed: strict
2
2
  # frozen_string_literal: true
3
3
 
4
- require "parlour"
5
-
6
4
  begin
7
5
  require "smart_properties"
8
6
  rescue LoadError
@@ -55,7 +53,7 @@ module Tapioca
55
53
  # sig { params(published: T.nilable(T::Boolean)).returns(T.nilable(T::Boolean)) }
56
54
  # def published=(published); end
57
55
  #
58
- # ssig { returns(T.nilable(T::Boolean)) }
56
+ # sig { returns(T.nilable(T::Boolean)) }
59
57
  # def enabled; end
60
58
  #
61
59
  # sig { params(enabled: T.nilable(T::Boolean)).returns(T.nilable(T::Boolean)) }
@@ -65,14 +63,7 @@ module Tapioca
65
63
  class SmartProperties < Base
66
64
  extend T::Sig
67
65
 
68
- sig do
69
- override
70
- .params(
71
- root: Parlour::RbiGenerator::Namespace,
72
- constant: T.class_of(::SmartProperties)
73
- )
74
- .void
75
- end
66
+ sig { override.params(root: RBI::Tree, constant: T.class_of(::SmartProperties)).void }
76
67
  def decorate(root, constant)
77
68
  properties = T.let(
78
69
  T.unsafe(constant).properties,
@@ -82,7 +73,7 @@ module Tapioca
82
73
 
83
74
  instance_methods = constant.instance_methods(false).map(&:to_s).to_set
84
75
 
85
- root.path(constant) do |k|
76
+ root.create_path(constant) do |k|
86
77
  properties.values.each do |property|
87
78
  generate_methods_for_property(k, property) do |method_name|
88
79
  !instance_methods.include?(method_name.to_sym)
@@ -93,11 +84,10 @@ module Tapioca
93
84
 
94
85
  sig { override.returns(T::Enumerable[Module]) }
95
86
  def gather_constants
96
- classes = T.cast(ObjectSpace.each_object(Class), T::Enumerable[Class])
97
- classes.select do |c|
98
- c < ::SmartProperties
99
- end.reject do |c|
100
- c.name.nil? || c == ::SmartProperties::Validations::Ancestor
87
+ all_modules.select do |c|
88
+ name_of(c) &&
89
+ c != ::SmartProperties::Validations::Ancestor &&
90
+ c < ::SmartProperties && ::SmartProperties::ClassMethods === c
101
91
  end
102
92
  end
103
93
 
@@ -105,7 +95,7 @@ module Tapioca
105
95
 
106
96
  sig do
107
97
  params(
108
- klass: Parlour::RbiGenerator::Namespace,
98
+ klass: RBI::Scope,
109
99
  property: ::SmartProperties::Property,
110
100
  block: T.proc.params(arg: String).returns(T::Boolean)
111
101
  ).void
@@ -119,7 +109,7 @@ module Tapioca
119
109
 
120
110
  klass.create_method(
121
111
  method_name,
122
- parameters: [Parlour::RbiGenerator::Parameter.new(name, type: type)],
112
+ parameters: [create_param(name, type: type)],
123
113
  return_type: type
124
114
  ) if block.call(method_name)
125
115
  end
@@ -134,10 +124,13 @@ module Tapioca
134
124
 
135
125
  sig { params(property: ::SmartProperties::Property).returns(String) }
136
126
  def type_for(property)
137
- converter = property.converter
138
- return "T.untyped" if converter
127
+ converter, accepter, required = property.to_h.fetch_values(
128
+ :converter,
129
+ :accepter,
130
+ :required,
131
+ )
139
132
 
140
- accepter = property.accepter
133
+ return "T.untyped" if converter
141
134
 
142
135
  type = if accepter.nil? || accepter.respond_to?(:to_proc)
143
136
  "T.untyped"
@@ -147,25 +140,20 @@ module Tapioca
147
140
  "T::Boolean"
148
141
  elsif Array(accepter).all? { |a| a.is_a?(Module) }
149
142
  accepters = Array(accepter)
150
- types = accepters.map { |mod| name_of(mod) }.join(', ')
143
+ types = accepters.map { |mod| T.must(qualified_name_of(mod)) }.join(", ")
151
144
  types = "T.any(#{types})" if accepters.size > 1
152
145
  types
153
146
  else
154
147
  "T.untyped"
155
148
  end
156
149
 
157
- required_attr = property.instance_variable_get(:@required)
158
- required = !required_attr.is_a?(Proc) && !!required_attr
159
- property_required = type == "T.untyped" || required
160
- type = "T.nilable(#{type})" unless property_required
150
+ # Early return for "T.untyped", nothing more to do.
151
+ return type if type == "T.untyped"
161
152
 
162
- type
163
- end
153
+ might_be_optional = Proc === required || !required
154
+ type = "T.nilable(#{type})" if might_be_optional
164
155
 
165
- sig { params(type: Module).returns(String) }
166
- def name_of(type)
167
- name = Module.instance_method(:name).bind(type).call
168
- name.start_with?("::") ? name : "::#{name}"
156
+ type
169
157
  end
170
158
  end
171
159
  end
@@ -1,9 +1,6 @@
1
1
  # typed: strict
2
2
  # frozen_string_literal: true
3
3
 
4
- require "parlour"
5
- require "tapioca/core_ext/class"
6
-
7
4
  begin
8
5
  require "state_machines"
9
6
  rescue LoadError
@@ -121,16 +118,19 @@ module Tapioca
121
118
  class StateMachines < Base
122
119
  extend T::Sig
123
120
 
124
- sig { override.params(root: Parlour::RbiGenerator::Namespace, constant: ::StateMachines::ClassMethods).void }
121
+ sig { override.params(root: RBI::Tree, constant: ::StateMachines::ClassMethods).void }
125
122
  def decorate(root, constant)
126
123
  return if constant.state_machines.empty?
127
124
 
128
- root.path(constant) do |klass|
125
+ root.create_path(T.unsafe(constant)) do |klass|
129
126
  instance_module_name = "StateMachineInstanceHelperModule"
130
127
  class_module_name = "StateMachineClassHelperModule"
131
128
 
132
- instance_module = klass.create_module(instance_module_name)
133
- class_module = klass.create_module(class_module_name)
129
+ instance_module = RBI::Module.new(instance_module_name)
130
+ klass << instance_module
131
+
132
+ class_module = RBI::Module.new(class_module_name)
133
+ klass << class_module
134
134
 
135
135
  constant.state_machines.each_value do |machine|
136
136
  state_type = state_type_for(machine)
@@ -160,7 +160,7 @@ module Tapioca
160
160
 
161
161
  sig { override.returns(T::Enumerable[Module]) }
162
162
  def gather_constants
163
- Object.descendants.select { |mod| mod < ::StateMachines::InstanceMethods }
163
+ all_classes.select { |mod| mod < ::StateMachines::InstanceMethods }
164
164
  end
165
165
 
166
166
  private
@@ -172,54 +172,48 @@ module Tapioca
172
172
  if value_types.size == 1
173
173
  value_types.first
174
174
  else
175
- "T.any(#{value_types.join(', ')})"
175
+ "T.any(#{value_types.join(", ")})"
176
176
  end
177
177
  end
178
178
 
179
- sig { params(instance_module: Parlour::RbiGenerator::Namespace).void }
179
+ sig { params(instance_module: RBI::Module).void }
180
180
  def define_activerecord_methods(instance_module)
181
- create_method(
182
- instance_module,
181
+ instance_module.create_method(
183
182
  "changed_for_autosave?",
184
183
  return_type: "T::Boolean"
185
184
  )
186
185
  end
187
186
 
188
- sig { params(instance_module: Parlour::RbiGenerator::Namespace, machine: ::StateMachines::Machine).void }
187
+ sig { params(instance_module: RBI::Module, machine: ::StateMachines::Machine).void }
189
188
  def define_state_methods(instance_module, machine)
190
189
  machine.states.each do |state|
191
- create_method(
192
- instance_module,
190
+ instance_module.create_method(
193
191
  "#{state.qualified_name}?",
194
192
  return_type: "T::Boolean"
195
193
  )
196
194
  end
197
195
  end
198
196
 
199
- sig { params(instance_module: Parlour::RbiGenerator::Namespace, machine: ::StateMachines::Machine).void }
197
+ sig { params(instance_module: RBI::Module, machine: ::StateMachines::Machine).void }
200
198
  def define_event_methods(instance_module, machine)
201
199
  machine.events.each do |event|
202
- create_method(
203
- instance_module,
200
+ instance_module.create_method(
204
201
  "can_#{event.qualified_name}?",
205
202
  return_type: "T::Boolean"
206
203
  )
207
- create_method(
208
- instance_module,
204
+ instance_module.create_method(
209
205
  "#{event.qualified_name}_transition",
210
- parameters: [Parlour::RbiGenerator::Parameter.new("*args", type: "T.untyped")],
206
+ parameters: [create_rest_param("args", type: "T.untyped")],
211
207
  return_type: "T.nilable(::StateMachines::Transition)"
212
208
  )
213
- create_method(
214
- instance_module,
209
+ instance_module.create_method(
215
210
  event.qualified_name.to_s,
216
- parameters: [Parlour::RbiGenerator::Parameter.new("*args", type: "T.untyped")],
211
+ parameters: [create_rest_param("args", type: "T.untyped")],
217
212
  return_type: "T::Boolean"
218
213
  )
219
- create_method(
220
- instance_module,
214
+ instance_module.create_method(
221
215
  "#{event.qualified_name}!",
222
- parameters: [Parlour::RbiGenerator::Parameter.new("*args", type: "T.untyped")],
216
+ parameters: [create_rest_param("args", type: "T.untyped")],
223
217
  return_type: "T::Boolean"
224
218
  )
225
219
  end
@@ -227,106 +221,95 @@ module Tapioca
227
221
 
228
222
  sig do
229
223
  params(
230
- instance_module: Parlour::RbiGenerator::Namespace,
224
+ instance_module: RBI::Module,
231
225
  machine: ::StateMachines::Machine,
232
226
  state_type: String
233
227
  ).void
234
228
  end
235
229
  def define_state_accessor(instance_module, machine, state_type)
236
230
  attribute = machine.attribute.to_s
237
- create_method(
238
- instance_module,
231
+ instance_module.create_method(
239
232
  attribute,
240
233
  return_type: state_type
241
234
  )
242
- create_method(
243
- instance_module,
235
+ instance_module.create_method(
244
236
  "#{attribute}=",
245
- parameters: [Parlour::RbiGenerator::Parameter.new("value", type: state_type)],
237
+ parameters: [create_param("value", type: state_type)],
246
238
  return_type: state_type
247
239
  )
248
240
  end
249
241
 
250
- sig { params(instance_module: Parlour::RbiGenerator::Namespace, machine: ::StateMachines::Machine).void }
242
+ sig { params(instance_module: RBI::Module, machine: ::StateMachines::Machine).void }
251
243
  def define_state_predicate(instance_module, machine)
252
- create_method(
253
- instance_module,
244
+ instance_module.create_method(
254
245
  "#{machine.name}?",
255
- parameters: [Parlour::RbiGenerator::Parameter.new("state", type: "T.any(String, Symbol)")],
246
+ parameters: [create_param("state", type: "T.any(String, Symbol)")],
256
247
  return_type: "T::Boolean"
257
248
  )
258
249
  end
259
250
 
260
- sig { params(instance_module: Parlour::RbiGenerator::Namespace, machine: ::StateMachines::Machine).void }
251
+ sig { params(instance_module: RBI::Module, machine: ::StateMachines::Machine).void }
261
252
  def define_event_helpers(instance_module, machine)
262
253
  events_attribute = machine.attribute(:events).to_s
263
254
  transitions_attribute = machine.attribute(:transitions).to_s
264
255
  event_attribute = machine.attribute(:event).to_s
265
256
  event_transition_attribute = machine.attribute(:event_transition).to_s
266
257
 
267
- create_method(
268
- instance_module,
258
+ instance_module.create_method(
269
259
  events_attribute,
270
- parameters: [Parlour::RbiGenerator::Parameter.new("*args", type: "T.untyped")],
260
+ parameters: [create_rest_param("args", type: "T.untyped")],
271
261
  return_type: "T::Array[T.any(String, Symbol)]"
272
262
  )
273
- create_method(
274
- instance_module,
263
+ instance_module.create_method(
275
264
  transitions_attribute,
276
- parameters: [Parlour::RbiGenerator::Parameter.new("*args", type: "T.untyped")],
265
+ parameters: [create_rest_param("args", type: "T.untyped")],
277
266
  return_type: "T::Array[::StateMachines::Transition]"
278
267
  )
279
- create_method(
280
- instance_module,
268
+ instance_module.create_method(
281
269
  "fire_#{event_attribute}",
282
270
  parameters: [
283
- Parlour::RbiGenerator::Parameter.new("event", type: "T.any(String, Symbol)"),
284
- Parlour::RbiGenerator::Parameter.new("*args", type: "T.untyped"),
271
+ create_param("event", type: "T.any(String, Symbol)"),
272
+ create_rest_param("args", type: "T.untyped"),
285
273
  ],
286
274
  return_type: "T::Boolean"
287
275
  )
288
276
  if machine.action
289
- create_method(
290
- instance_module,
277
+ instance_module.create_method(
291
278
  event_attribute,
292
279
  return_type: "T.nilable(Symbol)"
293
280
  )
294
- create_method(
295
- instance_module,
281
+ instance_module.create_method(
296
282
  "#{event_attribute}=",
297
- parameters: [Parlour::RbiGenerator::Parameter.new("value", type: "T.any(String, Symbol)")],
283
+ parameters: [create_param("value", type: "T.any(String, Symbol)")],
298
284
  return_type: "T.any(String, Symbol)"
299
285
  )
300
- create_method(
301
- instance_module,
286
+ instance_module.create_method(
302
287
  event_transition_attribute,
303
288
  return_type: "T.nilable(::StateMachines::Transition)"
304
289
  )
305
- create_method(
306
- instance_module,
290
+ instance_module.create_method(
307
291
  "#{event_transition_attribute}=",
308
- parameters: [Parlour::RbiGenerator::Parameter.new("value", type: "::StateMachines::Transition")],
292
+ parameters: [create_param("value", type: "::StateMachines::Transition")],
309
293
  return_type: "::StateMachines::Transition"
310
294
  )
311
295
  end
312
296
  end
313
297
 
314
- sig { params(instance_module: Parlour::RbiGenerator::Namespace, machine: ::StateMachines::Machine).void }
298
+ sig { params(instance_module: RBI::Module, machine: ::StateMachines::Machine).void }
315
299
  def define_path_helpers(instance_module, machine)
316
300
  paths_attribute = machine.attribute(:paths).to_s
317
301
 
318
- create_method(
319
- instance_module,
302
+ instance_module.create_method(
320
303
  paths_attribute,
321
- parameters: [Parlour::RbiGenerator::Parameter.new("*args", type: "T.untyped")],
304
+ parameters: [create_rest_param("args", type: "T.untyped")],
322
305
  return_type: "T::Array[::StateMachines::Transition]"
323
306
  )
324
307
  end
325
308
 
326
309
  sig do
327
310
  params(
328
- instance_module: Parlour::RbiGenerator::Namespace,
329
- class_module: Parlour::RbiGenerator::Namespace,
311
+ instance_module: RBI::Module,
312
+ class_module: RBI::Module,
330
313
  machine: ::StateMachines::Machine
331
314
  ).void
332
315
  end
@@ -334,31 +317,27 @@ module Tapioca
334
317
  name_attribute = machine.attribute(:name).to_s
335
318
  event_name_attribute = machine.attribute(:event_name).to_s
336
319
 
337
- create_method(
338
- class_module,
320
+ class_module.create_method(
339
321
  "human_#{name_attribute}",
340
- parameters: [Parlour::RbiGenerator::Parameter.new("state", type: "T.any(String, Symbol)")],
322
+ parameters: [create_param("state", type: "T.any(String, Symbol)")],
341
323
  return_type: "String"
342
324
  )
343
- create_method(
344
- class_module,
325
+ class_module.create_method(
345
326
  "human_#{event_name_attribute}",
346
- parameters: [Parlour::RbiGenerator::Parameter.new("event", type: "T.any(String, Symbol)")],
327
+ parameters: [create_param("event", type: "T.any(String, Symbol)")],
347
328
  return_type: "String"
348
329
  )
349
- create_method(
350
- instance_module,
330
+ instance_module.create_method(
351
331
  name_attribute,
352
332
  return_type: "T.any(String, Symbol)"
353
333
  )
354
- create_method(
355
- instance_module,
334
+ instance_module.create_method(
356
335
  "human_#{name_attribute}",
357
336
  return_type: "String"
358
337
  )
359
338
  end
360
339
 
361
- sig { params(class_module: Parlour::RbiGenerator::Namespace, machine: ::StateMachines::Machine).void }
340
+ sig { params(class_module: RBI::Module, machine: ::StateMachines::Machine).void }
362
341
  def define_scopes(class_module, machine)
363
342
  helper_modules = machine.instance_variable_get(:@helper_modules)
364
343
  class_methods = helper_modules[:class].instance_methods(false)
@@ -366,10 +345,9 @@ module Tapioca
366
345
  class_methods
367
346
  .select { |method| method.to_s.start_with?("with_", "without_") }
368
347
  .each do |method|
369
- create_method(
370
- class_module,
348
+ class_module.create_method(
371
349
  method.to_s,
372
- parameters: [Parlour::RbiGenerator::Parameter.new("*states", type: "T.any(String, Symbol)")],
350
+ parameters: [create_rest_param("states", type: "T.any(String, Symbol)")],
373
351
  return_type: "T.untyped"
374
352
  )
375
353
  end