Детализирована документация. Небольшие изменения имен параметров.
This commit is contained in:
@@ -0,0 +1,89 @@
|
||||
"""Индексация BSL-модулей конфигурации."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import re
|
||||
from dataclasses import dataclass
|
||||
from pathlib import Path
|
||||
|
||||
from .config import OBJECT_TYPE_FOLDERS
|
||||
|
||||
# Процедура/Функция Имя(...)
|
||||
RE_SYMBOL = re.compile(
|
||||
r"(?im)^\s*(?:&[А-Яа-яA-Za-z_]+)*\s*"
|
||||
r"(?:Процедура|Функция|Procedure|Function)\s+"
|
||||
r"([А-Яа-яA-Za-z_][А-Яа-яA-Za-z0-9_]*)"
|
||||
)
|
||||
|
||||
# Лимит тела для FTS (символы) — полные гигантские модули не кладём целиком.
|
||||
MAX_BODY_CHARS = 200_000
|
||||
|
||||
|
||||
@dataclass
|
||||
class ModuleRec:
|
||||
config: str
|
||||
rel_path: str
|
||||
abs_path: str
|
||||
owner: str
|
||||
module_kind: str
|
||||
symbols: list[str]
|
||||
body: str
|
||||
line_count: int
|
||||
size: int
|
||||
mtime_ns: int
|
||||
|
||||
|
||||
def _module_kind(rel: Path) -> str:
|
||||
name = rel.name
|
||||
if name == "Module.bsl":
|
||||
parent = rel.parent.name
|
||||
if parent == "Form":
|
||||
return "FormModule"
|
||||
if parent == "Ext":
|
||||
# CommonModules/.../Ext/Module.bsl или HTTPServices/.../Ext/Module.bsl
|
||||
return "Module"
|
||||
return "Module"
|
||||
if name.endswith("Module.bsl"):
|
||||
return name[: -len(".bsl")] # ObjectModule, ManagerModule, ...
|
||||
return name
|
||||
|
||||
|
||||
def _owner_from_rel(rel: Path) -> str:
|
||||
"""Documents/ЗаказКлиента/Ext/ObjectModule.bsl → Document.ЗаказКлиента."""
|
||||
parts = rel.parts
|
||||
if not parts:
|
||||
return ""
|
||||
folder = parts[0]
|
||||
otype = OBJECT_TYPE_FOLDERS.get(folder)
|
||||
if otype and len(parts) >= 2:
|
||||
return f"{otype}.{parts[1]}"
|
||||
return folder
|
||||
|
||||
|
||||
def parse_bsl_file(path: Path, *, config: str, src_root: Path) -> ModuleRec | None:
|
||||
try:
|
||||
st = path.stat()
|
||||
text = path.read_text(encoding="utf-8-sig", errors="replace")
|
||||
except OSError:
|
||||
return None
|
||||
rel = path.relative_to(src_root).as_posix()
|
||||
symbols = sorted(set(RE_SYMBOL.findall(text)))
|
||||
body = text if len(text) <= MAX_BODY_CHARS else text[:MAX_BODY_CHARS]
|
||||
return ModuleRec(
|
||||
config=config,
|
||||
rel_path=rel,
|
||||
abs_path=str(path),
|
||||
owner=_owner_from_rel(Path(rel)),
|
||||
module_kind=_module_kind(Path(rel)),
|
||||
symbols=symbols,
|
||||
body=body,
|
||||
line_count=text.count("\n") + (1 if text and not text.endswith("\n") else 0),
|
||||
size=st.st_size,
|
||||
mtime_ns=getattr(st, "st_mtime_ns", int(st.st_mtime * 1e9)),
|
||||
)
|
||||
|
||||
|
||||
def iter_bsl_files(src: Path) -> list[Path]:
|
||||
if not src.is_dir():
|
||||
return []
|
||||
return sorted(src.rglob("*.bsl"))
|
||||
Reference in New Issue
Block a user