def validate_references(cls, classes: List[Class]): """Validate all code gen objects are not cross referenced.""" references = [ ref for obj in classes for ref in cls.class_references(obj) ] if len(references) != len(set(references)): raise AnalyzerValueError("Cross references detected!")
def process_simple_dependency(cls, source: Class, target: Class, attr: Attr, attr_type: AttrType): """ Replace the given attribute type with the types of the single field source class. Ignore enumerations and gracefully handle dump types with no attributes. :raises: AnalyzerValueError if the source class has more than one attributes """ if source.is_enumeration: return total = len(source.attrs) if total == 0: cls.reset_attribute_type(attr_type) elif total == 1: source_attr = source.attrs[0] index = attr.types.index(attr_type) attr.types.pop(index) for source_attr_type in source_attr.types: clone_type = source_attr_type.clone() attr.types.insert(index, clone_type) index += 1 restrictions = source_attr.restrictions.clone() restrictions.merge(attr.restrictions) attr.restrictions = restrictions ClassUtils.copy_inner_classes(source, target) else: raise AnalyzerValueError( f"{source.type.__name__} with more than one attribute: `{source.name}`" )
def process(cls, target: Class): """Process classes that contain attributes derived from xs:enumeration and any other xs element.""" if target.is_enumeration or not any(attr.is_enumeration for attr in target.attrs): return enumerations = [] for attr in list(target.attrs): if attr.is_enumeration: target.attrs.remove(attr) enumerations.append(attr) if len(target.attrs) > 1: raise AnalyzerValueError( "Mixed enumeration with more than one normal field.") enum_inner = next( (inner for inner in target.inner if inner.is_enumeration), None) if not enum_inner: enum_inner = Class( name="value", type=SimpleType, module=target.module, package=target.package, mixed=False, abstract=False, nillable=False, ) target.attrs[0].types.append(AttrType(name="value", forward=True)) target.inner.append(enum_inner) enum_inner.attrs.extend(enumerations)
def process_attribute(self, target: Class, attr: Attr): """ Find the source class the attribute refers to and copy its attributes to the target class. :raises AnalyzerValueError: if source class is not found. """ qname = attr.types[0].qname # group attributes have one type only. source = self.container.find(qname, condition=lambda x: x.type in (AttributeGroup, Group)) if not source: raise AnalyzerValueError(f"Group attribute not found: `{qname}`") if source is target: target.attrs.remove(attr) else: ClassUtils.copy_group_attributes(source, target, attr)