LSP 三源融合
wescode 的代码智能系统采用 LSP + Tree-sitter + CKG 三源数据融合架构,三者各有所长、互为补充,共同提供精准的代码理解能力。
架构概述
┌──────────────┐ ┌──────────────┐ ┌──────────────┐
│ Language │ │ Tree-sitter │ │ CKG │
│ Server (LSP)│ │ 解析器 │ │ 代码知识图谱 │
│ │ │ │ │ │
│ 类型推断 │ │ 语法树 │ │ 调用图 │
│ 跳转定义 │ │ 符号提取 │ │ 引用关系 │
│ 引用查找 │ │ 增量解析 │ │ FTS5 搜索 │
│ 补全建议 │ │ 代码折叠 │ │ 影响分析 │
└──────┬───────┘ └──────┬───────┘ └──────┬───────┘
│ │ │
└────────┬────────┴────────┬────────┘
│ │
┌──────▼─────────────────▼──────┐
│ 三源融合引擎 │
│ 数据合并 → 冲突消解 → 输出 │
└──────────────┬────────────────┘
│
┌─────────▼─────────┐
│ AI 上下文组装 │
│ 编辑器增强功能 │
└───────────────────┘
三源能力对比
Language Server Protocol (LSP)
LSP 通过语言特定的 Language Server 提供精确的语义信息:
| 能力 | 说明 | 精度 |
|---|---|---|
| 跳转定义 | 精确跳转到符号定义位置 | ★★★★★ |
| 类型推断 | 完整的类型信息 | ★★★★★ |
| 代码补全 | 上下文感知的补全建议 | ★★★★☆ |
| 引用查找 | 查找符号的所有引用 | ★★★★☆ |
| 重命名 | 安全的跨文件重命名 | ★★★★★ |
| 诊断 | 编译错误和警告 | ★★★★★ |
优势:类型精确、语义准确 劣势:启动慢、单语言、不提供调用图、不提供全局视图
Tree-sitter
Tree-sitter 是增量解析器,提供快速的语法级分析:
| 能力 | 说明 | 速度 |
|---|---|---|
| 语法高亮 | 基于语法树的精确高亮 | ★★★★★ |
| 符号提取 | 函数、类型、变量的快速提取 | ★★★★★ |
| 增量解析 | 编辑时实时更新语法树 | ★★★★★ |
| 代码折叠 | 基于语法结构的折叠 | ★★★★★ |
| 多语言 | 支持 200+ 种语言 | ★★★★★ |
优势:极快、多语言、增量解析 劣势:无类型信息、无语义理解、仅语法级
CKG 代码知识图谱
CKG 是 wescode 独有的代码知识图谱:
| 能力 | 说明 | 覆盖 |
|---|---|---|
| 调用图 | 函数间调用关系 | ★★★★☆ |
| 影响分析 | 变更波及范围评估 | ★★★★☆ |
| 全文搜索 | FTS5 索引快速搜索 | ★★★★★ |
| 孤立检测 | 发现未使用的函数 | ★★★★☆ |
| 结构概览 | 项目整体结构视图 | ★★★★★ |
优势:全局视图、调用图、离线可用 劣势:无类型精度、依赖索引构建
融合策略
数据合并
三源数据按以下规则合并:
- 符号信息:LSP 精度最高时用 LSP,LSP 不可用时用 Tree-sitter,CKG 提供补充元数据
- 跳转定义:优先 LSP,回退 CKG(通过符号名匹配),最后 Tree-sitter(语法级匹配)
- 引用查找:LSP 精确引用 + CKG 调用图引用,去重后合并
- 悬停信息:LSP 类型信息 + CKG 调用统计(调用者数量、被调用者列表)
- 搜索:CKG 的 FTS5 提供快速搜索,LSP 提供语义级过滤
冲突消解
当三源数据冲突时:
LSP 说 foo() 定义在 a.go:10
CKG 说 foo() 定义在 b.go:20 ← CKG 索引可能过期
Tree-sitter 说 foo 是函数声明
消解规则:
- LSP 优先:LSP 拥有最新的类型推断信息,其结果优先
- Tree-sitter 验证:用 Tree-sitter 验证语法合理性
- CKG 降级:CKG 数据仅在 LSP 不可用时使用
降级策略
当某个数据源不可用时,系统自动降级:
| 场景 | 降级行为 |
|---|---|
| LSP 未启动 | Tree-sitter + CKG 提供基础智能 |
| LSP 加载中 | Tree-sitter 提供即时反馈,CKG 补充 |
| CKG 索引中 | LSP + Tree-sitter 正常工作 |
| 未知语言 | 仅 Tree-sitter 语法级支持 |
类型信息
LSP 提供的类型
LSP 提供最精确的类型信息:
// 悬停在 result 上
var result, err = db.Query(ctx, sql, args...)
// LSP 显示:var result *sql.Rows
CKG 增强
CKG 在 LSP 类型信息基础上添加调用上下文:
// 悬停在 Query 上
db.Query(ctx, sql, args...)
// LSP:func (*sql.DB).Query(ctx, query string, args ...any) (*Rows, error)
// CKG:被 12 个函数调用 | 位于 3 条热路径上
跳转定义
三级回退
跳转定义按以下顺序尝试:
- LSP
textDocument/definition:最精确,支持泛型、接口实现 - CKG 符号表查询:通过限定名查找定义位置
- Tree-sitter 语法匹配:在当前文件和相关文件中搜索匹配的声明
跨文件跳转
对于跨文件的符号引用:
import "internal/service"
func main() {
svc := service.NewUserService()
svc.Create(ctx, user) // Ctrl+Click → 跳转到 UserService.Create
}
LSP 通过类型推断精确跳转到 UserService.Create 的定义。CKG 提供备用路径——通过 (service).Create 在符号表中查找。
引用查找
LSP 引用
// 在 Create 上右键 → 查找所有引用
func (s *UserService) Create(ctx context.Context, user *User) error {
LSP 返回所有精确引用(包括接口实现引用)。
CKG 增强引用
CKG 在 LSP 引用基础上提供调用方向的上下文:
- 作为调用目标的引用:
handler.go:34 → svc.Create(ctx, user) - 作为参数传递的引用:
test.go:12 → mock.On("Create", ...) - 作为方法值的引用:
router.go:8 → r.Handle(svc.Create)
支持的语言
完整支持(LSP + Tree-sitter + CKG)
| 语言 | Language Server | CKG 调用图 |
|---|---|---|
| Go | gopls | ✅ 完整 |
| TypeScript / JavaScript | typescript-language-server | ✅ 完整 |
| Python | pylsp / pyright | ✅ 完整 |
| Rust | rust-analyzer | ✅ 基础 |
| Java | jdtls | ✅ 基础 |
部分支持(Tree-sitter + 文本搜索)
| 语言 | Tree-sitter 解析 | 文本搜索 |
|---|---|---|
| C / C++ | ✅ | ✅ |
| Ruby | ✅ | ✅ |
| PHP | ✅ | ✅ |
| Swift | ✅ | ✅ |
| Kotlin | ✅ | ✅ |
| 200+ 其他语言 | ✅ | ✅ |
语言特定配置
不同语言的 Language Server 可以通过 VS Code 设置配置:
{
"go.useLanguageServer": true,
"typescript.tsdk": "node_modules/typescript/lib",
"python.languageServer": "Pylance"
}
AI 如何使用三源数据
上下文组装
AI 在组装上下文时综合使用三源数据:
- 焦点文件上下文:编辑器当前文件 + 光标位置(来自 Device Agent)
- 类型上下文:LSP 提供的当前函数参数、返回值类型
- 调用上下文:CKG 提供的调用者和被调用者
- 结构上下文:Tree-sitter 提供的语法结构信息
智能读取
AI 使用 read 工具读取文件时,三源融合自动增强:
帮我理解 processOrder 函数的完整逻辑
AI 不仅读取该函数本身,还通过 CKG 自动定位和读取关键的被调用函数。
配置
启用/禁用数据源
{
"wescode.codeintel.lsp.enabled": true,
"wescode.codeintel.treesitter.enabled": true,
"wescode.codeintel.ckg.enabled": true
}
性能调优
对于超大项目,可以调整 CKG 索引范围:
{
"wescode.ckg.excludePatterns": [
"**/vendor/**",
"**/node_modules/**",
"**/generated/**"
],
"wescode.ckg.maxFileSize": 1048576
}
注意事项
- LSP 启动延迟:Language Server 启动需要时间,启动期间仅 Tree-sitter + CKG 可用
- CKG 索引延迟:首次打开项目时 CKG 需要构建索引
- 内存占用:三个数据源同时运行会增加内存占用
- 语言支持差异:不同语言的 LSP 成熟度不同,CKG 支持也有差异