def __new__(mcs, name, bases, dct): # Don't do anything special for Enum itself if not mcs.base_enum_type: result = type.__new__(mcs, name, bases, dct) mcs.base_enum_type = result return result location = extract_library_location() with Context('in {}'.format(name), location): check_source_language( bases == (Enum, ), 'Enumeration types must derive from and only from Enum' ) # Get the list of values, initializing their name values = [] for key, value in dct.items(): # Ignore __special__ fields if key.startswith('__') and key.endswith('__'): continue check_source_language( isinstance(value, EnumValue), 'Enum subclass can only contain EnumValue instances' ' (here, {} is {})'.format(key, value) ) check_source_language( value._type is None, 'EnumValue instances cannot be used in multiple Enum' ' subclasses (here: {})'.format(key) ) value._name = names.Name.from_lower(key) values.append(value) values.sort(key=lambda v: v._id) dct['_values'] = values DSLType._import_base_type_info(name, location, dct) # Create the subclass and associate values to it cls = type.__new__(mcs, name, bases, dct) for value in cls._values: value._type = cls # Now create the CompiledType instance, register it where needed enum_type = EnumType(cls._name, cls._location, cls._doc, [v._name for v in cls._values]) enum_type.dsl_decl = cls cls._type = enum_type # Associate the enumeration values in the DSL/Langkit internals for dsl_val, internal_val in zip(cls._values, enum_type.values): dsl_val._type = cls dsl_val._value = internal_val internal_val.dsl_decl = dsl_val return cls
def _enum_value(self): """ Return the _EnumType.Alternative instance corresponding to this instance. :rtype: _EnumType.Alternative """ assert self._type return _EnumType.Alternative(self._type, self.alt)