Facebook开源Aroma: 通过机器学习向程序员推荐代码模板


为了简化和加快编写会对许多系统产生影响的代码的过程,工程师经常需要一种方法来查找其他人如何编写代码来处理类似的任务。我们创建了Aroma,一种代码到代码的搜索和推荐工具,它使用机器学习(ML)使得从大型代码库获得洞察力的过程变得更加容易。
在Aroma之前,现有的工具都没有完全解决这个问题。文档工具并不总是可用且可能过时,代码搜索工具通常会返回无数匹配结果,并且很难立即找到惯用的使用模式。通过Aroma,工程师可以轻松找到常见的编码模式,而无需手动浏览数十个代码段,从而节省了日常开发工作流程的时间和精力。

让我们看看Android工程师想要了解其他人如何编写类似代码的情况。假设工程师编写以下内容来解码Android手机上的位图:

Bitmap bitmap = BitmapFactory.decodeStream(input);
bitmap = BitmapFactory.decodeStream(input);

    
这是可行的,但工程师想知道其他人如何在相关项目中实现此功能,尤其是设置了哪些常用选项,或处理了哪些常见错误,以避免应用程序在生产中崩溃。

Aroma使工程师能够使用代码片段本身进行搜索查询。结果作为代码建议返回。每个代码建议都是从存储库中找到的类似代码片段的集群中创建的,并表示常见的使用模式。以下是Aroma为此示例返回的第一条建议:

代码示例1

final BitmapFactory.Options options = new BitmapFactory.Options();
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = 2;.inSampleSize = 2;
// ...// ...
Bitmap bmp = BitmapFactory.decodeStream(is, null, options);
Bitmap bmp = BitmapFactory.decodeStream(is, null, options);

这段代码建议是从存储库中找到的五个类似方法的集合中合成的。此处仅显示了方法集群中的公共代码,并在间隙(省略号...部分)中删除了各个方法的具体细节。
这段代码建议试图说明什么?嗯,它说在五种不同的情况下,工程师在解码位图时设置了额外的选项。设置样本大小有助于减少解码大位图时的内存消耗,实际上,Stack Overflow上的一个热门帖子暗示了相同的模式。Aroma通过发现包含此模式的代码片段集自动创建此建议。

让我们看看另一个建议。
代码示例2

try { {
  InputStream is = am.open(fileName);InputStream is = am.open(fileName);
  image = BitmapFactory.decodeStream(is);= BitmapFactory.decodeStream(is);
  is.close();is.close();
} catch (IOException e) {} catch (IOException e) {
  // ...// ...
}}

此代码段是从另外四种方法聚类而来的。它显示了InputStream在解码位图中的惯用用法。此外,此建议演示了在打开InputStream时捕获潜在IOException的良好做法。如果此异常在运行时发生且未捕获,则应用程序将立即崩溃。负责任的工程​​师应使用此建议扩展代码并正确处理此异常。

与传统的代码搜索工具相比,Aroma的代码推荐功能有以下几个优点:

  • Aroma在语法树上执行搜索。Aroma不是寻找字符串级别或令牌级别的匹配,而是可以找到语法上与查询代码类似的实例,并通过修剪不相关的语法结构来突出显示匹配的代码。
  • Aroma自动将类似的搜索结果聚集在一起以生成代码建议。这些建议代表惯用的编码模式,比非聚集搜索匹配更容易使用。
  • Aroma足够快,可以实时使用。在实践中,即使对于非常大的代码库,它也会在几秒钟内创建建议,并且不需要提前进行模式挖掘。
  • Aroma的核心算法与语言无关。我们在Hack,JavaScript,Python和Java的内部代码库中部署了Aroma。