예제 #1
0
 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!")
예제 #2
0
    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}`"
            )
예제 #3
0
    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)
예제 #4
0
    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)