def _visit(self, node: Any) -> Optional[Any]: if isinstance(node, (YAMLRoot, dict)): if isinstance(node, YAMLRoot): node = self._add_type(node) for k, v in list(node.items()): if v: new_v = self._visit(v) if new_v is not None: node[k] = new_v elif isinstance(node, list): for i in range(0, len(node)): new_v = self._visit(node[i]) if new_v is not None: node[i] = new_v elif isinstance(node, set): for v in list(node): new_v = self._visit(v) if new_v is not None: node.remove(v) node.add(new_v) elif isinstance(node, ClassDefinitionName): return ClassDefinitionName(camelcase(node)) elif isinstance(node, SlotDefinitionName): return SlotDefinitionName(underscore(node)) elif isinstance(node, TypeDefinitionName): return TypeDefinitionName(underscore(node)) elif isinstance(node, SubsetDefinitionName): return SubsetDefinitionName(underscore(node)) elif isinstance(node, ElementName): return ClassDefinitionName(camelcase(node)) if node in self.schema.classes else \ SlotDefinitionName(underscore(node)) if node in self.schema.slots else \ SubsetDefinitionName(camelcase(node)) if node in self.schema.subsets else \ TypeDefinitionName(underscore(node)) if node in self.schema.types else None return None
def add_ref( self, fromtype: RefType, fromname: ElementName, totype: RefType, toname: ElementName, ) -> None: """ Add an inverse reference, indicating that to type/name is referenced by from type/name :param fromtype: Referencer type :param fromname: Referencer name :param totype: Referencee type :param toname: Referencee name :return: """ if totype is ClassType: self.classrefs.setdefault(ClassDefinitionName(toname), References()).addref(fromtype, fromname) elif totype is SlotType: self.slotrefs.setdefault(SlotDefinitionName(toname), References()).addref(fromtype, fromname) elif totype is TypeType: self.typerefs.setdefault(TypeDefinitionName(toname), References()).addref(fromtype, fromname) elif totype is SubsetType: self.subsetrefs.setdefault(SubsetDefinitionName(toname), References()).addref( fromtype, fromname) elif totype is EnumType: self.enumrefs.setdefault(SlotDefinitionName(toname), References()).addref(fromtype, fromname) else: raise TypeError("Unknown typ: {typ}")
def adjust_slot(self, slot: SlotDefinition) -> None: if slot.range in self.schema.classes: slot.range = ClassDefinitionName(camelcase(slot.range)) elif slot.range in self.schema.slots: slot.range = SlotDefinitionName(underscore(slot.range)) elif slot.range in self.schema.types: slot.range = TypeDefinitionName(underscore(slot.range)) slot.slot_uri = self.namespaces.uri_for(slot.slot_uri)
def slot_usage_name(usage_name: SlotDefinitionName, owning_class: ClassDefinition) -> SlotDefinitionName: """ Synthesize a unique name for an overridden slot :param usage_name: :param owning_class: :return: Synthesized name """ return SlotDefinitionName(extended_str.concat(owning_class.name, '_', usage_name))
def addref(self, fromtype: RefType, fromname: ElementName) -> None: if fromtype is ClassType: self.classrefs.add(ClassDefinitionName(fromname)) elif fromtype is TypeType: self.typerefs.add(TypeDefinitionName(fromname)) elif fromtype is SlotType: self.slotrefs.add(SlotDefinitionName(fromname)) elif fromtype is SubsetType: self.subsetrefs.add(SubsetDefinitionName(fromname)) elif fromtype is EnumType: self.slotrefs.add(EnumDefinitionName(fromname)) else: raise TypeError(f"Unknown typ: {fromtype}")
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)