学术研究报告:FixJS——一个用于自动程序修复的JavaScript缺陷修复提交数据集
本报告旨在介绍一项由Viktor Csuvik和László Vidács完成的研究,该研究发表于2022年5月23-24日在美国匹兹堡举行的第19届国际软件仓库挖掘会议(MSR ‘22)上。两位作者均来自匈牙利塞格德大学软件工程系及MTA-SZTE人工智能研究小组。
一、 研究背景与动机
本研究属于软件工程领域,特别是自动程序修复(Automated Program Repair, APR)这一重要子领域。自动程序修复旨在通过自动化技术修复软件中的缺陷,从而显著降低软件开发和维护的成本。近年来,基于深度学习的数据驱动APR方法取得了长足进展,这些方法依赖于从大量数据中学习缺陷模式及其修复方案。然而,该领域面临一个关键瓶颈:缺乏高质量、大规模、且易于获取的公开数据集。
现有的主流APR评估数据集,如Defects4J、QuixBugs和ManyBugs,主要针对Java和C语言,且规模较小(通常包含数百个缺陷),不足以训练复杂的深度学习模型。这导致许多先进的数据驱动APR研究不得不构建自己的私有数据集,使得不同方法之间的评估和比较变得异常困难。尽管Tufano等人先前的工作构建了一个基于GitHub提交的大型Java数据集并被纳入CodeXGLUE基准,但JavaScript作为全球最流行、在GitHub上使用最广泛的语言,在APR研究领域仍缺乏一个与之匹配的、大规模的公开基准数据集。
因此,本研究的目标非常明确:填补这一空白,为JavaScript的自动程序修复研究社区提供一个大规模、高质量、预处理的缺陷修复数据集,名为FixJS。该数据集旨在为训练和评估深度学习修复模型提供一个“开箱即用”的公共平台,促进不同APR工具之间的公平比较,并推动该领域的发展。
二、 详细研究流程与方法
本研究的工作流程主要分为两个核心阶段:缺陷修复提交挖掘(Bug-Fix Mining)和代码抽象化(Abstraction)。整个过程如图2所示,是一个从海量原始提交数据到结构化、多表示形式数据集的系统化处理管道。
第一阶段:缺陷修复提交挖掘 此阶段的目标是从GitHub上识别并获取JavaScript相关的缺陷修复提交及其对应的“缺陷前”和“修复后”代码文件。 1. 数据源与时间范围:研究使用GH Archive作为数据源,这是一个记录GitHub公共事件的数据集。出于时间和资源限制,研究选取了2012年全年(1月1日至12月30日)的推送事件(Push Events)作为初始数据池。 2. 识别缺陷修复提交:从GH Archive获取的事件中提取提交哈希(SHA)和提交信息。通过筛选提交信息中是否包含特定关键词([“fix”, “solve”, “bug”, “issue”, “problem”, “error”]),来识别潜在的缺陷修复提交。这一步骤共识别出约2,129,715个候选提交。 3. 获取JavaScript文件变更:对于每一个识别出的提交,研究利用GitHub REST API获取该提交的详细信息。首先,过滤掉非JavaScript文件(即扩展名不为.js的文件)。然后,通过API获取每个受影响的JavaScript文件在提交前(buggy version)和提交后(fixed version)的完整内容。同时,保存文件的差异信息(git diff)。 4. 数据整理:最终,此阶段成功处理了103,115个包含JavaScript文件变更的提交,涉及总计201,198个文件。每个提交的数据被组织在以提交哈希命名的文件夹中,包含before.js(缺陷代码)、after.js(修复后代码)和diff(差异文件)三个文件。
第二阶段:代码抽象化 此阶段的目标是从上一步获取的原始文件中提取出被修改的函数,并为其创建适合机器学习模型输入的表示形式。 1. 函数提取:使用Esprima库对before.js和after.js文件进行解析,生成抽象语法树(AST)。从AST中提取出发生变更的函数体。值得注意的是,提取过程忽略了函数名,因为JavaScript中函数表达式和箭头函数本就没有名称,且绝大多数修复发生在函数体内,忽略名称不会造成显著信息损失。 2. 创建三种代码表示:为了适应不同模型的需求并控制词汇表大小,研究为每个函数生成了三种不同抽象级别的表示: * 令牌化表示(Tokenized):最简单的表示。将源代码按令牌(token)分割,用空格分隔。这种表示保留了所有原始标识符和字面量,因此词汇表大小是开放且巨大的。 * 完全映射表示(Full-Mapping):在此表示中,所有的标识符(变量名、方法名)和字面量(字符串、数字、布尔值、正则表达式)都被映射为通用ID。ID的格式为类型_索引(例如var_0, string_1)。这样做将词汇表大小限制在约130个固定token(6种字面量类型 + 63个JS关键字 + ~60个特殊字符)加上每个样本中唯一的ID数量,极大地压缩了词汇空间。 * 惯用语化表示(Idiomized):这是对完全映射的泛化。研究首先统计了所有提交中令牌的出现频率,选取了前N个最常出现的“惯用语”(如i, j, 0, -1等)。在解析时,如果一个令牌属于这个惯用语集合,则保留其原始值;否则,则像完全映射一样将其替换为通用ID。这种表示在保留常见“关键词”的同时,也限制了词汇表大小(词汇表大小 = N + 固定token数 + 唯一ID数)。 3. 按大小分类:根据函数在令牌化表示中的令牌数量,将样本分为三个独立的数据集:小型(#tokens < 50)、中型(50 <= #tokens < 100)和大型(100 <= #tokens)。这有助于研究人员根据模型处理长序列的能力选择合适的训练数据。 4. 最终数据集结构:最终生成的FixJS数据集包含约30万个样本。对于每个尺寸类别(小/中/大),都提供三个文本文件对(before_tokenized.txt/after_tokenized.txt, before_mapped.txt/after_mapped.txt, before_idiom.txt/after_idiom.txt),其中每一行对应一个函数的特定表示。此外,还提供map.txt文件,其中存储了映射表示中通用ID到原始标识符的对应关系,以便在需要时还原代码。
三、 主要研究结果
string_0, var_0)的使用。这些结果直接支撑了研究的核心目标:提供一个大规模、即用型的JavaScript APR数据集。数据集的规模(约30万样本)使其适合于训练深度学习模型;其多表示形式和清晰的分类为方法研究提供了灵活性;而开源可用性则解决了现有研究中数据集私有化导致的评估壁垒问题。
四、 研究结论与价值
本研究的结论是成功创建并发布了FixJS——一个专门针对JavaScript的大规模、多表示形式的缺陷修复提交数据集。该数据集涵盖了从海量真实世界软件项目中挖掘的约30万个缺陷修复实例,并提供了三种不同抽象级别的代码表示。
其科学价值和应用价值主要体现在以下几个方面: * 为APR研究提供公共基准:FixJS为JavaScript的自动程序修复研究提供了一个标准化的、大规模的评估平台,使得不同数据驱动APR方法可以在相同的数据基础上进行公平比较,促进了该领域的可重复研究和健康发展。 * 推动深度学习在APR中的应用:大规模的数据是训练高性能深度学习模型的基石。FixJS的规模足以支持训练复杂的序列到序列(Seq2Seq)或图神经网络等模型,有助于探索更先进的APR技术。 * 支持源代码表示方法研究:数据集提供的三种不同表示(原始令牌、完全抽象、部分保留惯用语)为研究不同代码抽象策略对修复模型性能的影响提供了绝佳的实验材料。 * 促进对软件演化过程的理解:除了直接的APR应用,该数据集还可用于研究软件缺陷的模式、修复行为的共性以及软件的自然演化规律。
五、 研究亮点
六、 其他有价值的内容
研究也坦诚地讨论了FixJS的局限性。首先,数据主要来源于2012年,时间范围有限。其次,在挖掘过程中未对GitHub仓库设置质量筛选(如星标数、复刻数),因此可能包含低质量项目的提交。第三,数据集中可能包含与缺陷修复无关的“纠缠变更”。最后,与Defects4J等数据集不同,FixJS不包含测试用例,因此无法直接用于基于测试的补丁生成评估。作者将这些列为未来版本的改进方向。此外,论文还将FixJS与相关工作进行对比,指出其在样本数量(特别是大型数据集)、语言专注性(JavaScript)以及提供的多表示形式和附加提交信息方面具有优势。