aalpar/wile-goast

GitHub: aalpar/wile-goast

wile-goast 是一个通过暴露 Go 编译器内部机制并以 Scheme 驱动静态分析,解决代码库中结构重复与一致性问题的 MCP 服务器。

Stars: 5 | Forks: 0

# wile-goast 你有一个大型的 Go 代码库。几十个包中的数百个函数。 你怀疑存在重复的函数、不一致的约定,以及与实际代码运行方式不匹配的结构体边界。grep 只能找到字符串匹配。gopls 可以找到引用。golangci-lint 可以发现已知的反模式。但它们无法回答: - 这两个函数除了类型不同,结构上是否完全相同? - `Step` 的每个调用者都处理了返回的错误吗? - 每个获取锁的函数是否在所有路径上都释放了锁? - 哪些结构体边界与实际字段访问模式相矛盾? - 这 30 个方法是否遵循相同的调用约定?哪些偏离了? wile-goast 是一个 MCP 服务器,它将 Go 编译器的内部机制——AST、SSA、控制流图、调用图和 lint 分析——作为分析原语暴露出来。你的 AI 助手编写查询。你描述你要寻找的内容。 ## 安装 安装二进制文件: ``` go install github.com/aalpar/wile-goast/cmd/wile-goast@latest ``` 将其添加到你的 MCP 客户端配置中: ``` { "mcpServers": { "wile-goast": { "command": "wile-goast", "args": ["--mcp"] } } } ``` 该二进制文件是自包含的。所有分析库都已嵌入——运行时无需外部依赖。 ## 重构会话 你正在清理一个 Go 服务。以下是一个会话的示例。 ### 查找重复函数 你提问:*“扫描我的 service/... 目录,查找重复或近似重复的函数。”* 助手使用 `goast-refactor` 提示来驱动分析。背后,它会解析每个函数,按签名形状分组,并对每对函数运行结构差异分析。替换折叠会分离出真正的差异与类型传播噪声——如果 `FooStore` 和 `BarStore` 的方法体除了类型名称外完全一致,工具会将其识别为单个类型参数,而不是几十个分散的差异。 输出是一个评分列表: ``` store.CreateFoo <-> store.CreateBar similarity: 0.94 type params: 1 ?T0: FooRecord -> BarRecord literals: 0 operators: 0 cosmetic: 12 structural: 0 ``` 94% 相似,仅一个类型参数,零结构差异。这是一个统一候选——提取为泛型函数并删除重复项。 相似度为 0.65 且存在两个结构差异和一个字面量差异的组合?这是压缩,而非简化。工具会标记这些差异,让你决定如何处理。 ### 检查约定违规 你提问:*“raft.Step 的所有调用者都处理了返回的错误吗?”* 助手定义一个信念——一种统计一致性检查——并在你的包上运行它: ``` step-error-handling sites: callers-of "Step" adherence: 87% (13/15) deviations: processMessage (file.go:142) — missing error handling handleRaftReady (file.go:308) — missing error handling ``` 87% 的调用者处理了错误。有两个没有。这些就是需要调查的地方。 信念之所以有效,是因为约定是统计性的。你不会写一条规则说“每个调用者必须做 X”,而是写“找到调用者,检查这个属性,并报告少数例外”。代码库定义了约定,工具负责发现违反者。 同一机制也适用于锁/解锁配对、有序操作、字段协同修改、空指针解引用前的检查——任何大多数代码遵循但部分代码违反的属性。 ### 检查锁纪律 你提问:*“Lock 是否总是与 Unlock 配对?检查所有路径,包括 defer。”* 两个信念,串联执行: ``` lock-unlock-pairing sites: functions calling Lock adherence: 91% (42/46) deviations: acquireLease (lease.go:87) — unpaired startElection (raft.go:203) — unpaired ... ``` 偏差表现为调用了 `Lock` 但未调用 `Unlock` 的函数。但也许它们的调用者处理了。第二个信念在第一条基础上延伸——它检查偏差函数的上层调用栈: ``` lock-unlock-callers sites: deviations from lock-unlock-pairing adherence: 75% (3/4) deviations: handleTimeout (server.go:445) — caller also missing Unlock ``` 四个偏差中有三个被它们的调用者处理了。有一个没有。这就是你的 Bug。 ### 查找错误的 struct 边界 你提问:*“哪些结构体边界与实际字段访问模式不一致?”* 助手从 SSA 字段存储数据构建一个概念格——哪些函数写入哪些类型的哪些字段。自然分组从数据中涌现。当一个分组跨越多个结构体类型时,意味着函数将不同类型的字段视为一个整体。这些就是错误的边界候选。 ``` Cross-boundary concept: types: MachineContext, vmState fields: pc, sp, callStack, continuation functions (7): step, resume, pushFrame, popFrame, ... These 7 functions access fields from both types together. Consider: colocate fields, extract shared type, or confirm the coupling is intentional. ``` 这是形式概念分析(Ganter & Wille, 1999)——不是启发式方法。概念格是描述所有合法字段分组的数学结构。跨边界概念是数据支持但类型系统未反映的分组。 ### 验证重构结果 你已经合并了重复函数,修复了锁错误,重构了类型。现在验证: *“再次运行相同的信念。同时在变更的包上运行 nilness、unusedresult 和 shadow 分析。”* 信念确认约定仍然成立——或捕捉到你重构引入的新偏差。Lint 检查捕获机械性问题。调用图确认旧函数的所有调用者现在都引用了统一后的替换函数。 ## 我还可以问什么 MCP 服务器包含三个引导提示,用于结构化分析: | 提示 | 用途 | |------|------| | `goast-analyze` | 查询代码结构:AST 形状、数据流、控制流、调用关系 | | `goast-beliefs` | 定义并运行跨包的 consistency 检查 | | `goast-refactor` | 查找统一候选并验证重构的正确性 | 除了上述流程,分析层级还支持: - **调用图查询**——谁调用了这个函数?从 main 出发能到达哪里? 支持静态、CHA 和 RTA 算法。 - **控制流**——语句 A 是否支配语句 B?枚举两个块之间的所有路径。构建支配树。 - **SSA 数据流**——到达定义、活跃变量分析、常量传播、符号分析、区间分析。 基于工作列表的前向/后向分析。 - **代数等价性**——两个 SSA 表达式在交换律、恒等律和零元规则下是否等价? - **布尔简化**——将复杂的 Go 条件归一化以检测等价或冗余逻辑。 - **路径代数**——基于耦合距离、错误传播深度等的调用图上的半环最短路算法。 - **40+ lint 分析器**——完整的 `go/analysis` 套件,可通过名称调用。 ## 作为 Go 库 如果你想在自己的工具中嵌入这些分析: ``` engine, err := wile.NewEngine(ctx, wile.WithSafeExtensions(), wile.WithExtension(goast.Extension), wile.WithExtension(goastssa.Extension), wile.WithExtension(goastcfg.Extension), wile.WithExtension(goastcg.Extension), wile.WithExtension(goastlint.Extension), ) defer engine.Close() val, err := engine.Eval(ctx, `(go-parse-expr "1 + 2")`) ``` ## 构建与测试 ``` make build # Build to ./dist/{os}/{arch}/wile-goast make test # Run all tests make lint # Run golangci-lint make ci # Full CI: lint + build + test + covercheck + verify-mod ``` ## 文档 | 文档 | 内容 | |------|------| | [docs/PRIMITIVES.md](docs/PRIMITIVES.md) | 所有分析原语的完整参考 | | [docs/AST-NODES.md](docs/AST-NODES.md) | 50+ 种 Go AST 节点字段参考 | | [docs/EXAMPLES.md](docs/EXAMPLES.md) | 示例脚本的带注释逐步讲解 | | [docs/GO-STATIC-ANALYSIS.md](docs/GO-STATIC-ANALYSIS.md) | 跨层使用指南 | ## 依赖 | 依赖 | 用途 | |------|------| | [github.com/aalpar/wile](https://github.com/aalpar/wile) | R7RS Scheme 解释器与扩展 API | | golang.org/x/tools | SSA、调用图、CFG、go/analysis 框架 | | mark3labs/mcp-go | MCP 服务器(基于 stdio 的 JSON-RPC) | 基于 [Wile](https://github.com/aalpar/wile) 构建——一个 R7RS Scheme 解释器。 Go 的 AST 本身就是一棵树——S 表达式是其自然表示。 AI 能熟练编写 Scheme;你不需要会。
标签:EVTX分析, golangci-lint, gopls, Go源码分析, Go语言, grep增强, MCP服务器, Scheme脚本, SSA, 云安全监控, 代码审查, 代码搜索, 代码重复检测, 函数结构比较, 技术债务, 控制流图, 日志审计, 模式匹配, 程序破解, 类型参数化, 结构体边界分析, 编译器内部, 自动化资产收集, 调用图, 调用约定一致性, 跨层分析, 重构辅助, 锁获取与释放, 错误处理检查, 静态分析