Files
chinook/chinook/models/_target.py
T

124 lines
3.0 KiB
Python

import yaml
from dataclasses import dataclass
from dataclasses import field
from typing import ClassVar
from typing import Self
from ._accessor import Accessor
from ._includes import Includes
from ._output import Output
# TODO: Handle C/C++ standards.
@dataclass
class Target(yaml.YAMLObject):
yaml_dumper: ClassVar[type[yaml.SafeDumper]] = yaml.SafeDumper
yaml_loader: ClassVar[type[yaml.SafeLoader]] = yaml.SafeLoader
yaml_tag: ClassVar[str] = u"!target"
name: str
type: Output
incs: Includes
opts: list[Accessor] = field(default_factory=list)
defs: list[Accessor] = field(default_factory=list)
deps: list[Accessor] = field(default_factory=list)
libs: list[Accessor] = field(default_factory=list)
srcs: list[Accessor] = field(default_factory=list)
# Internal to the tool.
_flattend: bool = field(init=False,default=False)
_prepared: bool = field(init=False,default=False)
_rebuilt: bool = field(init=False,default=False)
def __deepcopy__(self, memo) -> Self:
return Target(
self.name,
self.type,
Includes(
list(self.incs.includes),
list(self.incs.libraries)
),
list(self.opts),
list(self.defs),
list(self.deps),
list(self.libs),
list(self.srcs)
)
@classmethod
def to_dict(cls, data: Self) -> dict:
return {
"name": data.name,
"type": data.type,
"incs": Includes.to_dict(data.incs),
"opts": Accessor.to_list(data.opts),
"defs": Accessor.to_list(data.defs),
"deps": Accessor.to_list(data.deps),
"libs": Accessor.to_list(data.libs),
"srcs": Accessor.to_list(data.srcs)
}
@classmethod
def to_list(cls, data: list[Self]) -> list[dict]:
return [Target.to_dict(v) for v in data]
@classmethod
def to_yaml(
cls,
dumper: yaml.SafeDumper,
data: yaml.YAMLObject
) -> yaml.Node:
if not isinstance(data, Target):
raise ValueError
return dumper.represent_mapping(
"tag:yaml.org,2002:map",
cls.to_dict(data)
)
@classmethod
def from_dict(cls, data: dict) -> Self:
def bad_attr(name: str, obj: dict) -> None:
raise AttributeError(name=name,obj=obj)
return cls(**{
"name": data.get("name") or bad_attr("name", data),
"type": data.get("type") or bad_attr("type", data),
"incs": Includes.from_dict(data.get("incs", {})),
"opts": Accessor.from_list(data.get("opts", [])),
"defs": Accessor.from_list(data.get("defs", [])),
"deps": Accessor.from_list(data.get("deps", [])),
"libs": Accessor.from_list(data.get("libs", [])),
"srcs": Accessor.from_list(data.get("srcs", []))
})
@classmethod
def from_list(cls, data: list[dict]) -> list[Self]:
return [
v if isinstance(v, Target) \
else Target.from_dict(v)
for v in data
]
@classmethod
def from_yaml(
cls,
loader: yaml.SafeLoader,
node: yaml.Node
) -> Self:
return cls.from_dict(
loader.construct_mapping(node, deep=True)
)
Target.yaml_dumper.add_representer(
Target.yaml_tag,
Target.to_yaml
)
Target.yaml_loader.add_constructor(
Target.yaml_tag,
Target.from_yaml
)