代码推荐的制作方法

文档序号:12287746阅读:176来源:国知局
代码推荐的制作方法与工艺

代码重用可以改进软件开发的效率。例如,许多应用编程接口(API)方法能够被调用并且被使用在各种编程上下文中以完成相应的任务。如已知的,第三方API库可以包含数百或甚至数千个API方法或函数。另外,在软件开发项目中,软件工程师通常将大量方法设计并实现为用于稍后调用的内部API。结果,特定于项目的API方法的数量也可能是巨大的。

实践中,遗憾的是,关于API方法及其用途的知识常常没有被很好地归档。当使用API方法时,存在由用于学习那些API方法的不充足的或缺少的资源造成的障碍。软件工程师知道存在可能有助于完成他/她的任务的创建API方法。然而,他/她常常不能够记住确切的API方法或如何使用它。针对代码推荐和代码完成的传统解决方案通常遭受不足够的准确性、效用和/或用户友好性。



技术实现要素:

当前,难以确定针对特定编程任务的API方法的适当的子集。因此,对于用户而言有挑战的是有效地且高效地在不同的编程上下文中调用和使用API方法,尤其是对于具有关于API的相对较少知识的那些用户。实际上,在不考虑特定编程上下文的情况下,一些推荐的代码不适合于当前任务并且因此是毫无意义的。此外,在大规模代码库中可能存在数以万计的API方法,并且单个API方法可以具有几种用途。因此,重要的是提供那些API方法及其用途的高覆盖率。同时,代码推荐应当是简洁的以避免提供基本上相似或相同的用途的代码片断。另外,如果有用户必须做出额外的努力以确定如何使所推荐的代码片断适应于当前编程上下文,则用户体验将被降低,尤其是利用不支持用于快速地浏览、选择和/或编辑代码推荐的有效的且高效的方式的传统用户接口。

本文中描述的主题的一个方面涉及存储各种方法的用途的知识库的构建。在一个实施例中,代码片断根据可以由包含于该代码片断中的方法用途的集合呈现的方法用途来分组。为了实现方法用途的高覆盖率,在一个实施例中,要被分组的一个或多个代码片断可以以调用为中心的方式来提取。针对任何得到的组,代表性代码片断被选择。所表示的代码片断与至少指示代表性代码片断中的变化点的元数据相关联地被存储在知识库中。以这种方式,知识库是可扩展的并且元数据可以提供推荐中的有用信息。

本文中描述的主题的另一方面涉及代码推荐。在一个实施例中,当前编程上下文基于方法调用来获得。一个或多个候选代码片断基于编程上下文从知识库中来检索并且被推荐给用户。在一个实施例中,检索到的代码片断可以根据一个或多个准则来排名。在一个实施例中,有可能基于相关联的元数据来突出所推荐的代码片断中的一个或多个变化点,使得用户能够有效地且高效地使代码片断适应于特定编程上下文。结果,代码推荐的质量、利用率和用户友好性得到改进。

本发明内容被提供为以简化的形式介绍下面在具体实施方式中进一步描述的一系列概念。本发明内容不旨在标识所要求保护的主题的关键特征或必要特征,也不旨在用于限制所要求保护的主题的范围。

附图说明

图1图示了本文中描述的主题的实施例可以被实现在其中的计算环境的框图。

图2图示了根据本文中描述的主题的一个实施例的用于代码推荐的系统的框图;

图3图示了根据本文中描述的主题的一个实施例的用于构建知识库的流程图;

图4图示了根据本文中描述的主题的一个实施例的在代码片断中标识的变化点的示例;

图5图示了根据本文中描述的主题的一个实施例的用于从代码段中提取代码片断的流程图;

图6图示了根据本文中描述的主题的一个实施例的通过以调用为中心的切分进行的代码片断提取的示例;

图7图示了根据本文中描述的主题的一个实施例的存在于所提取的代码片断中的代码克隆的示例;

图8图示了根据本文中描述的主题的实施例的用于代码推荐的方法的流程图;

图9图示了根据本文中描述的主题的实施例的用于构建知识库的系统的框图;以及

图10图示了根据本文中描述的主题的实施例的用于代码推荐的系统的框图。

具体实施方式

现在将参考几个示例实施例讨论本文中描述的主题。应当理解,这些实施例仅仅出于使得本领域技术人员能够更好地理解并且因此实现本文中描述的主题的目的来讨论,而非暗示对本主题的范围的任何限制。

如本文中所使用的,术语“包括”及其变型要被解读为意指“包括但不限于”的开放式术语。术语“或者”要被解读为“和/或”,除非上下文另行清楚指示。术语“基于”要被解读为“至少部分地基于”。术语“一个实施例”和“实施例”要被解读为“至少一个实施例”。术语“另一实施例”要被解读为“至少一个其他实施例”。下面可以包含其他定义,无论是显式的还是隐式的。

图1图示了所描述的主题的一个或多个实施例可以被实现在其中的计算环境100的示例。计算环境100不旨在暗示对本文中描述的主题的使用或功能的范围的任何限制,因为各种实施例可以被实现在各种各样的通用或专用计算环境中。

参考图1,计算环境100包括至少一个处理单元(或处理器)110和存储器120。处理单元110运行计算机可执行指令并且可以为真实处理器或虚拟处理器。在多处理系统中,多个处理单元运行计算机可执行指令以提高处理能力。存储器120可以为易失性存储器(例如,寄存器、缓存、RAM)、非易失性存储器(例如,ROM、EEPROM、闪速存储器)或这两者的某种组合。存储器120存储用于构建知识库和/或代码推荐的软件170的至少一部分。

计算环境100可以具有附加的组件或特征。在图1中示出的示例中,计算环境100包括存储装置130、一个或多个输入设备140、一个或多个输出设备150以及一个或多个通信连接160。诸如总线、控制器或网络互连件的互连机构(未示出)将计算环境100的组件相互连接。通常,操作系统软件(未示出)提供针对在计算环境100中运行的其他软件的操作环境,并且协调计算环境100的组件的活动。

存储装置130可以为可移除的或不可移除的,并且可以包括计算机可读存储介质,诸如闪速驱动器、磁盘、磁带或磁带盒、CD-ROM、CD-RW、DVD的、或者能够被用于存储信息并且能够在计算环境100内被访问的任何其他介质。存储装置130可以存储针对软件170的指令的至少一部分。

输入设备140可以为各种不同的输入设备中的一个或多个输入设备。例如,输入设备140可以包括用户设备,诸如鼠标、键盘、跟踪球等。输入设备140可以实现一种或多种自然用户接口技术,诸如语音识别、触摸和触笔识别、与输入设备140相接触以及与输入设备140相邻的手势的识别、空中手势的识别、头部和眼部跟踪、声音和语音识别、感测用户大脑活动、以及机器智能。作为其他示例,输入设备140可以包括扫描设备;网络适配器;CD/DVD阅读器;或者向计算环境100提供输入的另一设备。输出设备150可以为显示器、打印机、扬声器、CD/DVD刻录机、网络适配器、或提供来自计算环境100的输出的另一设备。输入设备140和输出设备150可以被并入在单个系统或设备(诸如触摸屏或虚拟现实系统)中。

通信连接160实现通过通信介质到另一计算实体的通信。附加地,计算环境100的组件的功能可以被实现在单个计算机器中或者能够通过通信连接进行通信的多个计算机器中。因此,计算环境100可以操作于使用到一个或多个远程计算设备的逻辑连接的网络化环境中,一个或多个远程计算设备诸如手持计算设备、个人计算机、服务器、路由器、网络PC、对等设备或另一公共网络节点。通信介质以经调制的数据信号传达诸如数据或计算机可执行指令或请求的信息。“经调制的数据信号”是具有以将信息编码在信号中的方式设置或改变的其特性中的一个或多个特性的信号。通过举例而非限制的方式,通信介质包括利用电气载体、光学载体、RF载体、红外载体、声学载体或其他载体实现的有线或无线技术。

本主题的实施例能够在计算机可读介质的总体上下文中进行描述,计算机可读介质可以为存储介质或通信介质。计算机可读存储介质是能够在计算环境内被访问的任何可用存储介质,但是术语计算机可读存储介质不指代传播的信号本身。通过举例而非限制的方式,在计算环境100内,计算机可读存储介质包括存储器120、存储装置130及其组合。

本主题的实施例能够在计算机可读指令的通用上下文中进行描述,计算机可读指令诸如被包括在程序模块中的、在计算环境中被运行在目标真实或虚拟处理器上的那些指令。总体上,程序模块包括例程、程序、库、对象、类、组件、数据结构等,其执行特定任务或实现特定抽象数据类型。程序模块的功能可以根据期望在各种实施例中被组合或在程序模块之间被拆分。针对程序模块的计算机可执行指令可以被运行在本地或分布式计算环境内。在分布式计算环境中,程序模块可以被定位在本地计算机存储介质和远程计算机存储介质两者中。

图2图示了根据本文中描述的主题的实施例的用于代码推荐的系统200的框图。如所示出的,系统200包括知识库210。除此之外,知识库210存储关于能够在编程中被调用的一个或多个方法的用途的知识。通过举例的方式,在一个实施例中,知识库210被实现为表征针对一个或多个API方法的用途的API用途库。在下面的描述中,将参考API方法讨论一些实施例。然而,要理解,这仅仅是出于说明的目的而不暗示对本文中描述的主题的任何限制。本文中描述的主题的实施例可应用于能够在编程中被调用或唤起的各种类型的方法。

知识库210包含多个代码片断2201、2202、...220n(统称为“代码片断220”)。代码片断220中的每个代码片断包含一个或多个语句并且表示某种方法用途。可以以任何适当的方式来获得代码片断。例如,在一个实施例中,一个或多个代码片断220可以直接从一个或多个代码库和/或互联网收集。备选地或附加地,代码片断220可以从现有代码段生成。在一个实施例中,一个或多个代码片断220由包括片断提取、分组和选择的过程生成。将在稍后讨论代码片断220及其生成的示例。

如图2所示,在一个实施例中,代码片断2201、2202、...220n具有相应的元数据2301、2302、...230n(统称为“元数据230”)。元数据230描述可能在代码推荐中有用的相关联的代码片断220的任何信息。通过举例的方式,在一个实施例中,元数据230指示相关联的代码片断220中的一个或多个变化点。如本文中所使用的,术语“变化点”是指代码片断中的有可能特定于编程任务的并且需要由用户手动地和/或通过利用任何适当的自动编码技术编辑或指定的点。将在稍后讨论这方面的示例实施例。任何其他相关信息可以被包括在元数据230中。例如,在一个实施例中,元数据230可以包括关于从其获得相关联的代码片断220的来源的信息。

要理解,代码片断220及其相关联的元数据230不一定如图2所示地一起存储。相反,在一个实施例中,元数据230的全部或部分可以被存储在例如表或任何其他适当的数据结构中。表中的每个条目可以例如通过代码片断220中的标识符与代码片断220相关联。

系统200还包括开发环境240。开发环境240可以被用于编辑、存储、调试、构建和/或运行计算机程序代码。在一个实施例中,开发环境240是集成开发环境(IDE)。具体地,开发环境240包括用户可以在其中输入和/或编辑代码的代码编辑器250。在一个实施例中,开发环境240还可以包括推荐区域260。在操作时,例如,当用户正在代码编辑器250中键入代码时,可以获得编程上下文。编程上下文以及可能的其他相关信息可以被用于查询知识库210。作为响应,知识库210将检索并返回预计与编程上下文相关的一个或多个代码片断220。经历诸如排名的一些处理,由知识库210提供的代码片断220的一些或全部代码片断可以作为代码推荐被呈现在推荐区域260中。通过浏览、选择和/或编辑呈现于推荐区域260中的推荐,用户能够利用所推荐的代码片断220来完成他/她的代码。

知识库210和开发环境240可以经由双向连接270与彼此进行通信。在一个实施例中,知识库210和开发环境240被共同定位在单个物理机器中。在这一点上,连接270可以例如为应用间通信连接或过程间通信连接。在另一实施例中,知识库210和开发环境240被分布在单独的机器中。在这样的实施例中,连接270可以例如为计算机网络,诸如局域网(“LAN”)、广域网(“WAN”)或互联网、通信网络、近场通信连接、或其任何组合。要理解,开发环境240可以利用本地知识库和远程知识库两者。在这一点上,连接270实现本地通信和远程通信。

要理解,尽管代码编辑器250和推荐区域260在图2中被示出为单独的区域,但是这仅仅是出于说明的目的而不暗示对本文中描述的主题的任何限制。备选地,代码和推荐可以被显示在单个区域或窗口、弹出窗口或框内、或下拉菜单中。通过举例的方式,在一个实施例中,推荐区域260可以被实现为被显示在代码编辑器250中的光标的位置附近的浮动窗口。

现在将描述知识库210的构建。图3示出了用于构建知识库210的方法300的流程图。要理解,方法300可以在任何适当的时机被执行。例如,在一个实施例中,知识库210可以提前被构建。附加地或备选地,方法300可以在知识库210已经被部署为过程查询之后被执行,使得知识库210可以被动态地更新。此外,仅仅出于说明的目的,将参考API方法来讨论方法300。

一般地,在方法300中,知识库通过对多个代码片断进行分组来构建。为此,方法300在步骤305处进入,其中要被分组的代码片断可以被过滤以移除噪声,由此改进分组的准确性。根据用于分组的准则,过滤可以以各种不同的方式来完成。下面将描述过滤的示例。要理解,代码片断的过滤不一定被执行。在一个实施例中,代码片断可以被直接分组而不被过滤。

在步骤310处,将多个代码片断进行分组以获得一个或多个组。要被分组的代码片断中的每个代码片断包含与一个或多个API方法的调用相关的语句。要被分组的代码片断可以以任何适当的方式来获得。例如,在一个实施例中,可以从现有代码片断中提取代码片断中的一个或多个代码片断。将在稍后讨论这方面的示例实施例。备选地,要被分组的代码片断可以从代码库或从任何适当的来源中被收集。

在步骤310处,根据代码片断的方法用途来执行分组。也即,表示相同的或相似的方法用途的代码片断将被分组在一起。以这种方式,每个得到的组包含与相同的或相似的方法用途相关联的代码片断。

如本文中所使用的,方法用途是指反映该方法如何在给定上下文中操作的方法的利用的模式。可以以任何适当的方式来表示方法用途。例如,方法用途可以由参数或变量的集合、方法调用的集合、方法调用的顺序、数据依赖性、控制流和/或任何其他适当的方面来表征。因此,这些方面中的一个或多个方面可以被用于对代码片断进行分组。

具体地,在一个实施例中,代码片断可以仅仅根据包含于代码片断中的方法调用的集合而被分组。这是可行的,因为代码片断中的方法调用的集合能够在大多数情况下表征代码片断的语义。实验表明针对具有方法调用的相同的集合的两个代码片断,调用顺序、数据依赖性和/或控制流的变化可能在语义上不显著。在这样的实施例中,包含方法调用的相同的或相似的集合的代码片断被分配到单个组中。该方法是相当高效的并且无需调整参数,这将在实践中在效率方面是有益的。

如以上所描述的,在一个实施例中,在步骤310处对代码片断的分组之前,有可能在步骤305处对代码片断进行过滤以移除噪声。通过举例的方式,当在步骤305处基于方法调用的集合来对代码片断进行分组时,可以从代码片断移除一个或多个零散方法调用。如本文中所使用的,术语“零散方法调用”是指仅仅提供辅助功能并且与代码片断的语义较不相关的方法调用。通过举例的方式,诸如ToString函数或日志记录函数的API方法的调用可以被认为是零散方法调用。在一个实施例中,一个或多个零散方法调用可以提前被定义并被存储。具体地,零散方法调用可以针对个体代码库被定制。在操作时,要被分组的代码片断可以针对预定义零散方法调用进行检查以移除代码片断中的零散方法调用(如果存在)。通过以这种方式过滤噪声,能够更准确地对代码片断进行分组。

方法300之后进行到步骤320,其中针对从步骤310得到的组中的每个组选择一个或多个代表性代码片断。代表性代码片断可以被存储到知识库210中作为用于后续查询的代码片断220。在一个实施例中,针对组的代表性代码片断例如可以在随机的基础上直接从该组选择。备选地或附加地,从受信的或经认证的来源获得的代码片断可以被选择为代表性代码片断。

为了进一步改进代表性片断选择的准确性,在一个实施例中,针对组的代表性代码片断可以通过基于代码片断的形状来对该组中的代码片断进一步分组来选择。如本文中所使用的,术语代码片断的“形状”是指通过对代码片断中的标识符进行标记而获得的语句的序列。更具体地,代码片断的形状可以被认为是转移的标记序列,其中诸如类型名和变量名的标识符由相同的标记替换,同时保持关键字和方法调用不被标记。如以上所描述的,在一个实施例中,基于被包括在代码片断中的方法调用的集合来对代码片断进行分组,而不考虑方法调用的顺序。通过根据代码片断的形状来选择代表性代码片断,方法调用的顺序被考虑。因此,所选择的代表性代码片断能够更准确地反映方法用途。

在这样的实施例中,针对从步骤310得到的任何组,一个或多个子组可以通过基于代码片断的形状对组进一步划分来获得。接下来,可以至少部分地基于子组的大小来选择子组。如本文中所使用的,术语子组的“大小”是指包含于该子组中的代码片断的数量,或者包含于该子组中的代码片断相较于子组整体或其他子组的百分比或比率。在一个实施例中,具有最大大小的子组被选择。

附加地或备选地,也可以考虑关于子组中的代码片断的编码样式的用户设置或偏好。例如,在一个实施例中,如果存在具有最大大小的两个或更多个子组,则这些子组中的一个子组可以根据用户偏好来选择。在这样的实施例中,用户可以提前指示关于代码样式的他/她的偏好。通过举例的方式,用户可以将对try-catch-finally语句的使用定义为良好编码样式。根据这样的偏好,包含使用try-catch-finally语句的代码片断的子组可以被选择。在子组选择中可以考虑代码片断的作者、来源、生成时间和/或任何其他相关信息。

之后,所确定的子组内的代码片断被选择为代表性代码片断。在一个实施例中,代表性代码片断可以从所确定的子组中随机地选择。可选地,可以考虑所选择的子组中的个体代码片断的编码样式、来源、作者、生成时间和/或任何其他相关信息。

仍然参考图3,在步骤330处,针对在步骤320处被选择的每个代表性代码片断生成元数据。元数据可以指示关于代表性代码片断的任何适当的信息或知识。具体地,在一个实施例中,元数据指示代表性代码片断中的一个或多个变化点。如以上所描述的,变化点是代码片断中的有可能根据特定编程任务变化的并且因此可能需要由用户手动地和/或通过自动编码技术编辑或指定的点。通过经由元数据指示这样的变化点,当相关联的代码片断被推荐给用户时,可以突出变化点。因此,用户能够容易地通过根据特定编程任务和上下文编辑或设置变化点的特定值来重用代码片断。这将改进编码效率和用户体验。下面将详细描述示例实施例。

在步骤330处,可以以各种方式来确定代表性代码中的变化点。如以上所描述的,在一个实施例中,在步骤310处获得的组中的每个组可以基于用于选择代表性代码片断的片断形状而被进一步划分成子组。结果,一个子组内的代码片断具有相同的形状。在这样的实施例中,代表性代码片断中的变化点可以通过标识在相同子组中的代表性代码片断与一个或多个另外的代码片断之间的差异来确定。例如,在相同子组中的所选择的代表性代码片断与其他代码片断之间的不同的标识符和/或文字可以被定义为变化点。图4示出了标识变化点的示例。

在图4中示出的示例中,代码片断400是针对组的代表性代码片断,并且代码片断410来自与代表性代码片断400相同的子组。能够看出,代码片断400和410具有相同的形状并且仅仅在第7行处的标识符处与彼此不同。因此,在第7行处的所标识的点420和430可以被确定为变化点并且被存储在元数据中。

要理解,元数据可以包括任何其他相关信息。例如,在一个实施例中,元数据包括从其中获得所选择的代表性代码片断的来源的信息(例如,标识符和/或完整路径名)。在代码推荐中,这样的知识可以帮助用户在他/她知道该来源中的代码的质量或者能够查看代码片断的用途的较大上下文时做出关于是否重用代码片断的更好的决定。

在步骤310到330中,针对表示API方法用途的每个组,获得代表性代码片断和相关联的元数据。之后,在步骤340处,代表性代码片断与它们各自的元数据相关联地被存储到知识库210中。更具体地,每个代表性代码片断被存储为知识库210中的代码片断220,并且相关联的元数据被存储为元数据230。

将认识到,根据如本文中描述的主题的实施例,关于被包括在相应的元数据230中的代码片断220的知识可以在代码推荐中被用于提供有用的提示或向导,使得用户能够容易地确定如何修改所推荐的代码片断以完成他/她的当前编程任务。附加地,本文中描述的主题的实施例可应用于大规模代码库并且是高度可扩展的。例如,有可能并行地生成并收集要被分组的代码片断。备选地或附加地,在一个实施例中,分组可以通过例如哈希技术来加速。因此,可以高效地构建大规模API用途库。

如以上所讨论的,要由方法300处理的用于构建知识库210的代码片断可以以各种方式来获得。例如,在一个实施例中,可以从代码片断中提取一个或多个代码片断。例如,从中提取片断的代码段可以从诸如现有代码库和/或互联网的各种来源获得。在给定目标API方法的情况下,可以以许多不同的方式提取代码片断。例如,在其中目标方法被调用的函数主体可以被提取为代码片断。作为另一示例,有可能提取包含目标方法的预定义数量的行的代码碎片作为代码片断。具体地,为了有效地且高效地提取代码片断,可以在一个实施例中使用代码切分技术。

图5图示了用于基于代码切分从代码段中提取代码片断的方法500的流程图。更具体地,在方法500中,基于与给定方法调用相关联的语句的数据依赖性来从代码段中提取代码片断。也即,在该实施例中,通过以调用为中心的代码切分来提取代码片断。

如所示出的,方法500在步骤510处进入,其中对代码段中的重用的变量进行重命名。如所示出的,在实践中,为方便起见,变量可能在方法内被重用以执行不同的任务。例如,在单个代码段内,许多软件工程师有可能重复地使用“i”或“j”来表示不同代码碎片(诸如方法主体或控制循环)中的变量。在这种情况下,如果两个独立的代码碎片包含相同的变量名,则它们可能被不正确地标识为具有数据依赖性并且因此当基于数据依赖性提取代码片断时不能够被分离。结果,变量的重用将降低代码切分过程的准确性。通过在代码切分之前在步骤510处对代码段内的这样的重用的变量进行重命名,该问题能够得到解决。要理解,作为预处理步骤,重用的变量的重命名是可选的并且在一些实施例中可以被省略。

接下来,代码段中的方法调用可以被选择为目标,并且语句与目标方法调用的数据依赖性可以被确定。具体地,在步骤520处,标识与所选择的目标方法调用相关的一个或多个变量。在一个实施例中,可以标识与目标方法调用直接相关的变量。这样的变量包括但不限于由目标方法调用定义、使用或返回的变量。之后,在步骤530处可以确定定义、使用和/或返回所标识的变量的一个或多个语句。

在一个实施例中,方法500之后进行到步骤540以标识与针对目标方法调用的控制流相关联的一个或多个语句。例如,如果目标调用被定位在代码分支或循环中,则在步骤540处可以标识控制流语句“IF...THEN...ELSE”或“WHILE”。利用控制流语句,所提取的代码片断能够更准确地反映方法用途。在一个实施例中,在步骤540处标识的控制流语句可以被直接包括在代码片断中。在备选实施例中,所标识的控制流可以以任何适当的方式而被指示在元数据中。然而,要理解,可以在不标识控制流的情况下提取代码片断。也即,步骤540可以被省略,并且代码片断提取也仅仅根据数据依赖性来工作。

在一个实施例中,在步骤550处,确定是否要继续标识与目标方法调用的间接数据依赖性。如果是(分支“是”),则方法500重复步骤520、530以及可能的540。将认识到,在第一轮处理中,在步骤520处,标识与目标方法调用直接相关的变量。因此,在步骤530处确定的任何语句具有与目标方法调用的直接数据依赖性。在后续轮中,在步骤520处标识的变量和在步骤530处确定的语句与在先前轮中确定的语句相关并且因此具有与目标方法调用的间接数据依赖性。

通过重复步骤520到540一次或多次,可以获得针对目标方法调用的一个用途或一个更高层级的用途。这样,所提取的用途将是更完整且准确的。然而,要理解,不一定要求更高层级的用途。在一个实施例中,步骤520、530以及可能的540可以仅仅被执行一次以提取第一层级的用途。

如果在步骤550处确定没有更多间接数据依赖性要被提取(分支“否”),则方法500进行到步骤560以提取代码片断。具体地,在530处确定的语句在步骤560处被提取作为代码片断的一部分。另外,在其中在步骤540处确定控制流语句的那些实施例中,还在步骤560处将控制流语句提取到代码片断中。

图6示出了利用方法500提取代码片断的示例。在代码段600中,假定在第6行对API方法StreamReader.ReadLine的调用是目标方法调用。该API方法具有通过调用在第2行的方法File.OpenText被构建并且在第11行被关闭的输入参数sr。目标API方法调用具有输出参数行,其在第5行被初始化并且在第8行被处理。另外,能够看出,在示出的示例中API方法StreamReader.ReadLine在从第6行到第10行的WHILE循环中被调用。因此,在第6行、第7行和第10行处的控制流语句也是API用途的部分。之后,具有与在第6行的方法调用StreamReader.ReadLine的数据依赖性的所有语句及其相关的控制流语句从代码段600中被提取以形成在图6中带下划线的代码片断。

将认识到,在图6中示出的示例中,仅仅提取并利用第一层级的用途。在另一实施例中,如以上所讨论的,有可能提取方法用途的一个或多个另外的层级。例如,方法调用File.OpenText可以之后被分析以确定它的直接依赖性,其是针对StreamReader.ReadLine的间接依赖性。因此,可以提取第二层级的用途。

参考图5,在一个实施例中,所提取的代码片断可以在可选的步骤570处被进一步处理以移除代码克隆。如本文中所使用的,术语“代码克隆”是指在归一化和标记化之后在语法上相同的两个或更多个代码碎片。图7示出了使用方法new SqlCommand的调用作为目标方法调用提取的代码片断700的示例。可以看出,在第4行到第5行处的代码碎片720以及在第6行到第7行处的代码碎片730是在第2行到第3行处的代码碎片710的克隆。这样的克隆代码不提供在目标方法new SqlCommand的用途方面的额外的知识并且因此可以在步骤570处被移除或被过滤。

为此,在一个实施例中,高效的技术被用于检测并移除克隆代码。在给定所提取的代码片断的情况下,包含于片断中的代码首先被归一化和标记化。也即,利用相同的标记来替换所有变量名和文字。例如,参考图7,在碎片710和720中,变量和文字“@StsCode”、“SqlDbType.Int”、“0”、“resultCode”、“@ErrMsg”、“SqlDbType.VarChar”、“1”和“errorText”可以全部利用相同的标记(例如“X”)来替换。之后,可以针对任何重复的子字符串检查代码片断。在本文中可以应用任何子字符串检查算法,无论是当前已知的还是未来开发的。在一个实施例中,针对在代码片断中检测到的克隆的代码碎片,这些代码碎片中的一个代码碎片被保持并且其他代码碎片被移除。

关于方法500,通过以调用为中心的方式对代码段进行切分来提取代码片断。通过对多个代码段应用代码片断提取过程500,能够获得针对代码库中的多个API方法的用途,而不忽视具有较不频繁的用途的API方法。实际上,通过选择不同的目标方法调用,有可能从单个代码段中提取多于一个代码片断。以这种方式,所提取的代码片断可以覆盖API方法调用的重要部分以及它们在代码库中的用途。此外,在片断提取中,代码库中的每个方法主体中的代码可以被独立地处理并且能够被并行运行。另外,借助于预处理(在步骤510处的重用的变量重命名)和后处理(在步骤570处的代码克隆移除)以及控制流语句的并入,所提取的代码片断可以是更加准确且完整的。如以上参考图3所讨论的,之后,由方法500提取的代码片断可以由方法300分组并且因此被用于构建知识库210。

现在将讨论基于代码知识库的代码推荐。参考图8,图8示出了用于代码推荐的方法800的流程图。

方法800在步骤810处进入,其中确定针对考虑中的代码段的编程上下文。例如,代码段可以是在图2中示出的开发环境240中在代码编辑器250中输入或编辑的代码段。在一个实施例中,以调用为中心的技术被利用使得至少部分地基于与代码中的方法调用的数据依赖性来获得编程上下文。例如,考虑接近用户已经经常输入的上一字符的上一方法调用语句最好地反映用户的意图的事实,在一个实施例中,有可能利用被输入到代码编辑器250中的上一方法(被标示为“m”)的调用来自动提取编程上下文。

之后,确定在代码段中被调用的并且具有与方法调用的数据依赖性的方法的序列q=<I0,I1,…,In-1>。在序列q中,Ii(i=0,…,n-1)是从开发中的函数的主体开始的第i个被调用的方法。调用Ii的语句具有与调用m的语句的数据依赖性。每个Ii可以以与如以上讨论的方法500中的步骤520和530类似的方式来标识。具体地,与如参考图5讨论的以调用为中心的代码切分技术类似,序列q中的方法Ii可以具有与方法调用m的直接数据依赖性或间接数据依赖性。因此,被调用的方法的序列q反映用户的意图并且可以被用作编程上下文。

方法800进行到步骤820,其中至少部分地基于在步骤810处确定的编程上下文从知识库210中检索一个或多个候选代码片断。在一个实施例中,在给定例如形式为被调用的方法序列q的编程上下文的情况下,大致与q相关的候选代码片断的集合(被标示为C)可以在知识库820处被确定。例如,集合C可以以使得C中的每个候选代码片断调用编程上下文q中的至少一个方法的方式来确定。

接下来,在步骤820处,例如在推荐区域260中将在步骤820处检索的候选代码片断中的至少一些候选代码片断作为代码推荐呈现给用户。在一个实施例中,在步骤820处检索的所有候选代码片断可以被推荐给用户。为了进一步改进推荐的准确性和用户友好性,在一个实施例中,检索到的候选代码片断可以在步骤830处根据预定义准则或规则的集合来过滤或排名。一个或多个排名前列的代码片断之后被推荐给用户。通过举例的方式,在一个实施例中,排名可以在两个阶段中完成。

在这样的实施例中,用于对候选代码片断进行排名的预定义准则可以包括但不限于以下中的一项或多项:候选代码片断与编程上下文的相关性;候选代码片断的用途的流行度;候选代码片断的简洁性;以及代码推荐的多样性或简明性。要理解,这些准则仅仅是出于说明的目的而不暗示对本文中描述的主题的范围的限制。任何备选的或附加的适当的因素、准则或规则可以被用于在步骤830处对候选代码片断进行过滤或排名。例如,可以考虑与候选代码片断相关的来源、作者和/或用户偏好。相关性指示代码片断与编程上下文相匹配的程度。用途的流行度指示代码片断先前(由当前用户或由数据集中的用户的团体之一或两者)被选择并被使用多少次或者多么频繁。简洁性涉及代码片断的可读性或清楚性的程度。多样性或简明性意指在所推荐的代码片断中,期望尽可能多地覆盖预计的方法用途。也即,在不同的代码片断表示不同的方法用途的情况下推荐的简明列表是期望的。

这样的准则可以被单独地或以任何组合来使用。例如,在一个实施例中,在步骤820处检索的候选代码片断可以根据至少一个准则来被首先排名和/或过滤(例如,相关性、用途的流行度和简洁性中的至少一个成员或组合)并且之后根据第二准则来被重新排名和/或过滤(例如,多样性或简洁性中的至少一项或两者)。

更具体地,在一个实施例中,在步骤830处的第一阶段排名根据相关性和用途的流行度来执行。针对集合C中的每个候选代码片断s,如下定义的分数(被标示为“score1”)被计算为:

score1=α×Relevance(q,s)+(1-α)×Support(s) (1)

其中,α表示范围从0到1的参数;Relevance(q,s)表示在s与在步骤810处确定的编程上下文q之间的相关性;并且Support(s)表示针对代码片断s的用途的流行度。

在一个实施例中,Relevance(q,s)可以被定义如下:

其中,MatchScore(q,s)表示s和q的匹配程度,并且Penalty(q,s)表示针对MatchScore(q,s)的惩罚函数。

如以上所讨论的,可以假设接近用户已经输入的上一字符的上一方法调用语句经常最好地反映用户的意图。因此,MatchS(q,s)可以以使得较大的权重被给予相对更接近用户已经输入的上一字符的匹配的方法的方式来定义。通过举例的方式,MatchScore(q,s)可以被定义如下:

其中isMatchi表示当编程上下文q中的第i个被调用的方法出现在s中时被设置为1并且否则被设置为0的值;γ表示其值可以被提前定义的参数;并且ratio表示匹配的方法的数量除以s中的方法的数量。如果ratio等于1,则意味着代码片断s不提供任何新的方法并且因此不太有意义被推荐。在这种情况下,MatchScore将被设置为0。

在一个实施例中,公式(2)中的Penalty(q,s)可以是在s与q之间的相关性的下降函数,其在一个示例中可以被定义如下:

其中μ表示其值可以被提前定义的参数。将认识到,当代码片断s与编程上下文q更相关时,ratio的值将增大并且因此Pe(q,s)的值将减小。如以上所描述的,在一个实施例中,如果代码片断包含编程上下文q中的至少一个方法,则该代码片断可以被选择为候选。结果,一个或多个候选片断代码s可能包括与当前编程上下文q不匹配或不相关的方法的调用。通过使用Pen(q,s),当对候选代码片断进行排名时可以考虑包括在候选代码片断中的这些不匹配或不相关的方法的影响。

在一个实施例中,公式(1)中的表示代码片断s的流行度的Support(s)可以被定义为知识库210中具有与代码片断s相同的方法调用的集合的代码片断的数量的归一化的值。通过举例的方式,在一个实施例中,Support(s)可以被定义如下:

其中Frequency(s)表示知识库210中具有与s相同的方法调用的集合的代码片断的数量,其可以例如当构建知识库210时被确定;并且Max_Frequency表示针对知识库中的所有代码片断s的Frequency(s)的最大值。将认识到,Support(s)是Fre(s)的归一化的值。

要理解,以上在公式(1)到(5)中描述的度量仅仅是出于说明的目的而不暗示对本文中描述的主题的任何限制。作为示例,Rel(q,s)和Support(s)可以被独立地使用,或者度量的任何组合可以是合适的。作为另一示例,score1可以通过考虑简洁性来定义。简洁性可以例如由代码片断的长度来衡量。

通过在第一阶段中根据相关性、用途的流行度和/或简洁性来对候选代码片断进行排名,可以针对第二阶段排名选择具有最高分数的头k*m个候选代码片断,其中k表示推荐列表的期望的大小,并且m是常数。通过举例的方式,在一个实施例中,m的值可以被设置为2.5。接下来,从第一阶段排名获得的头k*m个片断候选(被标示为C’)可以在第二阶段中被重新排名,使得仅仅头k个候选代码片断被输出为推荐。根据多样性和/或简明性来执行重新排名以确保排名头k个的代码片断尽可能多地与彼此不相似。

在用于包括多样性排名的一个实施例中,C’中的具有如公式(1)中定义的score1的最高值的代码片断被首先保存。C’中的每个剩余的片断s使用衡量在两个代码片断之间的差异性的程度的分数(被标示为score2)来重新排名。在一个实施例中,score2可以被定义为score1和在代码片断s与已经被选入集合C中的代码片断之间的最小化差异性的加权平均。通过举例的方式,在一个实施例中,score2可以被表示如下:

score2=β×score1+(1-β)×Min(Disimilarity(s,s′)) (6)

其中β表示用于调节权重的、范围从0到1的参数;Disimilarity(s,s')表示在s与s'之间的差异性;并且s'表已经被选入集合C’中的代码片断;并且Min()表示返回最小值的函数。因此,针对代码片断s的score2将随着在s与已经被推荐的片断之间的相似性减小而增大。

具有score2的最高值的代码片断被排名为C’中的第二位置。接下来,对剩余的片断进行重新排名并且具有score2的最高值的片断被选择为第三推荐。通过迭代地重复该过程,要被推荐的头k个代码片断被确定并按顺序被呈现给用户。在一个实施例中,可以过滤掉或移除具有较低排名的候选代码片断。备选地,这些候选代码片断可以被反转,将在稍后对其进行讨论。

要理解,在一些实施例中步骤830可以被省略。例如,在一个实施例中,有可能在不进行过滤或排名的情况下将在步骤820处检索到的所有候选代码片断推荐给用户。

仍然参考图8,在步骤840处,例如在推荐区域260中将一个或多个候选代码片断作为代码推荐呈现给用户。通过举例的方式,所推荐的代码片断可以例如根据在步骤830处的排名而被显示为推荐区域260中的列表。可以以任何适当的方式来呈现所推荐的代码片断。作为示例,在一个实施例中,每个代码片断可以由例如包括代码片断的头几行的概述来表示。作为另一示例,缩略图可以被用于呈现所推荐的代码片断。在由用户选择时,所选择的代码片断可以被展开。

在一个实施例中,在阈值时间段后或应来自用户的请求,所推荐的代码片断的所呈现的列表可以被展开以包括附加的代码片断。例如,在其中检索到的代码片断被过滤或被排名的那些实施例中,所展开的列表可以显示被初始地过滤掉或被排名为比代码片断的初始呈现的列表低的那些代码片断。

通过在步骤840处将一个或多个候选代码片断推荐给用户,用户可以检查目标API方法是否以正确的和/或有效的方式来利用。此外,如以上所讨论的,由用户输入的最后的方法可以被选择为目标方法。同时,所推荐的代码片断中的至少一些所推荐的代码片断可以包含在目标方法之后的一个或多个语句并且因此能够被用作对用户正在试图做什么的预测。因此,用户能够选择并重用与他/她的任务相匹配或期望用于代码完成的一个或多个所推荐的代码片断。

要理解,可以以不同的方式来触发代码推荐方法800。在一个实施例中,代码推荐的检索和/或显示可以被自动启用。例如,如果在用户正在将字符键入到代码编辑器250中时检测到某些关键字或字符,则方法800可以被激活以检索并推荐相关代码片断。备选地或附加地,代码推荐可以由用户禁用或启用。例如,在一个实施例中,使得用户能够以任何适当的交互方式激活和去激活所推荐的代码片断的检索和/或显示。

具体地,如以上所描述的,存储在知识库210中的片断代码220可以具有相关联的元数据230。因此,在一个实施例中,在步骤820处,元数据可以连同相关联的代码片断一起被检索。当代码片断被推荐给用户时,可以基于元数据来显示一些相关或辅助信息。例如,针对一个或多个所呈现的代码片断,可以显示源文件和/或如由相关联的元数据指示的任何其他相关者。备选地或附加地,在一个实施例中,可以突出一个或多个所推荐的代码片断中的变化点。如以上所描述的,变化点能够由用户手动地设置或编辑,或者通过自动编码技术修改。通过突出变化点,诸如图4中示出的点420和430,用户能够有效地且高效地确定如何调整所推荐的代码片断以完成当前编程任务。以这种方式,将改进编码效率和用户体验。

图9示出了用于构建知识库210的系统900的框图。如所示出的,系统900可以包括:片断分组单元910,片断分组单元910被配置为基于被包括在代码片断中的方法调用来获得代码片断的一个或多个组;以及片断选择单元920,片断选择单元920被配置为分别选择针对组的代表性代码片断。系统900还包括元数据生成单元930,数据生成单元930被配置为针对任何给定的代表性代码片断生成至少指示该代表性代码片断中的变化点的元数据。系统900还包括存储管理单元940,存储管理单元940被配置为将代表性代码片断与元数据相关联地存储在知识库中。

在一个实施例中,一个或多个预定义零散方法调用可以在分组之前从代码片断中被移除。在一个实施例中,片断选择单元920被配置为基于组内的代码片断的形状来将组划分成子组,被配置为至少部分地基于子组的大小来选择子组中的一个子组,并且被配置为从所选择的子组中选择代表性代码片断。在这样的实施例中,元数据生成单元930被配置为通过确定在所确定的子组中的代表性代码片断与另一代码片断之间的差异并且基于所确定的差异标识变化点来生成元数据。

在一个实施例中,系统900可以包括片断提取单元950,片断提取单元950被配置为基于代码段中的方法调用从该代码段中提取代码片断。例如,在一个实施例中,片断提取单元950被配置为执行如以上所讨论的方法500以从代码库中的代码段中提取一个或多个代码片断。

图10图示了根据本文中描述的主题的实施例的用于代码推荐的系统1000的框图。如所示出的,系统1000包括:上下文确定单元1010,上下文确定单元1010被配置为至少部分地基于与代码段中的方法调用的数据依赖性来获得针对该代码段的编程上下文;片断检索单元1020,片断检索单元1020被配置为至少部分地基于所获得的编程上下文来从知识库中检索候选代码片断;以及推荐单元1030,推荐单元1030被配置为将检索到的候选代码片断的至少一些检索到的候选代码片断呈现为代码推荐。

在一个实施例中,上下文确定单元1010被配置为通过确定在代码段中调用的具有与方法调用的所述数据依赖性的方法的序列来获得编程上下文。

在一个实施例中,系统1000还可以包括排名单元1025,排名单元1025被配置为根据预定义准则来对检索到的候选代码片断进行排名。因此,推荐单元1030可以被配置为呈现所排名的候选代码片断。例如,在一个实施例中,预定义准则包括以下中的至少一项:候选代码片断与编程上下文的相关性;候选代码片断的用途的流行度;候选代码片断的简洁性;以及代码推荐的多样性。在这样的实施例中,排名单元1025可以被配置为根据相关性、用途的流行度和简洁性中的至少一项来对检索到的候选代码片断进行排名,并且被配置为根据多样性来对所排名的候选代码片断进行重新排名,使得预定义数量的经重新排名的候选代码片断彼此不相似。

备选地或附加地,在一个实施例中,推荐单元1030被配置为在所呈现的代码片断中的至少一个所呈现的代码片断中突出变化点,该变化点由与该至少一个所呈现的代码片断相关联的元数据指示。

要理解,系统900和系统100可以被远程地定位在单独的机器中或者被共同定位在单个物理机器中。也即,知识库的构建和使用可以由不同实体或由单个实体实现。此外,要理解,方法300和方法500可以由单个实体或由不同实体执行。也即,代码片断提取和知识库构建的功能可以被整体地或分离地实现。

除了或代替被存储在计算机可读介质上的计算机可执行指令,本文中描述的主题的部分或全部能够至少部分地由一个或多个硬件逻辑组件执行。例如并且在不限制的情况下,能够被使用的说明性类型的硬件逻辑组件包括现场可编程门阵列(FPGA)、专用集成电路(ASIC)、专用标准产品(ASSP)、片上系统(SOC)、复杂可编程逻辑器件(CPLD)等。

尽管已经以特定于结构特征和/或方法动作的语言描述了本主题,但是要理解在所附权利要求中限定的主题不必限于以上描述的特定特征或动作。更确切地说,以上描述的特定特征和动作被公开为实施权利要求的示例形式。

当前第1页1 2 3 
网友询问留言 已有0条留言
  • 还没有人留言评论。精彩留言会获得点赞!
1