Source code for xsdata.codegen.analyzer

from typing import List

from xsdata.codegen.container import ClassContainer
from xsdata.codegen.models import Class
from xsdata.codegen.sanitizer import ClassSanitizer
from xsdata.codegen.validator import ClassValidator
from xsdata.exceptions import AnalyzerValueError


[docs]class ClassAnalyzer: """Validate, analyze, sanitize and select the final class list to be generated."""
[docs] @classmethod def process(cls, classes: List[Class]) -> List[Class]: """Run all the processes.""" # Wrap classes with container for easy access. container = ClassContainer.from_list(classes) # Run validation checks for duplicate, invalid and redefined types. ClassValidator.process(container) # Run analyzer handlers container.process() # Sanitize class attributes after merging and flattening types and extensions. ClassSanitizer.process(container) # Select final list of classes to be generated. return cls.select_classes(container)
[docs] @classmethod def select_classes(cls, container: ClassContainer) -> List[Class]: """ Return the qualified classes for code generation. Return all if no classes are derived from xs:element or xs:complexType. """ classes = list(container.iterate()) if any(item.is_complex for item in classes): classes = list( filter( lambda x: x.is_enumeration or (x.is_complex and not x.strict_type), classes, ) ) cls.validate_references(classes) return classes
[docs] @classmethod def class_references(cls, target: Class) -> List: """Produce a list of instance references for the given class.""" result = [id(target)] for attr in target.attrs: result.append(id(attr)) result.extend(id(attr_type) for attr_type in attr.types) for extension in target.extensions: result.append(id(extension)) result.append(id(extension.type)) for inner in target.inner: result.extend(cls.class_references(inner)) return result
[docs] @classmethod 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!")