Class: Tapioca::Dsl::Compilers::StateMachines

Inherits:
Tapioca::Dsl::Compiler show all
Extended by:
T::Sig
Defined in:
lib/tapioca/dsl/compilers/state_machines.rb

Overview

‘Tapioca::Dsl::Compilers::StateMachines` generates RBI files for classes that setup a [`state_machine`](github.com/state-machines/state_machines). The compiler also processes the extra methods generated by [StateMachines Active Record](github.com/state-machines/state_machines-activerecord) and [StateMachines Active Model](github.com/state-machines/state_machines-activemodel) integrations.

For example, with the following ‘Vehicle` class:

~~~rb class Vehicle

state_machine :alarm_state, initial: :active, namespace: :'alarm' do
  event :enable do
    transition all => :active
  end

  event :disable do
    transition all => :off
  end

  state :active, :value => 1
  state :off, :value => 0
end

end ~~~

this compiler will produce the RBI file ‘vehicle.rbi` with the following content:

~~~rbi # vehicle.rbi # typed: true class Vehicle

include StateMachineInstanceHelperModule
extend StateMachineClassHelperModule

module StateMachineClassHelperModule
  sig { params(event: T.any(String, Symbol)).returns(String) }
  def human_alarm_state_event_name(event); end

  sig { params(state: T.any(String, Symbol)).returns(String) }
  def human_alarm_state_name(state); end
end

module StateMachineInstanceHelperModule
  sig { returns(T::Boolean) }
  def alarm_active?; end

  sig { returns(T::Boolean) }
  def alarm_off?; end

  sig { returns(Integer) }
  def alarm_state; end

  sig { params(value: Integer).returns(Integer) }
  def alarm_state=(value); end

  sig { params(state: T.any(String, Symbol)).returns(T::Boolean) }
  def alarm_state?(state); end

  sig { params(args: T.untyped).returns(T::Array[T.any(String, Symbol)]) }
  def alarm_state_events(*args); end

  sig { returns(T.any(String, Symbol)) }
  def alarm_state_name; end

  sig { params(args: T.untyped).returns(T::Array[::StateMachines::Transition]) }
  def alarm_state_paths(*args); end

  sig { params(args: T.untyped).returns(T::Array[::StateMachines::Transition]) }
  def alarm_state_transitions(*args); end

  sig { returns(T::Boolean) }
  def can_disable_alarm?; end

  sig { returns(T::Boolean) }
  def can_enable_alarm?; end

  sig { params(args: T.untyped).returns(T::Boolean) }
  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.nilable(::StateMachines::Transition)) }
  def disable_alarm_transition(*args); end

  sig { params(args: T.untyped).returns(T::Boolean) }
  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.nilable(::StateMachines::Transition)) }
  def enable_alarm_transition(*args); end

  sig { params(event: T.any(String, Symbol), args: T.untyped).returns(T::Boolean) }
  def fire_alarm_state_event(event, *args); end

  sig { returns(String) }
  def human_alarm_state_name; end
end

end ~~~

Constant Summary collapse

ConstantType =
type_member { { fixed: T.all(Module, ::StateMachines::ClassMethods) } }

Constants included from Runtime::Reflection

Runtime::Reflection::ANCESTORS_METHOD, Runtime::Reflection::CLASS_METHOD, Runtime::Reflection::CONSTANTS_METHOD, Runtime::Reflection::EQUAL_METHOD, Runtime::Reflection::METHOD_METHOD, Runtime::Reflection::NAME_METHOD, Runtime::Reflection::OBJECT_ID_METHOD, Runtime::Reflection::PRIVATE_INSTANCE_METHODS_METHOD, Runtime::Reflection::PROTECTED_INSTANCE_METHODS_METHOD, Runtime::Reflection::PUBLIC_INSTANCE_METHODS_METHOD, Runtime::Reflection::REQUIRED_FROM_LABELS, Runtime::Reflection::SINGLETON_CLASS_METHOD, Runtime::Reflection::SUPERCLASS_METHOD, Runtime::Reflection::UNDEFINED_CONSTANT

Constants included from SorbetHelper

SorbetHelper::FEATURE_REQUIREMENTS, SorbetHelper::SORBET_BIN, SorbetHelper::SORBET_EXE_PATH_ENV_VAR, SorbetHelper::SORBET_GEM_SPEC, SorbetHelper::SORBET_PAYLOAD_URL, SorbetHelper::SPOOM_CONTEXT

Instance Attribute Summary

Attributes inherited from Tapioca::Dsl::Compiler

#constant, #root

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Tapioca::Dsl::Compiler

#add_error, #compiler_enabled?, handles?, #initialize, processable_constants

Methods included from T::Generic::TypeStoragePatch

#[], #has_attached_class!, #type_member, #type_template

Methods included from Runtime::Reflection

#abstract_type_of, #ancestors_of, #are_equal?, #class_of, #constant_defined?, #constantize, #constants_of, #descendants_of, #file_candidates_for, #final_module?, #inherited_ancestors_of, #method_of, #name_of, #name_of_type, #object_id_of, #private_instance_methods_of, #protected_instance_methods_of, #public_instance_methods_of, #qualified_name_of, #resolve_loc, #sealed_module?, #signature_of, #singleton_class_of, #superclass_of

Methods included from Runtime::AttachedClassOf

#attached_class_of

Methods included from RBIHelper

#as_nilable_type, #create_block_param, #create_kw_opt_param, #create_kw_param, #create_kw_rest_param, #create_opt_param, #create_param, #create_rest_param, #create_typed_param, #sanitize_signature_types, serialize_type_variable, #valid_method_name?, #valid_parameter_name?

Methods included from SorbetHelper

#sorbet, #sorbet_path, #sorbet_supports?

Constructor Details

This class inherits a constructor from Tapioca::Dsl::Compiler

Class Method Details

.gather_constantsObject



161
162
163
# File 'lib/tapioca/dsl/compilers/state_machines.rb', line 161

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

Instance Method Details

#decorateObject



118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
# File 'lib/tapioca/dsl/compilers/state_machines.rb', line 118

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