IBM/tree-sitter-codeviews
GitHub: IBM/tree-sitter-codeviews
基于 tree-sitter 的多代码视图生成工具,可提取并组合 AST、CFG、DFG 等代码表示,服务于机器学习驱动的软件工程研究。
Stars: 162 | Forks: 23
# Tree Sitter Multi Codeview Generator
Tree Sitter Multi Codeview Generator 旨在生成组合的多代码视图图,这些图可与各种类型的机器学习模型(序列模型、图神经网络等)配合使用。
# Comex
`comex` 是 Tree Sitter Multi Codeview Generator 的重构版本,旨在作为 Python 包更易于调用。此次重构还包含了一个 CLI 接口。目前,`comex` 可以为 Java 和 C# 生成代码视图,支持方法级别和文件级别的代码片段。`comex` 可用于为这两种语言生成超过 $15$ 种可能的代码视图组合(完整列表见[此处](https://github.com/IBM/tree-sitter-codeviews/blob/main/List_Of_Views.pdf))。`comex` 的设计使其能够轻松扩展至各种编程语言。这主要是因为我们使用了 [tree-sitter](https://tree-sitter.github.io/tree-sitter/) 进行解析,这是一个支持超过 $40$ 种语言的高效增量解析器。如果您希望添加对更多语言的支持,请参阅[贡献](https://github.com/IBM/tree-sitter-codeviews/blob/main/CONTRIBUTING.md)指南。
如果您想了解有关所采用方法的更多信息,以下是一些会议演讲和出版物:
- ASE 2023 演示:[COMEX:一种生成自定义源代码表示的工具](https://arxiv.org/abs/2307.04693)
- ICSE 2023 教程:[AI 驱动的软件工程任务中源代码表示学习的概览](https://research.ibm.com/publications/the-landscape-of-source-code-representation-learning-in-ai-driven-software-engineering-tasks)
Comex 在开发 `CodeSAM` 的过程中发挥了关键作用,`CodeSAM` 是一个用于将多代码视图注入基于 transformer 模型的新型框架。CodeSAM 构建于 `comex` 等工具之上,用于创建结构化的代码表示(例如 AST、CFG、DFG),从而支持对 CodeBERT 等语言模型进行微调。实验结果表明,通过使用这种技术,在针对 ML for SE(机器学习在软件工程中的应用)任务进行微调时,通过利用单个代码视图或组合的代码视图,与 GraphCodeBERT 和 CodeBERT 等 SLM 相比,可以提高下游性能。
您可以在以下预印本中找到有关 `CodeSAM` 的更多详细信息:
- [CodeSAM:通过将自注意力与多代码视图图融合进行源代码表示学习](https://arxiv.org/abs/2411.14611)
## 引用 Comex
如果您在研究中使用了 Comex,请使用以下 BibTeX 条目来引用我们的工作:
```
@inproceedings{das2023comex,
title={COMEX: A Tool for Generating Customized Source Code Representations},
author={Das, Debeshee and Mathews, Noble Saji and Mathai, Alex and Tamilselvam, Srikanth and Sedamaki, Kranthi and Chimalakonda, Sridhar and Kumar, Atul},
booktitle={2023 38th IEEE/ACM International Conference on Automated Software Engineering (ASE)},
pages={2054--2057},
year={2023},
organization={IEEE}
}
```
## 从 PyPi 安装
`comex` 已发布在 Python Registry 上,可以通过 pip 轻松安装:
```
pip install comex
```
**注意**:您需要安装 GraphViz([dot](https://graphviz.org/download/))才能生成图形可视化。
## 从源码安装
要在您的 Python 环境中使用源代码进行 `comex` 的开发设置:
```
pip install -r requirements-dev.txt
```
这会执行一个可编辑的安装,这意味着 `comex` 将在您的整个环境中可用(如果您使用 conda 或类似工具,这一点尤为相关)。这意味着现在您可以像对待任何其他包一样与 `comex` 进行交互并从中导入,同时它保持独立运行,并且能反映任何代码侧的更新,无需执行其他手动步骤。
## 作为 CLI 使用
这是开始使用 `comex` 的推荐方式,因为它是最用户友好的。
CLI 支持的属性和选项都有详细的文档说明,可以通过运行以下命令查看:
```
comex --help
```
例如,要为 Java 文件生成组合的 CFG 和 DFG 图,您可以运行:
```
comex --lang "java" --code-file ./test.java --graphs "cfg,dfg"
```
## 作为 Python 包使用
可以通过导入所需的驱动程序来使用 comex 包,如下所示:
```
from comex.codeviews.combined_graph.combined_driver import CombinedDriver
CombinedDriver(
src_language=lang,
src_code=code,
output_file="output.json",
graph_format=output,
codeviews=codeviews
)
```
在大多数情况下,可以通过 `combined_driver` 模块获取所需的组合,如上所示。
```
src_language: denotes one of the supported languaged hence currently "java" or "cs"
src_code: denotes the source code to be parsed
output_file: denotes the output file to which the generated graph is written
graph_format: denotes the format of the output graph. Currently supported formats are "dot" and "json". To generate both pass "all"
codeviews: refers to the configuration passed for each codeview
```
## 限制
虽然 `comex` 为 Java 和 C# 提供了方法级别和文件级别的支持,但请注意以下限制和已知问题:
### Java
- **不支持跨文件分析**:该工具目前不支持涉及多个 Java 文件之间交互的代码视图。它被设计为仅为单个 Java 文件生成代码视图。
- **代码中的语法错误**:尽管支持不可编译的代码,但为了确保代码视图的准确性,输入的 Java 代码必须没有语法错误。包含语法错误的代码可能无法被正确解析并显示在生成的代码视图中。
- **对函数调用参数的支持有限**:该工具未对在 Java 代码中将函数调用作为参数传递给另一个函数调用的情况提供适当的支持。在这种情况下,生成的代码视图可能无法准确表示预期的行为。
### C\#
除了针对 Java 提到的限制外,该工具还具有以下特定于 C# 的限制:
- **不支持 Lambda 函数和箭头表达式**:该工具不支持涉及 C# 中 lambda 函数和箭头表达式的代码视图。生成的代码视图可能无法准确表示这些语言特性。
- **不支持编译器指令**:该工具不支持编译器指令,例如 pragma 指令。包含此类指令的代码可能无法在生成的代码视图中正确显示。
- **不完整的运算符声明支持**:该工具对 C# 中的运算符声明可能仅提供有限的支持。与运算符重载相关的某些约束和边缘情况可能无法在生成的代码视图中完全捕获。
- **对继承和抽象的支持有限**:该工具对 C# 中继承和抽象的支持并不全面。涉及复杂继承层次结构或高级抽象模式的代码视图可能无法被准确表示。
请注意,尽管我们不断努力改进该工具并解决这些限制,但当前的实现可能并不完美。感谢您的理解,并鼓励您提供反馈和报告您遇到的任何问题,因为这有助于我们增强该工具的功能。
## 输出示例:
为一个求两个数中最大值的简单 Java 程序组合生成的 AST+CFG+DFG 图:

下面我们展示了 Java 和 C# 的输入代码片段和生成的代码视图的更多示例。
**CLI 命令**:
```
comex --lang "java" --code-file sample/example.java --graphs "cfg,dfg"
```
**Java 代码片段**:
```
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
public class Main {
// static String INPUT = "5\n3 2 2 4 1\n1 2 2 2 1";
static String INPUT = "";
public static void main(String[] args) {
InputStream is = INPUT.isEmpty() ? System.in : new ByteArrayInputStream(INPUT.getBytes());
Scanner scanner = new Scanner(is);
final int n = scanner.nextInt();
List positionList = new ArrayList<>(n);
for (int i = 0; i < n; i++) {
positionList.add(
new Position(
scanner.nextInt(),
scanner.nextInt(),
scanner.nextInt()
)
);
}
System.out.println(solve(positionList) ? "Yes" : "No");
}
static class Position {
int t;
int x;
int y;
public Position(int t, int x, int y) {
this.t = t;
this.x = x;
this.y = y;
}
}
static boolean solve(List positionList) {
Position currentPosition = new Position(0, 0, 0);
for (int i = 0; i < positionList.size(); i++) {
Position nextPosition = positionList.get(i);
if (!possibleMove(currentPosition.t, nextPosition.t, currentPosition.x, nextPosition.x, currentPosition.y, nextPosition.y)) {
return false;
}
currentPosition = nextPosition;
}
return true;
}
static boolean possibleMove(int t1, int t2, int x1, int x2, int y1, int y2) {
int tDiff = t2 - t1;
int absX = Math.abs(x1 - x2);
int absY = Math.abs(y1 - y2);
if (absX + absY <= tDiff) {
if (tDiff % 2 == (absX + absY) % 2) {
return true;
}
}
return false;
}
}
```
**生成的代码视图**:

**CLI 命令**:
```
comex --lang "cs" --code-file sample/example.cs --graphs "cfg,dfg"
```
**C# 代码片段**:
```
public class DFG_A2 {
public void main(string[] args) {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); // {}
String str = br.attribute1; // {3}
str = br.attribute2.method1(); // {3}
br.attribute1 = br.attribute2; // {3,5}
br.method2(br.attribute1, br.attribute2); // {3,5,6}
BufferedReader br2 = br; // {5,6,7}
br.method3(); // {5,6,7}
int j = br2.attribute1.method2(3,4); // {8}
}
}
```
**生成的代码视图**:

更多示例和结果可以在 [tests/data](https://github.com/IBM/tree-sitter-codeviews/tree/main/tests/data) 目录中找到。
### 代码组织
代码的结构如下:
1. 对于每个代码视图,首先使用 tree-sitter 解析器解析源代码,然后生成各种代码视图。在 [tree_parser](https://github.com/IBM/tree-sitter-codeviews/tree/main/src/comex/tree_parser) 目录中,Parser 和 ParserDriver 实现了所有代码视图通常所需的各种功能。特定语言的功能则在该目录中放置的特定语言解析器中进一步开发。
2. [codeviews](https://github.com/IBM/tree-sitter-codeviews/tree/main/src/comex/codeviews) 目录包含各种代码视图的核心逻辑。每个代码视图都有一个驱动类和一个 codeview 类,对于需要特定语言实现的代码视图,该类会按语言进一步继承和扩展。
3. [cli.py](https://github.com/IBM/tree-sitter-codeviews/tree/main/src/comex/cli.py) 文件是 CLI 的实现。驱动程序也可以像 Python 包一样直接导入和使用。它负责解析源代码并生成代码视图。
### 测试
该仓库设置为在向 main 和 development 分支发起 pull 时自动执行 CI 测试。
要在本地进行测试:
运行特定测试
- 假设您希望运行 `test_cfg` 函数
- 删掉 `'[...]'` 部分以运行文件中的所有测试
- 格式为 [extension-filename]
- no-cov 可阻止打印覆盖率报告
```
pytest -k 'test_cfg[cs-test7]' --no-cov
```
运行所有测试并获取覆盖率报告
```
pytest
```
通过使用详细输出分析由 `deepdiff` 给出的偏差报告。
这将有助于快速找出与标准文件(gold file)的差异
```
pytest -k 'test_cfg[cs-test7]' --no-cov -vv
```
### 发布
确保在 `setup.cfg` 中更新版本号。
然后运行以下命令:
```
rm -rf build dist
python setup.py sdist bdist_wheel
```
然后使用 [twine](https://twine.readthedocs.io/en/latest/#installation) 将其上传到 PyPI(如果未安装,请执行 `pip install twine`):
```
twine upload dist/*
```
### 关于 IBM OSCP 项目
该工具是作为 OSCP 项目的一部分为研究目的而开发的。高效的源代码表示对于使用 AI 流水线执行各种软件工程任务(如代码翻译、代码搜索和代码克隆检测)至关重要。代码表示旨在提取源代码的句法和语义特征,并将其表示为一个向量,以便直接用于下游任务。现有多项研究尝试将代码编码为序列数据,以轻松利用像 transformer 这样最先进的神经网络模型。但这会导致信息的丢失。图是代码的自然表示,但很少有研究(MVG-AAAI'22)尝试将不同代码视图(如程序依赖图、数据流图等)中获得的不同代码特征表示为多视图图。在这项工作中,我们希望探索更多的代码视图及其与不同代码任务的相关性,并利用 transformer 模型处理多代码视图图。我们相信这样的工作将有助于:
1. 确立特定代码视图对常见任务的影响
2. 演示如何将图与 transformer 结合
3. 创建可复用的模型
### 团队
该工具基于 IBM 与 [IIT Tirupati](https://www.iittp.ac.in/) 的 [Risha Lab](https://rishalab.in/) 之间正在进行的一项联合研究成果,旨在探索不同代码表示对基于代码的任务的影响,主要涉及人员包括:
- [Srikanth Tamilselvam](https://www.linkedin.com/in/srikanth-tamilselvam-913a2ab/)
- [Sridhar Chimalakonda](https://www.linkedin.com/in/sridharch/)
- [Alex Mathai](https://www.linkedin.com/in/alex-mathai-403117131/)
- [Debeshee Das](https://www.linkedin.com/in/debeshee-das/)
- [Noble Saji Mathews](https://www.linkedin.com/in/noble-saji-mathews/)
- [Kranthi Sedamaki](https://www.linkedin.com/in/kranthisedamaki/)
标签:AI辅助软件工程, Apex, CFG, CodeBERT, DFG, GNN, IBM, odt, Transformer, Tree-sitter, 代码特征提取, 代码理解, 代码表示学习, 代码视图, 可配置连接, 图生成, 图神经网络, 大语言模型微调, 序列模型, 开源, 抽象语法树, 控制流图, 数据流图, 机器学习, 树解析, 深度学习, 源代码分析, 程序分析, 逆向工具