Graphify 于 11 月 8 日发布新版本,将仓库路径与执行代码分离,并完善了各语言的调用关系分析。查看源代码中函数调用去向的开发者,可以降低通过路径执行代码的风险,并在图中查看此前遗漏的调用关系。
1. 将仓库路径与执行代码分离
/graphify 运行指南生成的代码块不再将扫描路径直接嵌入 Python 代码的字符串中。第一步将路径写入 graphify-out/.graphify_root 文件,后续分析和更新步骤读取该文件。
此前,路径中若包含引号或 $(...),就可能跳出 Path('INPUT_PATH') 的字符串并作为代码执行。现在,路径被视为地址数据,而非命令。这改变了仓库名称中的字符成为执行代码一部分的途径。
2. 位置改变后仍保留同一项目的节点
Python 无法确定导入目标时使用的临时节点,其标识符改为更少依赖仓库位置。通过以项目内部位置而非绝对路径为依据,即使将仓库下载到其他文件夹或移动缓存,也能保持相同标识符。这修复了图中目标的标签仅因仓库地址变化就随之改变的问题。
Windows 上也修复了同一文件因路径表示不同而产生多个缓存条目的问题。即使仓库使用长路径,记录文件状态的键仍采用相对于根目录的路径,从而在移动或克隆代码后继续使用快速查找缓存的方式。
针对子文件夹新建的图被误判为旧格式的问题也已修复。新图不再出现不必要的强制提取提示,完善了仅分析部分文件夹而非整个项目的流程。
3. 将 Solidity 和 C# 调用关联到声明
在 Solidity 中,通过在区块链上自动执行的智能合约或接口类型的值调用函数时,现在会关联到相应声明。以下是发布说明中的示例,展示了如何在图中将 token 变量的函数调用关联到其指向的声明。
IERC20 token; token.transfer()通过 using A for T 指令附加到特定类型的库函数和独立函数,其调用也会建立关联。这弥补了此前调用以这种方式附加的函数时,关系无法延伸到该函数的问题。
在 C# 中,实例构造函数、静态构造函数,以及在类型声明中接收参数、与类型声明一同定义的主构造函数,都会分别记录为独立节点。构造函数内部的调用归属于相应节点,创建对象或调用其他构造函数的代码则关联到参数数量匹配的构造函数。
属性和索引器的访问器,即读取或修改属性值的部分,其内部发生的调用也会关联到相应成员。索引器提供像数组一样通过方括号读写值的功能。该版本还记录表达式体、运算符和类型转换体中的调用,减少普通方法之外的调用遗漏。
Solidity 在无法确定目标类型或无法将候选缩小为一个时,会暂缓建立关联。C# 在参数数量匹配的构造函数候选有两个,或无法确认基类构造函数时,也不会添加构造函数关联。
4. 变更监视聚焦必要的重建
当监视工具支持事件过滤器时,会将只读事件排除在监视范围之外,仅处理变更事件。这是为了防止大型目录中事件队列反复溢出的问题。
监视过程中若图文件不存在,将重新构建整个图,而不是仅凭部分信息生成不完整的图。决定 JavaScript、TypeScript 导入路径的配置文件或锁文件发生变化时,也会执行全量重建。这修复了配置变更后图中仍保留旧文件关联的问题。
5. 准确性提升与缓存重新计算的成本
此次变更在仓库移动后保持标识符稳定,并减少各语言的调用遗漏,但也带来了重新执行部分分析的成本。决定语法分析结果存储所用代码结构与存储格式的 AST 缓存模式升至 40,因此若存在旧缓存,将重新执行受影响的 Solidity、C# 提取。Python 标识符的修复不需要更改缓存模式。
Graphify 0.9.104 提高了路径移动和分语言调用追踪的可靠性,但部分变更需要重新提取或重新计算整个图。
