示例#1
0
    def merge_slot(self, slot: SlotDefinition,
                   merged_slots: List[SlotDefinitionName]) -> None:
        """
        Merge parent slot information into target slot

        :param slot: target slot
        :param merged_slots: list of slot names that have been merged.  Used to do a distal ancestor resolution
        """
        if slot.name not in merged_slots:
            if slot.is_a:
                if slot.is_a in self.schema.slots:
                    self.merge_slot(self.schema.slots[slot.is_a], merged_slots)
                    merge_slots(slot, self.schema.slots[slot.is_a])
                else:
                    self.raise_value_error(
                        f'Slot: "{slot.name}" - unknown is_a reference: {slot.is_a}'
                    )
            for mixin in slot.mixins:
                if mixin in self.schema.slots:
                    self.merge_slot(self.schema.slots[mixin], merged_slots)
                    merge_slots(slot, self.schema.slots[mixin])
                else:
                    self.raise_value_error(
                        f'Slot: "{slot.name}" - unknown mixin reference: {mixin}'
                    )
            merged_slots.append(slot.name)
示例#2
0
    def process_slot_usages(self, cls: ClassDefinition) -> None:
        """
        Connect any slot usage items

        :param cls: class to process
        :return: usage item
        """
        for slotname, slot_usage in cls.slot_usage.items():
            if slot_usage.alias:
                self.raise_value_error(f'Class: "{cls.name}" - alias not permitted in slot_usage slot:'
                                       f' {slot_usage.alias}')
            # Construct a new slot
            # If we've already assigned a parent, use it

            parent_slot = self.schema.slots.get(slot_usage.is_a)
            # Follow the ancestry of the class to get the most proximal parent
            if not parent_slot:
                parent_slot = self.slot_definition_for(slotname, cls)
            if not parent_slot and slotname in self.schema.slots:
                parent_slot = self.schema.slots[slotname]

            if not parent_slot:
                # This test is here because it is really easy to break things in the slot merge utilities.  It should
                # stay
                self.logger.error(f'class "{cls.name}" slot "{slotname}" -- error occurred. This should not happen')
            else:
                child_name = slot_usage_name(slotname, cls)
                slot_alias = parent_slot.alias if parent_slot.alias else slotname
            new_slot = SlotDefinition(name=child_name, alias=slot_alias, domain=cls.name, is_usage_slot=Bool(True),
                                      usage_slot_name=slotname, owner=cls.name, domain_of=[cls.name],
                                      imported_from=cls.imported_from)
            self.schema.slots[child_name] = new_slot
            merge_slots(new_slot, slot_usage, inheriting=False, skip=['name', 'alias', 'domain', 'is_usage_slot',
                                                                      'usage_slot_name', 'owner', 'domain_of'])

            # Copy the parent definition.  If there is no parent definition, the slot is being defined
            # locally as a slot_usage
            if parent_slot is not None:
                new_slot.is_a = parent_slot.name
                merge_slots(new_slot, parent_slot)
                # This situation occurs when we are doing chained overrides.  Kludgy, but it works...
                if parent_slot.name in cls.slots:
                    if child_name in cls.slots:
                        del cls.slots[cls.slots.index(child_name)]
                    cls.slots[cls.slots.index(parent_slot.name)] = child_name
                elif child_name not in cls.slots:
                    cls.slots.append(child_name)
            elif not new_slot.range:
                new_slot.range = self.schema.default_range
示例#3
0
 def merge_type(self, typ: TypeDefinition, merged_types: List[TypeDefinitionName]) -> None:
     """
     Merge parent type information into target type
     :param typ: target type
     :param merged_types: list of type names that have bee merged.
     """
     if typ.name not in merged_types:
         if typ.typeof:
             if typ.typeof in self.schema.types:
                 reftyp = self.schema.types[cast(TypeDefinitionName, typ.typeof)]
                 self.merge_type(reftyp, merged_types)
                 merge_slots(typ, reftyp, [SlotDefinitionName('imported_from')])
             else:
                 self.raise_value_error(f'Type: "{typ.name}" - unknown typeof reference: {typ.typeof}', typ.typeof)
         merged_types.append(typ.name)
示例#4
0
    def process_slot_usages(self, cls: ClassDefinition) -> None:
        """
        Connect any slot usage items

        :param cls: class to process
        :return: usage item
        """
        for slotname, slot_usage in cls.slot_usage.items():
            if slot_usage.alias:
                self.raise_value_error(f'Class: "{cls.name}" - alias not permitted in slot_usage slot:'
                                       f' {slot_usage.alias}')
            # Construct a new slot
            # Follow the ancestry of the class to get the most proximal parent
            parent_slot = self.slot_definition_for(slotname, cls)
            if not parent_slot and slotname in self.schema.slots:
                parent_slot = self.schema.slots[slotname]

            # If parent slot is still not defined, it means that we introduced a NEW slot in the slot usages
            if not parent_slot:
                self.logger.warning(f'class "{cls.name}" slot "{slotname}" does not reference an existing slot.  '
                                    f'New slot was created.')
                child_name = slotname
                slot_alias = None
            else:
                child_name = slot_usage_name(slotname, cls)
                slot_alias = parent_slot.alias if parent_slot.alias else slotname
            new_slot = SlotDefinition(name=child_name, alias=slot_alias, domain=cls.name, is_usage_slot=Bool(True),
                                      usage_slot_name=slotname, owner=cls.name, domain_of=[cls.name])
            self.schema.slots[child_name] = new_slot
            merge_slots(new_slot, slot_usage, inheriting=False)

            # Copy the parent definition.  If there is no parent definition, the slot is being defined
            # locally as a slot_usage
            if parent_slot is not None:
                new_slot.is_a = parent_slot.name
                merge_slots(new_slot, parent_slot)
                # This situation occurs when we are doing chained overrides.  Kludgy, but it works...
                if parent_slot.name in cls.slots:
                    if child_name in cls.slots:
                        del cls.slots[cls.slots.index(child_name)]
                    cls.slots[cls.slots.index(parent_slot.name)] = child_name
                else:
                    cls.slots.append(child_name)
示例#5
0
    def process_slot_usages(self, cls: ClassDefinition) -> None:
        """
        Connect any slot usage items

        :param cls: class to process
        :return: usage item
        """
        for slotname, slot_usage in cls.slot_usage.items():
            # Construct a new slot
            # Follow the ancestry of the class to get the most proximal parent
            parent_slot = self.slot_definition_for(slotname, cls)
            if not parent_slot and slotname in self.schema.slots:
                parent_slot = self.schema.slots[slotname]

            # If parent slot is still not defined, it means that we introduced a NEW slot in the slot usages
            if not parent_slot:
                print(
                    f'Warning: class "{cls.name}" slot "{slotname}" does not reference an existing slot.  '
                    f'New slot was created.',
                    file=sys.stderr)
                child_name = slotname
                slot_alias = None
            else:
                child_name = slot_usage_name(slotname, cls)
                slot_alias = slotname
            new_slot = SlotDefinition(name=child_name,
                                      alias=slot_alias,
                                      domain=cls.name,
                                      is_usage_slot=True)
            self.schema.slots[child_name] = new_slot
            merge_slots(new_slot, slot_usage)

            # Copy the parent definition.  If there is no parent definition, the slot is being defined
            # locally as a slot_usage
            if parent_slot is not None:
                new_slot.is_a = parent_slot.name
                merge_slots(new_slot, parent_slot)
                # This situation occurs when we are doing chained overrides.  Kludgy, but it works...
                if parent_slot.name in cls.slots:
                    if child_name in cls.slots:
                        del cls.slots[cls.slots.index(child_name)]
                    cls.slots[cls.slots.index(parent_slot.name)] = child_name