Files
cdsl-cad/cadfs_to_cdsl/query_parser.py
T
2026-09-02 13:51:35 +08:00

52 lines
2.1 KiB
Python

from __future__ import annotations
from dataclasses import asdict, dataclass, field
from typing import Any
from .featurescript_parser import symbolic_string
from .ir import Call
@dataclass
class QueryInfo:
kind: str | None = None
owner_feature: str | None = None
topology_type: str | None = None
source_sketch: str | None = None
source_entity: str | None = None
is_start: bool | None = None
calls: list[str] = field(default_factory=list)
def as_dict(self) -> dict[str, Any]: return asdict(self)
def walk_calls(value: Any):
if isinstance(value, Call):
yield value
for arg in value.args: yield from walk_calls(arg)
elif isinstance(value, list):
for item in value: yield from walk_calls(item)
elif isinstance(value, dict):
for item in value.values(): yield from walk_calls(item)
def parse_query(value: Any) -> QueryInfo:
info = QueryInfo()
for call in walk_calls(value):
info.calls.append(call.name)
if call.name in {"makeQuery", "qCreatedBy"} and call.args:
owner = symbolic_string(call.args[0])
if "F" in owner:
tail = owner[owner.find("F"):].split(".", 1)[0]
info.owner_feature = tail
if call.name == "makeQuery" and len(call.args) > 2:
info.topology_type = str(call.args[1]); info.kind = str(call.args[2]).lower()
definition = next((arg for arg in call.args if isinstance(arg, dict)), {})
if isinstance(definition.get("isStart"), str): info.is_start = definition["isStart"].lower() == "true"
elif "isStart" in definition: info.is_start = bool(definition["isStart"])
if call.name in {"sQuery", "sketchEntityQuery"} and len(call.args) >= 3:
sketch = symbolic_string(call.args[0]); info.source_sketch = sketch.split(".", 1)[0]
info.kind = str(call.args[1]).lower(); info.source_entity = str(call.args[2])
if call.name == "qSketchRegion" and call.args:
info.source_sketch = symbolic_string(call.args[0]); info.kind = "face"
return info