#!/usr/bin/env python3 """Offline contract check for conservative BSL symbol resolution.""" from __future__ import annotations import argparse import json import sys from pathlib import Path from typing import Any ROOT = Path(__file__).resolve().parents[1] sys.path.insert(0, str(ROOT / "scripts")) from resolve_1c_bsl_symbol import load_json, resolve_symbol # noqa: E402 METADATA = ROOT / "plugins" / "1c" / "metadata" / "examples" / "metadata-v2.example.json" MODULES = ROOT / "plugins" / "1c" / "metadata" / "examples" / "bsl-modules.example.json" def example_resolve(expression: str) -> dict[str, Any]: return resolve_symbol( load_json(METADATA), load_json(MODULES), expression=expression, module_id="catalog.Номенклатура.object", object_kind="catalog", object_name="Номенклатура", routine_name="ПередЗаписью", ) def main() -> int: parser = argparse.ArgumentParser(description="Check BSL symbol resolver safety contract.") parser.add_argument("--print", action="store_true") args = parser.parse_args() full_path = example_resolve("Справочник.Номенклатура.Артикул") context_member = example_resolve("Наименование") parameter = example_resolve("Отказ.Код") short_name = example_resolve("Номенклатура.ЕдИзмерение.Код") checks = { "full_metadata_path": full_path.get("resolution_kind") == "metadata_path" and full_path.get("canonical_path") == "Справочник.Номенклатура.Артикул" and full_path.get("safe_as_metadata_path") is True, "context_standard_attribute": context_member.get("resolution_kind") == "context_metadata_member" and context_member.get("canonical_path") == "Справочник.Номенклатура.Наименование", "parameter_not_metadata": parameter.get("resolution_kind") == "parameter" and parameter.get("safe_as_metadata_path") is False, "short_name_not_metadata": short_name.get("status") == "unresolved" and short_name.get("safe_as_metadata_path") is False and bool(short_name.get("candidates")), } failures = [name for name, ok in checks.items() if not ok] report = { "schema": "onec_bsl_symbol_resolver_check.v1", "status": "ok" if not failures else "failed", "failures": failures, "checks": checks, } if args.print: print(json.dumps(report, ensure_ascii=False, indent=2)) elif failures: print("1C BSL symbol resolver status: failed", file=sys.stderr) else: print("1C BSL symbol resolver status: ok") return 0 if not failures else 1 if __name__ == "__main__": raise SystemExit(main())