1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54
|
from typing import Optional
from xsdata.codegen.mixins import RelativeHandlerInterface
from xsdata.codegen.models import Attr, Class
from xsdata.utils.namespaces import build_qname
class UnnestInnerClasses(RelativeHandlerInterface):
"""Unnest class processor."""
__slots__ = ()
def process(self, target: Class):
"""
Promote enumeration classes to root classes.
Candidates
- Enumerations
- All if config is enabled
"""
for inner in list(target.inner):
if inner.is_enumeration or self.container.config.output.unnest_classes:
self.promote(target, inner)
def promote(self, target: Class, inner: Class):
target.inner.remove(inner)
attr = self.find_forward_attr(target, inner.qname)
if attr:
clone = self.clone_class(inner, target.name)
self.update_types(attr, inner.qname, clone.qname)
self.container.add(clone)
@classmethod
def clone_class(cls, inner: Class, name: str) -> Class:
clone = inner.clone()
clone.local_type = True
clone.qname = build_qname(inner.target_namespace, f"{name}_{inner.name}")
return clone
@classmethod
def update_types(cls, attr: Attr, search: str, replace: str):
for attr_type in attr.types:
if attr_type.qname == search and attr_type.forward:
attr_type.qname = replace
attr_type.forward = False
@classmethod
def find_forward_attr(cls, target: Class, qname: str) -> Optional[Attr]:
for attr in target.attrs:
for attr_type in attr.types:
if attr_type.forward and attr_type.qname == qname:
return attr
return None
|