调用图分析

CKG(代码知识图谱)的调用图是 wescode 的核心差异化能力之一。它通过静态分析构建函数间的调用关系图,支持调用链追踪、影响分析和可视化交互,帮助 AI 和开发者深入理解代码结构。


调用图生成原理

数据来源

CKG 调用图的生成基于多源数据融合:

数据源提供的信息优先级
Tree-sitter函数调用语法节点基础层
LSP类型推断、跳转定义增强层
CKG 增量解析跨文件边解析融合层

10-Pass 管线

CKG 索引采用 10-Pass 管线处理,调用图相关的核心阶段:

  1. Pass 1 - 文件扫描:发现工作区内的源码文件
  2. Pass 2 - 符号提取:通过 Tree-sitter 提取函数、类型等符号
  3. Pass 3 - 调用边提取:提取函数调用关系(caller → callee)
  4. Pass 4 - 边解析:将未解析的调用目标关联到具体符号
  5. 后续 Pass:FTS5 索引写入、统计计算等

调用边的三级解析

对于一条调用边 foo() → bar(),CKG 按以下优先级尝试解析 bar 的目标:

解析级别匹配规则示例
精确匹配Type.Method 形式,通过 parent 列匹配svc.Create → UserService.Create
包路径匹配文件路径推断包名auth.Validate → internal/auth/Validate
裸名回退全局唯一的函数名processOrder → 唯一的 processOrder 定义

重要:当裸名对应多个候选符号时,CKG 保持 target_id IS NULL(未解析状态),交给查询层分组呈现,不会错误连边。


调用链追踪

向下追踪(Callees)

从一个函数出发,列出它调用的所有函数:

ProcessOrder 函数内部调用了哪些函数?

CKG 返回:

ProcessOrder
├── validateOrder       (internal/order/validate.go)
├── checkInventory      (internal/inventory/check.go)
├── calculateTotal      (internal/pricing/calc.go)
├── createTransaction   (internal/payment/tx.go)
│   ├── chargeCard      (internal/payment/card.go)
│   └── recordPayment   (internal/payment/record.go)
└── sendConfirmation    (internal/notify/email.go)

向上追踪(Callers)

反向查找调用某个函数的所有函数:

谁调用了 chargeCard 函数?

CKG 返回:

chargeCard ← 被以下函数调用:
├── createTransaction   (internal/payment/tx.go:45)
├── retryPayment        (internal/payment/retry.go:23)
└── processRefund       (internal/payment/refund.go:67)

多级追踪

CKG 支持多级调用链追踪,用于影响分析:

如果修改 chargeCard,最终会影响哪些 API 端点?

CKG 沿调用图向上追溯,直到到达入口函数:

chargeCard
  ← createTransaction
    ← ProcessOrder
      ← HandleOrderAPI     (POST /api/orders)
      ← HandleBatchImport  (POST /api/orders/batch)
  ← retryPayment
    ← HandleRetryPayment   (POST /api/payments/retry)
  ← processRefund
    ← HandleRefundAPI      (POST /api/refunds)

影响分析

变更影响范围

CKG 的影响分析帮助评估代码修改的波及范围:

我要修改 database.Connect 函数的签名,影响范围是多大?

AI 使用 CKG 分析:

  1. 直接调用者:直接调用 database.Connect 的函数
  2. 间接调用者:通过调用链间接依赖的函数
  3. 影响的包:受波及的 Go 包列表
  4. 影响的测试:需要重新运行的测试文件

孤立函数检测

CKG 能发现没有被任何函数调用的"孤立函数":

项目中有哪些没被使用的函数?

这些函数可能是:


D3 可视化交互

调用图视图

项目概览面板中的 D3 调用图提供交互式可视化:

节点

每个节点代表一个函数/方法:

边

每条边代表一个调用关系:

交互操作

操作效果
点击节点高亮该函数的调用者和被调用者
双击节点在编辑器中跳转到函数定义
右键节点展开/折叠子调用图、查看详情
框选选中一组节点查看子图
拖拽节点手动调整布局位置
搜索在调用图中高亮匹配的函数

筛选与聚焦

调用图支持多种筛选方式:


跨包多态分派

INV-CKG-EDGE-01

CKG 调用图遵循 INV-CKG-EDGE-01 不变量——调用边解析不猜测 receiver 大小写。

提取规则

调用提取保留 selector 的原始拼写:

// 提取为 "svc.CreateUser"(保留小写 svc)
svc.CreateUser(ctx, req)

// 提取为 "fmt.Errorf"(保留原始拼写)
fmt.Errorf("error: %w", err)

// 提取为 "UserService.Create"(类型选择器保持原样)
UserService.Create(ctx, req)

不会将 svc.CreateUser 猜测为 Svc.CreateUser——这可能导致错误绑定到一个不相关的类型。

解析规则

对于包含 receiver 的调用(如 svc.CreateUser),解析遵循三级回退:

  1. 精确 parent 匹配:symbols.parent = 'Svc' 或 'UserService'
  2. 包路径匹配:file_path LIKE '%/service/%'
  3. 裸名单候选:只在全局恰好有一个 CreateUser 时绑定

多候选时保持未解析,查询层通过 resolveDisambiguatedCallers 分组呈现(不静默丢弃,也不错误连边)。

接口实现追踪

CKG 支持追踪接口的实现关系:

哪些类型实现了 PaymentProcessor 接口?

CKG 通过分析方法签名匹配,找到所有满足接口契约的具体类型。

多态调用处理

对于接口方法调用,CKG 会展示所有可能的实现:

var processor PaymentProcessor
processor.Process(order) // CKG 会列出所有实现了 Process 的类型

使用示例

示例 1:理解新项目

帮我分析这个项目的核心调用链,从 HTTP handler 到数据库操作

AI 利用 CKG 生成调用链视图,帮助快速理解项目架构。

示例 2:安全审计

找出所有能够执行 SQL 查询的函数,以及它们的调用入口

AI 从底层 SQL 执行函数向上追踪,找出所有可能的入口路径,评估 SQL 注入风险。

示例 3:性能分析准备

找出调用链最深的几个函数,它们可能是性能瓶颈

CKG 计算每个函数的调用深度,返回深度最大的调用路径。


局限与注意事项

  1. 动态调用:反射、接口断言、高阶函数等动态调用可能无法被静态分析捕获
  2. 泛型:Go 泛型函数的调用边解析可能不完整
  3. CGo:C/Go 跨语言调用不在 CKG 的分析范围内
  4. 生成代码:go generate 生成的代码需要在生成后才能被 CKG 索引
  5. 索引延迟:新增文件后需要等待增量索引完成,调用图才会更新