tsl-devkit/lsp-server/框架.md

638 lines
36 KiB
Markdown
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<svg viewBox="0 0 1600 1800" xmlns="http://www.w3.org/2000/svg">
<defs>
<style>
.module-box { fill: #fff; stroke: #2c3e50; stroke-width: 3; }
.module-title { fill: #2c3e50; font-family: 'Segoe UI', Arial, sans-serif; font-size: 20px; font-weight: bold; }
.dir-box { fill: #ecf0f1; stroke: #34495e; stroke-width: 2; }
.file-box { fill: #3498db; stroke: #2980b9; stroke-width: 1.5; rx: 3; }
.file-text { fill: #fff; font-family: 'Consolas', 'Courier New', monospace; font-size: 12px; }
.service-box { fill: #e74c3c; stroke: #c0392b; stroke-width: 1.5; rx: 3; }
.service-text { fill: #fff; font-family: 'Consolas', monospace; font-size: 12px; }
.header-text { fill: #2c3e50; font-family: 'Segoe UI', sans-serif; font-size: 13px; font-weight: bold; }
.arrow { stroke: #7f8c8d; stroke-width: 2.5; fill: none; marker-end: url(#arrow); }
.arrow-thick { stroke: #e67e22; stroke-width: 3.5; fill: none; marker-end: url(#arrow-orange); }
.arrow-data { stroke: #27ae60; stroke-width: 3; fill: none; marker-end: url(#arrow-green); stroke-dasharray: 8,4; }
.label { fill: #7f8c8d; font-family: Arial, sans-serif; font-size: 11px; }
.label-important { fill: #e67e22; font-family: Arial, sans-serif; font-size: 12px; font-weight: bold; }
.note { fill: #95a5a6; font-family: Arial, sans-serif; font-size: 10px; font-style: italic; }
.layer-label { fill: #fff; font-family: Arial, sans-serif; font-size: 14px; font-weight: bold; }
</style>
<marker id="arrow" markerWidth="10" markerHeight="10" refX="9" refY="3" orient="auto">
<polygon points="0 0, 10 3, 0 6" fill="#7f8c8d" />
</marker>
<marker id="arrow-orange" markerWidth="12" markerHeight="12" refX="10" refY="3" orient="auto">
<polygon points="0 0, 12 3, 0 6" fill="#e67e22" />
</marker>
<marker id="arrow-green" markerWidth="12" markerHeight="12" refX="10" refY="3" orient="auto">
<polygon points="0 0, 12 3, 0 6" fill="#27ae60" />
</marker>
</defs>
<!-- Title -->
<rect x="0" y="0" width="1600" height="60" fill="#2c3e50"/>
<text x="800" y="38" text-anchor="middle" style="fill: #fff; font-family: 'Segoe UI', sans-serif; font-size: 28px; font-weight: bold;">
TSF Language Server - 完整架构图
</text>
<!-- ==================== LAYER 1: Core & Protocol ==================== -->
<rect x="30" y="80" width="740" height="320" class="module-box" rx="8"/>
<rect x="30" y="80" width="740" height="45" fill="#34495e" rx="8"/>
<text x="50" y="110" class="layer-label">📡 CORE & PROTOCOL LAYER</text>
<!-- core/ -->
<rect x="50" y="145" width="340" height="110" class="dir-box" rx="5"/>
<text x="60" y="165" class="header-text">core/</text>
<rect x="70" y="175" width="140" height="25" class="file-box"/>
<text x="80" y="192" class="file-text">server.hpp/.cpp</text>
<rect x="70" y="205" width="140" height="25" class="file-box"/>
<text x="80" y="222" class="file-text">dispatcher.hpp/.cpp</text>
<text x="230" y="195" class="note">连接管理</text>
<text x="230" y="210" class="note">请求路由</text>
<text x="230" y="225" class="note">响应处理</text>
<!-- protocol/ -->
<rect x="420" y="145" width="330" height="240" class="dir-box" rx="5"/>
<text x="430" y="165" class="header-text">protocol/</text>
<rect x="440" y="175" width="130" height="25" class="file-box"/>
<text x="450" y="192" class="file-text">protocol.hpp</text>
<text x="440" y="215" class="header-text">transform/</text>
<rect x="450" y="225" width="130" height="25" class="file-box"/>
<text x="460" y="242" class="file-text">common.hpp</text>
<rect x="450" y="255" width="130" height="25" class="file-box"/>
<text x="460" y="272" class="file-text">facade.hpp/.inl</text>
<rect x="450" y="285" width="130" height="25" class="file-box"/>
<text x="460" y="302" class="file-text">transformer.*</text>
<text x="600" y="240" class="note">LSP类型定义</text>
<text x="600" y="260" class="note">类型转换</text>
<text x="600" y="280" class="note">Position/Range</text>
<text x="600" y="300" class="note">序列化/反序列化</text>
<!-- scheduler/ -->
<rect x="50" y="275" width="340" height="110" class="dir-box" rx="5"/>
<text x="60" y="295" class="header-text">scheduler/</text>
<rect x="70" y="305" width="180" height="25" class="file-box"/>
<text x="80" y="322" class="file-text">async_executor.hpp/.cpp</text>
<text x="270" y="315" class="note">异步任务执行</text>
<text x="270" y="330" class="note">线程池管理</text>
<!-- ==================== LAYER 2: Provider ==================== -->
<rect x="800" y="80" width="770" height="320" class="module-box" rx="8"/>
<rect x="800" y="80" width="770" height="45" fill="#8e44ad" rx="8"/>
<text x="820" y="110" class="layer-label">🔌 PROVIDER LAYER (LSP Handlers)</text>
<rect x="820" y="145" width="350" height="240" class="dir-box" rx="5"/>
<text x="830" y="165" class="header-text">provider/</text>
<text x="840" y="190" class="header-text">base/ (注册&amp;接口)</text>
<rect x="850" y="200" width="140" height="20" class="file-box"/>
<text x="860" y="215" class="file-text" font-size="11px">bootstrap.*</text>
<rect x="1000" y="200" width="140" height="20" class="file-box"/>
<text x="1010" y="215" class="file-text" font-size="11px">interface.*</text>
<text x="840" y="240" class="header-text">核心功能模块:</text>
<rect x="850" y="250" width="140" height="20" class="file-box"/>
<text x="860" y="265" class="file-text" font-size="11px">initialize/</text>
<rect x="850" y="275" width="140" height="20" class="file-box"/>
<text x="860" y="290" class="file-text" font-size="11px">text_document/</text>
<rect x="850" y="300" width="140" height="20" class="file-box"/>
<text x="860" y="315" class="file-text" font-size="11px">workspace/</text>
<rect x="850" y="325" width="140" height="20" class="file-box"/>
<text x="860" y="340" class="file-text" font-size="11px">call_hierarchy/</text>
<rect x="1000" y="250" width="140" height="20" class="file-box"/>
<text x="1010" y="265" class="file-text" font-size="11px">completion_item/</text>
<rect x="1000" y="275" width="140" height="20" class="file-box"/>
<text x="1010" y="290" class="file-text" font-size="11px">code_action/</text>
<rect x="1000" y="300" width="140" height="20" class="file-box"/>
<text x="1010" y="315" class="file-text" font-size="11px">code_lens/</text>
<rect x="1000" y="325" width="140" height="20" class="file-box"/>
<text x="1010" y="340" class="file-text" font-size="11px">...</text>
<text x="840" y="370" class="note">20+ LSP请求处理器</text>
<!-- Key Handlers Detail -->
<rect x="1200" y="145" width="350" height="240" class="dir-box" rx="5"/>
<text x="1210" y="165" class="header-text">text_document/ (核心功能)</text>
<rect x="1220" y="180" width="150" height="20" class="service-box"/>
<text x="1230" y="195" class="service-text" font-size="11px">completion.*</text>
<rect x="1220" y="205" width="150" height="20" class="service-box"/>
<text x="1230" y="220" class="service-text" font-size="11px">hover.*</text>
<rect x="1220" y="230" width="150" height="20" class="service-box"/>
<text x="1230" y="245" class="service-text" font-size="11px">definition.*</text>
<rect x="1220" y="255" width="150" height="20" class="service-box"/>
<text x="1230" y="270" class="service-text" font-size="11px">implementation.*</text>
<rect x="1220" y="280" width="150" height="20" class="service-box"/>
<text x="1230" y="295" class="service-text" font-size="11px">did_open.*</text>
<rect x="1220" y="305" width="150" height="20" class="service-box"/>
<text x="1230" y="320" class="service-text" font-size="11px">did_change.*</text>
<text x="1385" y="195" class="note">→ Symbol</text>
<text x="1385" y="220" class="note">→ Symbol</text>
<text x="1385" y="245" class="note">→ Symbol</text>
<text x="1385" y="270" class="note">→ Symbol</text>
<text x="1385" y="295" class="note">→ Document</text>
<text x="1385" y="320" class="note">→ Document</text>
<text x="1210" y="355" class="note">调用 service/ 层进行实际处理</text>
<!-- ==================== LAYER 3: Service ==================== -->
<rect x="30" y="430" width="1540" height="380" class="module-box" rx="8"/>
<rect x="30" y="430" width="1540" height="45" fill="#16a085" rx="8"/>
<text x="50" y="460" class="layer-label">⚙️ SERVICE LAYER (业务逻辑 + 三区域符号存储)</text>
<!-- Symbol Service -->
<rect x="50" y="495" width="480" height="295" class="dir-box" rx="5"/>
<text x="60" y="515" class="header-text" font-size="15px">service/symbol/</text>
<rect x="70" y="530" width="180" height="25" class="service-box"/>
<text x="80" y="547" class="service-text">symbol.hpp/.cpp</text>
<text x="270" y="545" class="note">符号服务主接口</text>
<text x="70" y="575" class="header-text">detail/symbol/</text>
<rect x="80" y="585" width="180" height="25" class="service-box"/>
<text x="90" y="602" class="service-text">symbol_types.hpp</text>
<text x="280" y="600" class="note">PositionKey, RangeKey</text>
<text x="280" y="615" class="note">SymbolSignature</text>
<text x="70" y="630" class="header-text">三区域仓库:</text>
<rect x="80" y="645" width="180" height="30" style="fill: #f39c12; stroke: #d68910; stroke-width: 1.5;" rx="3"/>
<text x="90" y="665" class="file-text">system_repo.*</text>
<text x="280" y="655" class="label-important">~50KB/文件</text>
<text x="280" y="670" class="note">系统库轻量索引</text>
<rect x="80" y="685" width="180" height="30" style="fill: #3498db; stroke: #2980b9; stroke-width: 1.5;" rx="3"/>
<text x="90" y="705" class="file-text">workspace_repo.*</text>
<text x="280" y="695" class="label-important">~100KB/文件</text>
<text x="280" y="710" class="note">工作区文件索引</text>
<rect x="80" y="725" width="180" height="30" style="fill: #e74c3c; stroke: #c0392b; stroke-width: 1.5;" rx="3"/>
<text x="90" y="745" class="file-text">editing_repo.* (?)</text>
<text x="280" y="735" class="label-important">~1MB/文件</text>
<text x="280" y="750" class="note">完整符号表</text>
<text x="280" y="765" class="note" font-weight="bold" fill="#c0392b">⚠️ 需新增!</text>
<!-- Parser Service -->
<rect x="560" y="495" width="330" height="160" class="dir-box" rx="5"/>
<text x="570" y="515" class="header-text" font-size="15px">service/parser/</text>
<rect x="580" y="535" width="180" height="25" class="service-box"/>
<text x="590" y="552" class="service-text">parser.hpp/.cpp</text>
<text x="580" y="580" class="note">• Tree-sitter语法解析</text>
<text x="580" y="600" class="note">• 增量解析优化</text>
<text x="580" y="620" class="note">• 触发DocumentParsed事件</text>
<text x="580" y="640" class="note">• ParseTsfFile() 完整解析</text>
<!-- Document Service -->
<rect x="920" y="495" width="330" height="160" class="dir-box" rx="5"/>
<text x="930" y="515" class="header-text" font-size="15px">service/document/</text>
<rect x="940" y="535" width="180" height="25" class="service-box"/>
<text x="950" y="552" class="service-text">document.hpp/.cpp</text>
<text x="940" y="580" class="note">• 文档内容管理</text>
<text x="940" y="600" class="note">• 版本控制</text>
<text x="940" y="620" class="note">• OpenDocument()</text>
<text x="940" y="640" class="note">• UpdateDocument()</text>
<!-- Event Bus -->
<rect x="560" y="675" width="690" height="95" class="dir-box" rx="5"/>
<text x="570" y="695" class="header-text" font-size="15px">service/base/ (事件驱动)</text>
<rect x="580" y="710" width="150" height="25" class="service-box"/>
<text x="590" y="727" class="service-text">event_bus.hpp</text>
<rect x="750" y="710" width="150" height="25" class="service-box"/>
<text x="760" y="727" class="service-text">events.hpp</text>
<rect x="920" y="710" width="150" height="25" class="service-box"/>
<text x="930" y="727" class="service-text">bootstrap.*</text>
<text x="580" y="755" class="note">DocumentOpened → Parser → DocumentParsed → Symbol构建</text>
<!-- Utils -->
<rect x="1280" y="495" width="270" height="160" class="dir-box" rx="5"/>
<text x="1290" y="515" class="header-text" font-size="15px">service/utils/</text>
<rect x="1300" y="535" width="180" height="25" class="service-box"/>
<text x="1310" y="552" class="service-text">text_coordinates.*</text>
<text x="1300" y="580" class="note">• 位置计算</text>
<text x="1300" y="600" class="note">• 行列转换</text>
<text x="1300" y="620" class="note">• 范围处理</text>
<!-- ==================== LAYER 4: Language ==================== -->
<rect x="30" y="840" width="1540" height="480" class="module-box" rx="8"/>
<rect x="30" y="840" width="1540" height="45" fill="#d35400" rx="8"/>
<text x="50" y="870" class="layer-label">🧬 LANGUAGE LAYER (语言语义分析)</text>
<!-- AST -->
<rect x="50" y="905" width="480" height="390" class="dir-box" rx="5"/>
<text x="60" y="925" class="header-text" font-size="15px">language/ast/</text>
<rect x="70" y="945" width="200" height="30" class="file-box"/>
<text x="80" y="965" class="file-text">node_types.hpp</text>
<text x="290" y="950" class="note">AST节点定义(variant)</text>
<text x="290" y="965" class="note">UnitDef, ClassDef,</text>
<text x="290" y="980" class="note">FunctionDef, VarDecl...</text>
<rect x="70" y="995" width="200" height="30" class="file-box"/>
<text x="80" y="1015" class="file-text">deserializer.hpp/.cpp</text>
<text x="290" y="1005" class="note">TSTree → AST 转换</text>
<text x="70" y="1050" class="header-text">核心数据结构示例:</text>
<rect x="80" y="1060" width="380" height="220" style="fill: #ecf0f1; stroke: #95a5a6; stroke-width: 1.5;" rx="3"/>
<text x="90" y="1080" class="label" font-family="Consolas" font-size="11px">struct UnitDef {</text>
<text x="100" y="1100" class="label" font-family="Consolas" font-size="11px"> std::string name;</text>
<text x="100" y="1120" class="label" font-family="Consolas" font-size="11px"> Location location;</text>
<text x="100" y="1140" class="label" font-family="Consolas" font-size="11px"> std::optional&lt;UsesClause&gt; uses;</text>
<text x="100" y="1160" class="label" font-family="Consolas" font-size="11px"> vector&lt;ASTNode&gt; interface_stmts;</text>
<text x="100" y="1180" class="label" font-family="Consolas" font-size="11px"> vector&lt;ASTNode&gt; impl_stmts;</text>
<text x="90" y="1200" class="label" font-family="Consolas" font-size="11px">};</text>
<text x="90" y="1230" class="label" font-family="Consolas" font-size="11px">using ASTNode = variant&lt;</text>
<text x="100" y="1250" class="label" font-family="Consolas" font-size="11px">UnitDef, ClassDef, FunctionDef...</text>
<text x="90" y="1270" class="label" font-family="Consolas" font-size="11px">&gt;;</text>
<!-- Symbol -->
<rect x="560" y="905" width="480" height="390" class="dir-box" rx="5"/>
<text x="570" y="925" class="header-text" font-size="15px">language/symbol/</text>
<rect x="580" y="945" width="180" height="30" class="file-box"/>
<text x="590" y="965" class="file-text">symbol.hpp/.cpp</text>
<text x="780" y="960" class="note">符号类层次</text>
<rect x="580" y="985" width="180" height="30" class="file-box"/>
<text x="590" y="1005" class="file-text">table.hpp/.cpp</text>
<text x="780" y="1000" class="note">符号表 + GlobalTable</text>
<rect x="580" y="1025" width="180" height="30" class="file-box"/>
<text x="590" y="1045" class="file-text">builder.hpp/.cpp</text>
<text x="780" y="1040" class="note">AST → Symbol构建器</text>
<text x="570" y="1080" class="header-text">符号类型体系:</text>
<rect x="580" y="1090" width="430" height="190" style="fill: #ecf0f1; stroke: #95a5a6; stroke-width: 1.5;" rx="3"/>
<text x="590" y="1110" class="label" font-family="Consolas" font-size="11px">Symbol (base)</text>
<text x="600" y="1130" class="label" font-family="Consolas" font-size="11px">├─ Variable (变量/参数)</text>
<text x="600" y="1150" class="label" font-family="Consolas" font-size="11px">├─ Function (函数 + body_scope)</text>
<text x="610" y="1170" class="label" font-family="Consolas" font-size="11px">└─ Method (继承Function)</text>
<text x="600" y="1190" class="label" font-family="Consolas" font-size="11px">├─ Class (类 + members Table)</text>
<text x="600" y="1210" class="label" font-family="Consolas" font-size="11px">├─ Constant (常量)</text>
<text x="600" y="1230" class="label" font-family="Consolas" font-size="11px">└─ Unit (interface + impl Tables)</text>
<text x="600" y="1265" class="label-important">完整语义信息 ~1MB/文件</text>
<!-- Keyword -->
<rect x="1070" y="905" width="480" height="390" class="dir-box" rx="5"/>
<text x="1080" y="925" class="header-text" font-size="15px">language/keyword/</text>
<rect x="1090" y="945" width="180" height="30" class="file-box"/>
<text x="1100" y="965" class="file-text">types.hpp</text>
<text x="1290" y="960" class="note">关键字类型枚举</text>
<rect x="1090" y="985" width="180" height="30" class="file-box"/>
<text x="1100" y="1005" class="file-text">repo.hpp/.cpp</text>
<text x="1290" y="1000" class="note">关键字仓库</text>
<text x="1080" y="1040" class="header-text">用途:</text>
<text x="1090" y="1065" class="note">• 语法验证 (识别保留字)</text>
<text x="1090" y="1085" class="note">• 补全过滤 (避免建议关键字)</text>
<text x="1090" y="1105" class="note">• 高亮支持 (提供关键字列表)</text>
<text x="1080" y="1135" class="header-text">示例关键字:</text>
<rect x="1090" y="1145" width="430" height="130" style="fill: #fff9e6; stroke: #f39c12; stroke-width: 1.5;" rx="3"/>
<text x="1100" y="1165" class="label" font-family="Consolas" font-size="11px">begin, end, if, then, else</text>
<text x="1100" y="1185" class="label" font-family="Consolas" font-size="11px">class, function, procedure</text>
<text x="1100" y="1205" class="label" font-family="Consolas" font-size="11px">var, const, type</text>
<text x="1100" y="1225" class="label" font-family="Consolas" font-size="11px">unit, interface, implementation</text>
<text x="1100" y="1245" class="label" font-family="Consolas" font-size="11px">uses, private, public, published</text>
<!-- ==================== LAYER 5: Tree-sitter ==================== -->
<rect x="30" y="1350" width="1540" height="150" class="module-box" rx="8"/>
<rect x="30" y="1350" width="1540" height="45" fill="#7f8c8d" rx="8"/>
<text x="50" y="1380" class="layer-label">🌳 TREE-SITTER LAYER (C语法解析引擎)</text>
<rect x="50" y="1415" width="1500" height="65" class="dir-box" rx="5"/>
<text x="60" y="1435" class="header-text" font-size="15px">tree-sitter/</text>
<rect x="70" y="1450" width="120" height="20" class="file-box"/>
<text x="80" y="1465" class="file-text" font-size="11px">grammar.json</text>
<rect x="200" y="1450" width="120" height="20" class="file-box"/>
<text x="210" y="1465" class="file-text" font-size="11px">parser.c</text>
<rect x="330" y="1450" width="150" height="20" class="file-box"/>
<text x="340" y="1465" class="file-text" font-size="11px">node-types.json</text>
<text x="500" y="1455" class="note">→ 生成CST (Concrete Syntax Tree)</text>
<text x="500" y="1470" class="note">→ 增量解析 | 错误恢复 | 高性能</text>
<!-- ==================== Data Flow Arrows ==================== -->
<!-- Provider → Service -->
<path d="M 995 400 L 995 430" class="arrow-thick"/>
<text x="1005" y="420" class="label-important">调用服务</text>
<!-- Service → Language -->
<path d="M 275 810 L 275 840" class="arrow-data"/>
<text x="285" y="828" class="label-important" fill="#27ae60">构建符号表</text>
<path d="M 720 675 L 720 840" class="arrow-data"/>
<text x="730" y="760" class="label-important" fill="#27ae60">解析触发</text>
<!-- Language internal -->
<path d="M 290 905 L 560 1100" class="arrow-data"/>
<text x="400" y="990" class="label-important" fill="#27ae60">AST→Symbol</text>
<!-- Tree-sitter → Language -->
<path d="M 800 1350 L 800 1320" class="arrow-data"/>
<text x="810" y="1335" class="label-important" fill="#27ae60">TSTree</text>
<!-- ==================== Legend ==================== -->
<rect x="30" y="1530" width="1540" height="80" style="fill: #fff; stroke: #7f8c8d; stroke-width: 2;" rx="5"/>
<text x="50" y="1555" style="fill: #2c3e50; font-family: Arial, sans-serif; font-size: 16px; font-weight: bold;">
📋 图例
</text>
<rect x="60" y="1565" width="80" height="20" class="file-box"/>
<text x="70" y="1580" class="file-text" font-size="11px">普通模块</text>
<rect x="160" y="1565" width="80" height="20" class="service-box"/>
<text x="170" y="1580" class="service-text" font-size="11px">服务模块</text>
<rect x="260" y="1565" width="80" height="20" style="fill: #f39c12; stroke: #d68910;" rx="3"/>
<text x="270" y="1580" class="file-text" font-size="11px">轻量存储</text>
<rect x="360" y="1565" width="80" height="20" style="fill: #e74c3c; stroke: #c0392b;" rx="3"/>
<text x="370" y="1580" class="file-text" font-size="11px">完整表</text>
<line x1="470" y1="1575" x2="530" y2="1575" class="arrow-thick"/>
<text x="540" y="1580" class="label">调用关系</text>
<line x1="630" y1="1575" x2="690" y2="1575" class="arrow-data"/>
<text x="700" y="1580" class="label">数据流转</text>
<text x="850" y="1580" class="note">⚠️ 红色部分需新增文件</text>
<!-- Bottom Notes -->
<rect x="30" y="1630" width="1540" height="140" style="fill: #ecf0f1; stroke: #95a5a6; stroke-width: 2;" rx="5"/>
<text x="50" y="1660" style="fill: #2c3e50; font-family: Arial, sans-serif; font-size: 16px; font-weight: bold;">
💡 架构要点
</text>
<text x="60" y="1685" class="label" font-size="12px">
<tspan x="60" dy="0">1<tspan font-weight="bold">三层数据流</tspan>: 源代码 → TSTree (tree-sitter) → AST (language/ast) → Symbol (language/symbol) → 索引 (service/symbol)</tspan>
<tspan x="60" dy="20">2<tspan font-weight="bold">三区域存储</tspan>: SystemRepo(50KB) + WorkspaceRepo(100KB) + EditingRepo(1MB) = 分层节省内存</tspan>
<tspan x="60" dy="20">3<tspan font-weight="bold">事件驱动</tspan>: Document变化 → Parser解析 → Symbol构建 → Provider响应LSP</tspan>
<tspan x="60" dy="20">4<tspan font-weight="bold">职责分离</tspan>: Provider处理协议 | Service管理业务 | Language执行语义 | Tree-sitter负责语法</tspan>
</text>
</svg>
<svg viewBox="0 0 1400 1100" xmlns="http://www.w3.org/2000/svg">
<defs>
<style>
.service-module { fill: #e3f2fd; stroke: #1976d2; stroke-width: 2.5; }
.entity-box { fill: #fff9c4; stroke: #f57c00; stroke-width: 2; }
.repo-box { fill: #f3e5f5; stroke: #7b1fa2; stroke-width: 2; }
.base-box { fill: #e8f5e9; stroke: #388e3c; stroke-width: 2; }
.title { fill: #1a237e; font-family: 'Segoe UI', sans-serif; font-size: 16px; font-weight: bold; }
.subtitle { fill: #424242; font-family: 'Segoe UI', sans-serif; font-size: 13px; font-weight: bold; }
.text { fill: #424242; font-family: Arial, sans-serif; font-size: 11px; }
.code { fill: #1565c0; font-family: 'Consolas', monospace; font-size: 10px; }
.arrow { stroke: #616161; stroke-width: 2; fill: none; marker-end: url(#arrow); }
.arrow-event { stroke: #388e3c; stroke-width: 2.5; fill: none; marker-end: url(#arrow-green); stroke-dasharray: 5,3; }
.arrow-call { stroke: #1976d2; stroke-width: 2; fill: none; marker-end: url(#arrow-blue); }
.label { fill: #616161; font-family: Arial, sans-serif; font-size: 10px; }
.label-event { fill: #388e3c; font-family: Arial, sans-serif; font-size: 10px; font-weight: bold; }
.memory { fill: #d32f2f; font-family: Arial, sans-serif; font-size: 11px; font-weight: bold; }
</style>
<marker id="arrow" markerWidth="10" markerHeight="10" refX="9" refY="3" orient="auto">
<polygon points="0 0, 10 3, 0 6" fill="#616161" />
</marker>
<marker id="arrow-green" markerWidth="10" markerHeight="10" refX="9" refY="3" orient="auto">
<polygon points="0 0, 10 3, 0 6" fill="#388e3c" />
</marker>
<marker id="arrow-blue" markerWidth="10" markerHeight="10" refX="9" refY="3" orient="auto">
<polygon points="0 0, 10 3, 0 6" fill="#1976d2" />
</marker>
</defs>
<!-- Title -->
<text x="700" y="30" text-anchor="middle" style="fill: #1565c0; font-family: 'Segoe UI', sans-serif; font-size: 22px; font-weight: bold;">
Service 层内部架构设计
</text>
<!-- ========== BASE LAYER ========== -->
<rect x="30" y="60" width="1340" height="100" class="base-box" rx="5"/>
<text x="50" y="85" class="title">service/base/ - 基础设施</text>
<rect x="60" y="100" width="150" height="40" style="fill: #c8e6c9; stroke: #388e3c;" rx="3"/>
<text x="135" y="115" text-anchor="middle" class="subtitle" font-size="12px">EventBus</text>
<text x="70" y="132" class="text" font-size="10px">事件订阅/发布</text>
<rect x="230" y="100" width="150" height="40" style="fill: #c8e6c9; stroke: #388e3c;" rx="3"/>
<text x="305" y="115" text-anchor="middle" class="subtitle" font-size="12px">Events</text>
<text x="240" y="132" class="text" font-size="10px">事件类型定义</text>
<rect x="400" y="100" width="150" height="40" style="fill: #c8e6c9; stroke: #388e3c;" rx="3"/>
<text x="475" y="115" text-anchor="middle" class="subtitle" font-size="12px">Bootstrap</text>
<text x="410" y="132" class="text" font-size="10px">服务初始化</text>
<rect x="570" y="100" width="150" height="40" style="fill: #c8e6c9; stroke: #388e3c;" rx="3"/>
<text x="645" y="115" text-anchor="middle" class="subtitle" font-size="12px">Registry</text>
<text x="580" y="132" class="text" font-size="10px">服务注册表</text>
<!-- Events list -->
<text x="750" y="112" class="text">事件类型:</text>
<text x="760" y="127" class="code">DocumentOpened, DocumentChanged, DocumentClosed</text>
<text x="1100" y="127" class="code">DocumentParsed, SymbolTableBuilt</text>
<!-- ========== SERVICE MODULES ========== -->
<!-- Document Service -->
<rect x="30" y="190" width="400" height="250" class="service-module" rx="5"/>
<text x="50" y="215" class="title">service/document/</text>
<rect x="50" y="230" width="360" height="80" style="fill: #bbdefb; stroke: #1976d2;" rx="3"/>
<text x="60" y="250" class="subtitle">DocumentService (服务类)</text>
<text x="70" y="270" class="code">void OpenDocument(TextDocumentItem)</text>
<text x="70" y="285" class="code">void UpdateDocument(uri, changes)</text>
<text x="70" y="300" class="code">void CloseDocument(uri)</text>
<rect x="50" y="325" width="360" height="100" class="entity-box" rx="3"/>
<text x="60" y="345" class="subtitle">TextDocument (实体类)</text>
<text x="70" y="365" class="code">void ApplyChange(change)</text>
<text x="70" y="380" class="code">const string&amp; GetContent()</text>
<text x="70" y="395" class="code">integer GetVersion()</text>
<text x="70" y="410" class="text" font-style="italic">私有成员: TextDocumentItem item_</text>
<!-- Parser Service -->
<rect x="460" y="190" width="400" height="250" class="service-module" rx="5"/>
<text x="480" y="215" class="title">service/parser/</text>
<rect x="480" y="230" width="360" height="120" style="fill: #bbdefb; stroke: #1976d2;" rx="3"/>
<text x="490" y="250" class="subtitle">ParserService (服务类)</text>
<text x="500" y="270" class="code">ParseResult Parse(uri, source)</text>
<text x="500" y="285" class="code">ParseResult ParseIncremental(uri, old_tree)</text>
<text x="500" y="300" class="code">FileSymbolIndex ParseLight(file)</text>
<text x="500" y="315" class="code">ParseResult ParseFull(file)</text>
<text x="500" y="335" class="text">返回: AST + TSTree + Errors</text>
<rect x="480" y="365" width="360" height="60" style="fill: #e1f5fe; stroke: #0288d1;" rx="3"/>
<text x="490" y="385" class="subtitle">incremental.hpp (可选)</text>
<text x="500" y="405" class="text">• 增量解析优化逻辑</text>
<text x="500" y="420" class="text">• 变更范围计算</text>
<!-- Symbol Service -->
<rect x="890" y="190" width="480" height="250" class="service-module" rx="5"/>
<text x="910" y="215" class="title">service/symbol/</text>
<rect x="910" y="230" width="440" height="95" style="fill: #bbdefb; stroke: #1976d2;" rx="3"/>
<text x="920" y="250" class="subtitle">SymbolService (核心服务)</text>
<text x="930" y="270" class="code">void LoadSystemSymbols(folder)</text>
<text x="930" y="285" class="code">SymbolQueryResult FindSymbol(name, ctx)</text>
<text x="930" y="300" class="code">SymbolQueryResult FindSymbolAt(uri, pos)</text>
<text x="930" y="315" class="code">SymbolResolutionContext BuildContext(uri)</text>
<rect x="910" y="340" width="220" height="85" style="fill: #e1f5fe; stroke: #0288d1;" rx="3"/>
<text x="920" y="360" class="subtitle">types.hpp</text>
<text x="930" y="380" class="text">• PositionKey / RangeKey</text>
<text x="930" y="395" class="text">• SymbolSignature</text>
<text x="930" y="410" class="text">• SymbolQueryResult</text>
<rect x="1145" y="340" width="195" height="85" style="fill: #e1f5fe; stroke: #0288d1;" rx="3"/>
<text x="1155" y="360" class="subtitle">context.hpp/cpp</text>
<text x="1165" y="380" class="text">• 上下文构建</text>
<text x="1165" y="395" class="text">• 可见单元计算</text>
<text x="1165" y="410" class="text">• 可见性规则</text>
<!-- ========== REPOSITORY LAYER ========== -->
<rect x="30" y="470" width="1340" height="260" style="fill: #f3e5f5; stroke: #7b1fa2; stroke-width: 3;" rx="5"/>
<text x="50" y="495" class="title">service/symbol/repository/ - 三区域符号存储</text>
<!-- System Repo -->
<rect x="60" y="515" width="400" height="195" class="repo-box" rx="5"/>
<text x="80" y="540" class="subtitle">system_repo.hpp/cpp</text>
<text x="260" y="540" class="memory">~50KB/文件</text>
<text x="80" y="565" class="code">void LoadFromFolder(folder)</text>
<text x="80" y="580" class="code">SymbolSignature FindSymbol(unit, name)</text>
<text x="80" y="595" class="code">SystemSymbolIndex FindUnit(unit)</text>
<text x="80" y="610" class="code">GlobalTable* LoadFullSymbolTable(file)</text>
<text x="80" y="635" class="text" font-weight="bold">存储结构:</text>
<text x="90" y="655" class="text">• index_: unit_name → SystemSymbolIndex</text>
<text x="90" y="670" class="text">• global_symbols_: symbol → unit_name</text>
<text x="90" y="685" class="text" font-style="italic">只存 public/published 符号</text>
<!-- Workspace Repo -->
<rect x="490" y="515" width="400" height="195" class="repo-box" rx="5"/>
<text x="510" y="540" class="subtitle">workspace_repo.hpp/cpp</text>
<text x="690" y="540" class="memory">~100KB/文件</text>
<text x="510" y="565" class="code">void LoadFromFolder(folder)</text>
<text x="510" y="580" class="code">void AddOrUpdate(file, FileSymbolIndex)</text>
<text x="510" y="595" class="code">SymbolSignature FindSymbol(unit, name)</text>
<text x="510" y="610" class="code">vector&lt;string&gt; GetDependencies(file)</text>
<text x="510" y="635" class="text" font-weight="bold">存储结构:</text>
<text x="520" y="655" class="text">• files_: file_path → FileSymbolIndex</text>
<text x="520" y="670" class="text">• units_: unit_name → file_path</text>
<text x="520" y="685" class="text">• dependencies_: 依赖图</text>
<!-- Editing Repo -->
<rect x="920" y="515" width="420" height="195" class="repo-box" rx="5"/>
<text x="940" y="540" class="subtitle">editing_repo.hpp/cpp ⚠️ 需新增</text>
<text x="1120" y="540" class="memory">~1MB/文件</text>
<text x="940" y="565" class="code">void AddOrUpdate(uri, GlobalTable, AST)</text>
<text x="940" y="580" class="code">Symbol* FindSymbolAt(uri, position)</text>
<text x="940" y="595" class="code">Symbol* FindSymbolByName(uri, name)</text>
<text x="940" y="610" class="code">GlobalTable* GetSymbolTable(uri)</text>
<text x="940" y="635" class="text" font-weight="bold">存储结构 (EditingSymbolTable):</text>
<text x="950" y="655" class="text">• symbol_table: 完整 GlobalTable</text>
<text x="950" y="670" class="text">• name_index_: 名称快速查找</text>
<text x="950" y="685" class="text">• position_index_: 位置快速查找</text>
<!-- ========== UTILS ========== -->
<rect x="30" y="760" width="1340" height="100" style="fill: #fce4ec; stroke: #c2185b; stroke-width: 2;" rx="5"/>
<text x="50" y="785" class="title">service/utils/ - 工具类</text>
<rect x="60" y="800" width="300" height="40" style="fill: #f8bbd0; stroke: #c2185b;" rx="3"/>
<text x="210" y="815" text-anchor="middle" class="subtitle" font-size="12px">position.hpp/cpp</text>
<text x="70" y="832" class="text" font-size="10px">位置计算、行列转换、范围处理</text>
<rect x="380" y="800" width="300" height="40" style="fill: #f8bbd0; stroke: #c2185b;" rx="3"/>
<text x="530" y="815" text-anchor="middle" class="subtitle" font-size="12px">conversion.hpp (可选)</text>
<text x="390" y="832" class="text" font-size="10px">类型转换: Position ↔ PositionKey</text>
<!-- ========== ARROWS ========== -->
<!-- Document → EventBus -->
<path d="M 230 230 L 230 160" class="arrow-event"/>
<text x="240" y="190" class="label-event">触发事件</text>
<!-- EventBus → Parser -->
<path d="M 305 160 L 660 190" class="arrow-event"/>
<text x="450" y="175" class="label-event">DocumentOpened</text>
<!-- Parser → EventBus -->
<path d="M 660 230 L 305 160" class="arrow-event"/>
<text x="450" y="210" class="label-event">DocumentParsed</text>
<!-- EventBus → Symbol -->
<path d="M 305 160 L 1130 190" class="arrow-event"/>
<text x="700" y="175" class="label-event">DocumentParsed</text>
<!-- Symbol → Repos -->
<path d="M 1050 425 L 260 515" class="arrow-call"/>
<text x="600" y="470" class="label">查找顺序: 1.Editing → 2.Workspace → 3.System</text>
<path d="M 1130 425 L 690 515" class="arrow-call"/>
<path d="M 1200 425 L 1130 515" class="arrow-call"/>
<!-- Legend -->
<rect x="30" y="890" width="1340" height="180" style="fill: #fafafa; stroke: #9e9e9e; stroke-width: 2;" rx="5"/>
<text x="50" y="915" style="fill: #424242; font-family: Arial, sans-serif; font-size: 15px; font-weight: bold;">
关键设计说明
</text>
<text x="60" y="945" class="text" font-size="12px">
<tspan x="60" font-weight="bold">1. 服务接口统一命名:</tspan> DocumentService, ParserService, SymbolService (后缀 *Service)
</text>
<text x="60" y="965" class="text" font-size="12px">
<tspan x="60" font-weight="bold">2. 分层存储策略:</tspan> SystemRepo(轻量50KB) + WorkspaceRepo(索引100KB) + EditingRepo(完整1MB)
</text>
<text x="60" y="985" class="text" font-size="12px">
<tspan x="60" font-weight="bold">3. 事件驱动流程:</tspan> DocumentOpened → Parse → DocumentParsed → BuildSymbol → SymbolTableBuilt
</text>
<text x="60" y="1005" class="text" font-size="12px">
<tspan x="60" font-weight="bold">4. 查找优先级:</tspan> EditingRepo (当前文档) → WorkspaceRepo (项目) → SystemRepo (系统库)
</text>
<text x="60" y="1025" class="text" font-size="12px">
<tspan x="60" font-weight="bold">5. 按需加载:</tspan> 优先使用轻量级SymbolSignature需要时才load_full_symbol()加载完整GlobalTable
</text>
<text x="60" y="1045" class="text" font-size="12px">
<tspan x="60" font-weight="bold">6. 职责分离:</tspan> Document管理内容 | Parser负责解析 | Symbol处理语义 | Repository存储索引
</text>
<!-- Color Legend -->
<rect x="950" y="920" width="30" height="20" class="service-module"/>
<text x="990" y="935" class="text">服务类</text>
<rect x="1070" y="920" width="30" height="20" class="entity-box"/>
<text x="1110" y="935" class="text">实体类</text>
<rect x="1190" y="920" width="30" height="20" class="repo-box"/>
<text x="1230" y="935" class="text">仓库</text>
<rect x="1290" y="920" width="30" height="20" class="base-box"/>
<text x="1330" y="935" class="text">基础</text>
<line x1="950" y1="955" x2="1000" y2="955" class="arrow-event"/>
<text x="1010" y="960" class="text">事件流</text>
<line x1="1100" y1="955" x2="1150" y2="955" class="arrow-call"/>
<text x="1160" y="960" class="text">调用</text>
</svg>