class Tapioca::Dsl::Compilers::StateMachines

~~~
end
end
def human_alarm_state_name; end
sig { returns(String) }
def fire_alarm_state_event(event, *args); end
sig { params(event: T.any(String, Symbol), args: T.untyped).returns(T::Boolean) }
def enable_alarm_transition(*args); end
sig { params(args: T.untyped).returns(T.nilable(::StateMachines::Transition)) }
def enable_alarm!(*args); end
sig { params(args: T.untyped).returns(T::Boolean) }
def enable_alarm(*args); end
sig { params(args: T.untyped).returns(T::Boolean) }
def disable_alarm_transition(*args); end
sig { params(args: T.untyped).returns(T.nilable(::StateMachines::Transition)) }
def disable_alarm!(*args); end
sig { params(args: T.untyped).returns(T::Boolean) }
def disable_alarm(*args); end
sig { params(args: T.untyped).returns(T::Boolean) }
def can_enable_alarm?; end
sig { returns(T::Boolean) }
def can_disable_alarm?; end
sig { returns(T::Boolean) }
def alarm_state_transitions(*args); end
sig { params(args: T.untyped).returns(T::Array) }
def alarm_state_paths(*args); end
sig { params(args: T.untyped).returns(T::Array) }
def alarm_state_name; end
sig { returns(T.any(String, Symbol)) }
def alarm_state_events(*args); end
sig { params(args: T.untyped).returns(T::Array[T.any(String, Symbol)]) }
def alarm_state?(state); end
sig { params(state: T.any(String, Symbol)).returns(T::Boolean) }
def alarm_state=(value); end
sig { params(value: Integer).returns(Integer) }
def alarm_state; end
sig { returns(Integer) }
def alarm_off?; end
sig { returns(T::Boolean) }
def alarm_active?; end
sig { returns(T::Boolean) }
module StateMachineInstanceHelperModule
end
def human_alarm_state_name(state); end
sig { params(state: T.any(String, Symbol)).returns(String) }
def human_alarm_state_event_name(event); end
sig { params(event: T.any(String, Symbol)).returns(String) }
module StateMachineClassHelperModule
extend StateMachineClassHelperModule
include StateMachineInstanceHelperModule
class Vehicle
# typed: true
# vehicle.rbi
~~~rbi
this compiler will produce the RBI file ‘vehicle.rbi` with the following content:
~~~
end
end
state :off, :value => 0
state :active, :value => 1
end
transition all => :off
event :disable do
end
transition all => :active
event :enable do
state_machine :alarm_state, initial: :active, namespace: :’alarm’ do
class Vehicle
~~~rb
For example, with the following ‘Vehicle` class:
integrations.
and [StateMachines Active Model](github.com/state-machines/state_machines-activemodel)
[StateMachines Active Record](github.com/state-machines/state_machines-activerecord)
processes the extra methods generated by<br>(github.com/state-machines/state_machines). The compiler also
`Tapioca::Dsl::Compilers::StateMachines` generates RBI files for classes that setup a

def decorate

def decorate
  return if constant.state_machines.empty?
  root.create_path(T.unsafe(constant)) do |klass|
    instance_module_name = "StateMachineInstanceHelperModule"
    class_module_name = "StateMachineClassHelperModule"
    instance_module = RBI::Module.new(instance_module_name)
    klass << instance_module
    class_module = RBI::Module.new(class_module_name)
    klass << class_module
    constant.state_machines.each_value do |machine|
      state_type = state_type_for(machine)
      define_state_accessor(instance_module, machine, state_type)
      define_state_predicate(instance_module, machine)
      define_event_helpers(instance_module, machine)
      define_path_helpers(instance_module, machine)
      define_name_helpers(instance_module, class_module, machine)
      define_scopes(class_module, machine)
      define_state_methods(instance_module, machine)
      define_event_methods(instance_module, machine)
    end
    matching_integration_name = ::StateMachines::Integrations.match(constant)&.integration_name
    case matching_integration_name
    when :active_record
      define_activerecord_methods(instance_module)
    end
    klass.create_include(instance_module_name)
    klass.create_extend(class_module_name)
  end
end

def define_activerecord_methods(instance_module)

def define_activerecord_methods(instance_module)
  instance_module.create_method(
    "changed_for_autosave?",
    return_type: "T::Boolean",
  )
end

def define_event_helpers(instance_module, machine)

def define_event_helpers(instance_module, machine)
  events_attribute = machine.attribute(:events).to_s
  transitions_attribute = machine.attribute(:transitions).to_s
  event_attribute = machine.attribute(:event).to_s
  event_transition_attribute = machine.attribute(:event_transition).to_s
  instance_module.create_method(
    events_attribute,
    parameters: [create_rest_param("args", type: "T.untyped")],
    return_type: "T::Array[T.any(String, Symbol)]",
  )
  instance_module.create_method(
    transitions_attribute,
    parameters: [create_rest_param("args", type: "T.untyped")],
    return_type: "T::Array[::StateMachines::Transition]",
  )
  instance_module.create_method(
    "fire_#{event_attribute}",
    parameters: [
      create_param("event", type: "T.any(String, Symbol)"),
      create_rest_param("args", type: "T.untyped"),
    ],
    return_type: "T::Boolean",
  )
  if machine.action
    instance_module.create_method(
      event_attribute,
      return_type: "T.nilable(Symbol)",
    )
    instance_module.create_method(
      "#{event_attribute}=",
      parameters: [create_param("value", type: "T.any(String, Symbol)")],
      return_type: "T.any(String, Symbol)",
    )
    instance_module.create_method(
      event_transition_attribute,
      return_type: "T.nilable(::StateMachines::Transition)",
    )
    instance_module.create_method(
      "#{event_transition_attribute}=",
      parameters: [create_param("value", type: "::StateMachines::Transition")],
      return_type: "::StateMachines::Transition",
    )
  end
end

def define_event_methods(instance_module, machine)

def define_event_methods(instance_module, machine)
  machine.events.each do |event|
    instance_module.create_method(
      "can_#{event.qualified_name}?",
      return_type: "T::Boolean",
    )
    instance_module.create_method(
      "#{event.qualified_name}_transition",
      parameters: [create_rest_param("args", type: "T.untyped")],
      return_type: "T.nilable(::StateMachines::Transition)",
    )
    instance_module.create_method(
      event.qualified_name.to_s,
      parameters: [create_rest_param("args", type: "T.untyped")],
      return_type: "T::Boolean",
    )
    instance_module.create_method(
      "#{event.qualified_name}!",
      parameters: [create_rest_param("args", type: "T.untyped")],
      return_type: "T::Boolean",
    )
  end
end

def define_name_helpers(instance_module, class_module, machine)

def define_name_helpers(instance_module, class_module, machine)
  name_attribute = machine.attribute(:name).to_s
  event_name_attribute = machine.attribute(:event_name).to_s
  class_module.create_method(
    "human_#{name_attribute}",
    parameters: [create_param("state", type: "T.any(String, Symbol)")],
    return_type: "String",
  )
  class_module.create_method(
    "human_#{event_name_attribute}",
    parameters: [create_param("event", type: "T.any(String, Symbol)")],
    return_type: "String",
  )
  instance_module.create_method(
    name_attribute,
    return_type: "T.any(String, Symbol)",
  )
  instance_module.create_method(
    "human_#{name_attribute}",
    return_type: "String",
  )
end

def define_path_helpers(instance_module, machine)

def define_path_helpers(instance_module, machine)
  paths_attribute = machine.attribute(:paths).to_s
  instance_module.create_method(
    paths_attribute,
    parameters: [create_rest_param("args", type: "T.untyped")],
    return_type: "T::Array[::StateMachines::Transition]",
  )
end

def define_scopes(class_module, machine)

def define_scopes(class_module, machine)
  helper_modules = machine.instance_variable_get(:@helper_modules)
  class_methods = helper_modules[:class].instance_methods(false)
  class_methods
    .select { |method| method.to_s.start_with?("with_", "without_") }
    .each do |method|
      class_module.create_method(
        method.to_s,
        parameters: [create_rest_param("states", type: "T.any(String, Symbol)")],
        return_type: "T.untyped",
      )
    end
end

def define_state_accessor(instance_module, machine, state_type)

def define_state_accessor(instance_module, machine, state_type)
  attribute = machine.attribute.to_s
  instance_module.create_method(
    attribute,
    return_type: state_type,
  ) if ::StateMachines::HelperModule === machine.owner_class.instance_method(attribute).owner
  instance_module.create_method(
    "#{attribute}=",
    parameters: [create_param("value", type: state_type)],
    return_type: state_type,
  ) if ::StateMachines::HelperModule === machine.owner_class.instance_method("#{attribute}=").owner
end

def define_state_methods(instance_module, machine)

def define_state_methods(instance_module, machine)
  machine.states.each do |state|
    instance_module.create_method(
      "#{state.qualified_name}?",
      return_type: "T::Boolean",
    )
  end
end

def define_state_predicate(instance_module, machine)

def define_state_predicate(instance_module, machine)
  instance_module.create_method(
    "#{machine.name}?",
    parameters: [create_param("state", type: "T.any(String, Symbol)")],
    return_type: "T::Boolean",
  )
end

def gather_constants

def gather_constants
  all_classes.select { |mod| ::StateMachines::InstanceMethods > mod }
end

def state_type_for(machine)

def state_type_for(machine)
  value_types = machine.states.map { |state| state.value.class.name }.uniq
  if value_types.size == 1
    value_types.first
  else
    "T.any(#{value_types.join(", ")})"
  end
end