Method: T::Enum.enums

Defined in:
lib/sorbet/eraser/t/enum.rb

.enums(&blk) ⇒ Object

Entrypoint for allowing people to register new enum values. All enum values must be defined within this block.



197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
# File 'lib/sorbet/eraser/t/enum.rb', line 197

def self.enums(&blk)
  raise "enums cannot be defined for T::Enum" if self == T::Enum
  raise "Enum #{self} was already initialized" if @fully_initialized
  raise "Enum #{self} is still initializing" if @started_initializing

  @started_initializing = true

  @values = nil

  yield

  @mapping = nil
  @mapping = {}

  # Freeze the Enum class and bind the constant names into each of the instances.
  self.constants(false).each do |const_name|
    instance = self.const_get(const_name, false)
    if !instance.is_a?(self)
      raise "Invalid constant #{self}::#{const_name} on enum. " \
        "All constants defined for an enum must be instances itself (e.g. `Foo = new`)."
    end

    instance._bind_name(const_name)
    serialized = instance.serialize
    if @mapping.include?(serialized)
      raise "Enum values must have unique serializations. Value '#{serialized}' is repeated on #{self}."
    end
    @mapping[serialized] = instance
  end
  @values.freeze
  @mapping.freeze

  orphaned_instances = @values - @mapping.values
  if !orphaned_instances.empty?
    raise "Enum values must be assigned to constants: #{orphaned_instances.map {|v| v.instance_variable_get('@serialized_val')}}"
  end

  @fully_initialized = true
end