"""Symbol 索引服务。 目标: 1. 对代码库执行增量符号扫描(def/ref) 2. 提供符号查询、详情、概览 3. 为 GraphRAG / Agent 检索提供结构化工具层 """ from __future__ import annotations import ast import hashlib import re from dataclasses import dataclass from datetime import datetime, timezone from pathlib import Path from typing import Any, Optional from sqlalchemy import and_, delete, func, or_, select from sqlalchemy.ext.asyncio import AsyncSession from ...models import SymbolDefinition, SymbolReference from ...utils.timezone import CN_TZ, now_cn_aware, now_cn_naive TS_SYMBOL_RE = re.compile( r"^\s*(?:export\s+)?(?:default\s+)?(?:async\s+)?(?:function|class|interface|type|const)\s+([A-Za-z_][A-Za-z0-9_]*)", re.MULTILINE, ) TS_IMPORT_RE = re.compile(r"^\s*import\s+.*?\s+from\s+['\"]([^'\"]+)['\"]", re.MULTILINE) TS_CALL_RE = re.compile(r"\b([A-Za-z_][A-Za-z0-9_]*)\s*\(") TS_KEYWORDS = {"if", "for", "while", "switch", "catch", "return", "new", "typeof", "await"} @dataclass(slots=True) class ParsedSymbol: symbol_type: str symbol_name: str qualified_name: str start_line: int end_line: int signature: str docstring: str payload: dict[str, Any] @dataclass(slots=True) class ParsedReference: relation_type: str target_symbol_name: str target_qualified_name: str source_qualified_name: str start_line: int end_line: int payload: dict[str, Any]