124 lines
3.0 KiB
Python
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
|
|
)
|