龙空技术网

通过学习以识别和重构不一致方法名称

慕测科技 112

前言:

此时同学们对“论坛帖子代码”大体比较关怀,各位老铁们都需要了解一些“论坛帖子代码”的相关知识。那么小编在网摘上搜集了一些有关“论坛帖子代码””的相关内容,希望兄弟们能喜欢,我们一起来学习一下吧!

1 引用

Liu K, Kim D, Bissyandé T F, et al. Learning to spot and refactor inconsistent method names[C]//2019 IEEE/ACM 41st International Conference on Software Engineering (ICSE). IEEE, 2019: 1-12.

2 摘要

为了确保代码可读性并便于软件维护,程序方法需要被恰当地命名。尤其方法名称需要与相应的方法实现相一致。调试方法名称是一个重要的研究方向,其中存在各种方法分析大型数据集中方法名称之间的共性,以检测不一致的方法名称并提出更好的方法命名建议。我们发现最新技术并没有分析已实现的代码本身以评估一致性。因此,我们基于方法名称和方法代码之间一致性分析,提出了一种新颖的自动化方法来调试方法名称。对超过 210 万种 Java 方法的实验结果表明,与最新技术相比,我们最多可以提高 15 个百分点,同时在识别不一致的方法名称方面,F1 度量达到了 67.9%。我们进一步表明,我们的方法在建议全名时的准确率高达 25%,同时在真实程序场景下成功修复了 66 个不一致的方法名称。

3 引言

在编程中,名称(即标识符)在所有程序概念中都很普遍,例如类,方法和变量。描述性名称是被识别对象的直观特征,因此正确的命名对于确保软件程序的可读性和可维护性至关重要。正如包括 McConnell,Beck 和 Martin 在内的许多行业专家所强调的那样,命名是编程中的关键活动之一。

对于程序开发人员而言,命名是一项艰巨的任务。Johnson 进行的研究得出结论,标识符命名是程序员必须完成的最艰巨的任务。事实上由于各种原因,例如缺乏良好的词库,多个开发人员协作期间的样式冲突以及代码克隆不正确,开发人员经常在程序中编写质量较差(即不一致)的名称。

方法名称是开发人员了解程序或 API 行为的直观且重要的信息。因此不一致的方法名称会使程序难于理解和维护,甚至可能导致软件故障。较差的方法名的确容易导致故障。例如,常用的 FindBugs 静态分析器甚至枚举多达十种与方法标识符相关的错误类型。

图 1 提供了项目 AspectJ 中的示例,以说明不一致的名称如何混淆方法的可执行行为。第一个方法的名称 containsField 与该方法的行为一致,该行为检查 fieldsList 是否包含目标字段 f 的。第二种方法实现了对目标数据集中字段的搜索,因此始终被命名为 findField。第三种方法的实现与第二种方法 findField 相似,但是将其命名为 containsField,此名称不一致,可能导致误解 API 使用情况。

图 1 AspectJ 示例

作为对方法命名不一致问题的初步研究,我们调查了开发人员和用户在论坛和代码库上的帖子。我们使用“方法名称”和关键字类别(即不一致,一致性,误导性,不合适,不正确,令人困惑,错误,故障和缺陷)的组合连接来执行搜索,以匹配 StackOverflow 中的相关问题以及在 GitHub 中的提交日志。最终我们识别了 5644 个问题和 183901 次提交。图 2 显示了一些检索结果的片段。

图 2 识别的不一致方法名称问题的片段

此外,为了评估开发人员修复方法名称的难易程度,我们调查了实验中收集的所有 430 个项目的更改历史记录:存在 53,731 次提交,更改了方法名称而未更改相应的主体代码。我们进一步跟踪了之后的更改,并注意到在 16%的情况下,更改是最终的(即在项目的之后版本中,方法主体和方法名称均未再次更改)。这些发现表明,开发人员确实在努力选择适当的方法名称,通常是为了解决与代码上下文的一致性的问题。

为了调试方法名称,Høst 和 Østvold 探索了方法命名规则和方法实现的语义特征。Kim 等人依靠自定义代码字典来检测不一致的名称。Allamanis 等人引入了 NATURALIZE 框架从本地上下文中学习领域特定的命名约定,以使用 n-gram 模型提高代码标识符的风格一致性。然后在此框架的基础上,他们提出了一种对数双线性神经概率语言模型,以建议具有相似上下文的方法名和类名。

总体而言,它们的上下文信息仅限于本地标识符子令牌以及输入和输出的数据类型。尽管最新的技术取得了可喜的成果,但尚未考虑命名方法的主要标准:由于方法名称应仅仅是方法行为的概述,具体实现应是评估方法命名一致性的主要特征。图 1 中的示例说明了我们工作背后的直觉:在主体代码中实现相似行为的方法可能会使用相似的名称,反之亦然。通过考虑相似实现的方法的一致名称,应该有可能为方法建议新名称,以代替其不一致的名称。

在本文中,我们提出了一种新颖的自动化方法来识别和重构不一致的方法名称。我们的方法利用了段落向量和卷积神经网络来分别提取方法名称和代码实现的深层表示。然后给定一个方法名称,我们计算出两组相似的名称:第一个对应于可以由训练后的方法名称模型识别的名称;另一方面,第二个方法包括其主体被确定为与输入方法的主体相似的方法名称。如果这两个集合在某种程度上相交,则该方法名称被标识为一致,否则为不一致。当输入法名称标记为不一致时,我们进一步利用第二组一致名称来建议新名称。

为了评估我们提出的方法,我们从 430 个开源 Java 项目中收集了 2,116,413 种训练数据方法和 2,805 种测试方法进行了实验。我们的实验结果表明,该方法在识别不一致方法名称上 F1 度量达到了 67.9%,比现今最佳的方法改进了 15%。进一步,该方法在建议第一个子标记时达到 34-50%的准确性,在为不一致的方法名称建议准确的全名时达到 16-25%的准确性,均优于现有技术。最后我们报告了相关的研究中,我们的方法如何帮助开发人员在 10 个项目中修复了 66 个不一致的方法名称。

4 背景介绍

本节将简要介绍了神经网络领域的三种技术,即 Word2Vec,段落向量和卷积神经网络。我们的方法依靠这些技术来实现两个目标:(1)将方法名称和代码主体中的标记嵌入数字矢量形式中;(2)提取特征表示形式以准确识别相似的方法名称和代码主体。

(1)段落向量(Paragraph Vector:):段落向量是一种无监督算法,可从可变长度的文本(例如句子和段落)中学习固定长度的特征表示。该技术是可以有效地克服词袋特征的局限性,这些特征会(1)失去了词的顺序,并且(2)忽略了词的语义。最新文献的相关分析表明段落向量优于其他最新技术的文本表示,并且可以有效地捕获单词和句子之间的语义相似性。

在我们的工作中,我们使用段落向量来训练模型以计算方法名称之间的相似度(将方法名称子标记的序列视为句子)。我们希望该模型不仅要考虑词汇上的相似性,还要考虑语义上的相似性。例如,函数名称 containsObject 和 hasObject 应该归类为相似名称,因为它们都描述了检查集合是否包含特定对象的功能。我们将在本文的后半部分详细介绍如何利用段落向量算法的处理方法名称。

(2)卷积神经网络(Convolutional Neural Networks,CNNs):CNN 是多层人工神经网络的生物学启发变体。CNN 最初在图像识别领域得到应用并证明是有效的,同时在处理各种 NLP 任务已受欢迎。特别是对于文本分类,这些深度学习模型通过设法捕获句子的语义进行相关的相似度计算,取得了显着的结果。最近一些实证研究表明了软件的自然性。因此,在自然假设的启发下,我们将源代码(尤其是方法主体)视为以自然语言编写的文档,并且将 CNN 应用于该文档以进行代码嵌入。目的是生成一个可以准确识别相似的方法代码的模型。Bui 等人最新的研究结果表明,CNN 的某些变体甚至可以有效地捕获代码语义,从而允许跨编程语言对代码实现进行准确分类。

(3)Word2Vec:将方法主体的令牌提供给 CNN 时,必须将令牌转换为数值向量。否则如果使用单点编码,CNN 输入层的规模将太大。机器学习社区经常将矢量表示用于单词标记。该做法具有两个优点:(1)大量(唯一)令牌可以表示为固定宽度的矢量形式(降维);(2)相似令牌可以位于矢量空间中,以便可以将相似令牌以类似方式处理 CNN。我们的方法使用 Word2Vec 嵌入方法主体的标记。

Word2Vec 是一种将令牌编码为 n 维向量的技术。它是专门用于处理令牌序列的两层神经网络。神经网络将一组标记序列(即句子)作为输入,并在标记和数值向量之间产生映射。该技术不仅将令牌嵌入数字向量中,而且还将语义相似的词放置在向量空间中的相邻位置。

5. 方法概述

本节将介绍了调试不一致方法名称的方法。如图 3 所示,它涉及两个阶段:(1)训练阶段;(2)识别和建议阶段。在训练阶段,以真实项目中的大量方法作为输入,该方法将使用段落向量用于方法名称,使用 Word2Vec 和 CNN 用于方法主体,以将它们分别嵌入到数值向量中。最终将产生两个不同的向量空间,并将在下一阶段中利用它们。因此训练阶段的目标是将相似的方法名称和代码主体放置在每个向量空间的相邻位置中。

识别和建议阶段通过比较在方法名称向量空间中接近的方法名称集合与方法主体向量空间中接近的方法名集合的重叠程度,来确定给定方法的名称是否与其主体代码一致。方法主体向量空间。当重叠为 ∅ 时,该名称被认为与主体代码不一致,并建议使用其他一致的名称。

在解释这两个阶段的详细信息之前,我们首先描述一些数据处理的基本步骤。

5.1 数据预处理

此步骤旨在准备将给定方法的原始数据输入到我们方法的工作流程中。我们考虑代码的文本表示形式,并将其转换为令牌(即基本数据单元),这些令牌适用于上节中描述的深度表示学习技术。鉴于方法名称和主体具有不同的形状(即名称是关于自然语言的描述,而主体则专注于算法的代码实现),我们建议使用适用于每种形式的标记化技术:

(1)方法名称标记化:方法名称根据驼峰大小写和下划线命名约定分为子令牌序列,并将获得的子令牌转换为小写形式。先前的研究已证明该策略的有效性。例如,方法名称 findField 和 find_field 被标记为相同的序列[find,field],其中 find 和 field 分别是名称的第一和第二子标记。

(2)方法主体标记化:按照我们先前研究中提出的代码解析方法,将方法主体转换为文本标记序列。该方法使用深度优先搜索算法遍历方法主体代码的抽象语法树(AST)以收集两个令牌的种类:AST 节点类型和原始代码令牌。例如声明语句“ int a;”将被转换为四个标记的序列:[PrimitiveType,int,Variable,a]。由于代码的冗余信息(例如非描述性变量名 a,b)可能会干扰识别类似的代码,因此所有本地变量都将其名称重命名为其数据类型与字符串 Var 的串联。最终,先前的声明代码将由以下序列表示:[PrimitiveType,int,Variable,intVar]。

5.2 训练

此阶段使用代码语料库中的方法名称和主体的标记来生成两个数值向量空间,一方面利用这些数字向量空间来计算相似性,另一方面可以利用方法主体之间的相似性来最终标识不一致的名称并建议适当的名称。需要注意的是我们的目标不是训练一个分类器,以根据给定方法名称或主体输出某些分类标签。相反,我们采用无监督学习和惰性学习的思想来嵌入方法名称和主体。

5.3 识别和建议

此阶段包含两个子步骤。首先,该技术将给定方法作为查询,进行不一致识别分析。通过利用两个向量空间(即 VN 和 V’B)和两个嵌入函数(即 NVname 和 NVbody),它可以确定给定方法的名称是否与其主体一致。其次,如果名称不一致,则该方法会从类似实现的方法的名称中建议潜在的一致名称。

(1)不一致识别:对于给定的方法 mi,我们可以分别为其名称(ni)和主体(bi)选取一组相邻的向量(即 adj(ni)和 adj(bi))。检索与 adj(ni)和 adj(bi)中的向量对应的实际名称(即 name(*))后,我们可以将两个名称集之间的交集计算为 Cfull:

Cfull = name(adj(ni)) ∩ name(adj(bi))

如果 Cfull 是空集,我们认为代码主体 bi 和其名称 ni 不一致。

(2)名称建议:我们的方法通过提供相似名称的排名列表,为给定方建议新名称,并提供以下四种排名策略:

R1)该策略仅依赖于方法主体之间的相似性。相似方法主体的名称(Namesbi adj)通过与给定方法主体的相似性(在 V b 和 BodyVadj 之间)进行排名。

R2)该策略首先在 Name 中对相同的名称进行分组,因为可能存在重复。然后,它根据关联组的大小对不同的名称进行排序。根据 R1 方法主体之间的相似性来解决多个条件满足的情况。

R3)与 R2 相似,此策略在 Names 中将相同的名称分组。然后,该策略计算与每个组的 bi 的平均相似度,并根据平均相似度对组进行排名,但不考虑分组的规模。

R4)为了避免使用 R3 策略时高优先级组的规模较小,该策略最终通过将所有小规模的组降级到最低位置来对 R3 中产生的所有组重新排序

6 总结

方法名称对系统可读性和可维护性至关重要,但是为方法指定适当的名称并非易事。因此许多方法的名称并不一致,可能会妨碍程序的可读性和可维护性,甚至导致某些缺陷。为了减少解决不一致的方法名称的手动工作,我们提出了一种新颖的方法,该方法利用深度学习技术来调试不一致的方法名称。我们的实验结果表明,在识别不一致的方法名称时,我们的方法的 F1 度量达到了 67.9%。在为不一致的方法名称建议适当的第一个子标记和全名时,它分别达到了 34-50%和 16-25%的准确度,均明显优于最新的技术。我们进一步实验表明该方法可帮助开发人员修复 66 个不一致的方法名称。最后本文中使用的工具和数据可从获得。

致谢

本文由南京大学软件学院 2020 级博士张犬俊翻译转述。

标签: #论坛帖子代码