Error-Prone Refaster templates

闾丘鸣
2023-12-01

重组模板

除了通过内置的Error Prone补丁修补代码,我们还开发了一种使用前后模板重构代码的机制(我们称之为“重组模板”)。
编写这些模板后,将它们编译成.refaster文件,然后根据这些规则使用Error Prone编译器重构代码。

在“重构工具”研讨会上,路易斯·沃斯曼(Louis Wasserman)提出的一篇研究论文更详细地描述了重构。

构建重组模板

解释如何编写重组规则最好方法莫过于通过示例:

import com.google.errorprone.refaster.annotation.AfterTemplate;
import com.google.errorprone.refaster.annotation.AlsoNegation;
import com.google.errorprone.refaster.annotation.BeforeTemplate;

public class StringIsEmpty {
  @BeforeTemplate
  boolean equalsEmptyString(String string) {
    return string.equals("");
  }

  @BeforeTemplate
  boolean lengthEquals0(String string) {
    return string.length() == 0;
  }

  @AfterTemplate
  @AlsoNegation
  boolean optimizedMethod(String string) {
    return string.isEmpty();
  }
}

重载模板是具有多个方法的任何类,具有相同的返回类型和具有相同名称的参数列表。其中一个方法应该注释@AfterTemplate,并且每个其他方法都应该用@BeforeTemplate注释。
使用此模板,任何代码调用String#equals传递空字符串文字,或者调用String#length并将其与0进行比较都将被调用String#isEmpty所代替。值得注意的是,无论String表达式如何生成,Refaster都将进行替换:

boolean b = someChained().methodCall().returningAString().length() == 0;

会变成

boolean b = someChained().methodCall().returningAString().isEmpty();
if (this.someStringField.equals(""))

会变成

if (this.someStringField.isEmpty())

refaster.annotations包中还有其他注释,可以让您表达更复杂的前后重构,并提供有关如何在其javadoc中使用它们的示例。
另请参阅本文档的高级功能部分。

在上面的例子中,@AlsoNegation用于表示该规则也可以匹配@BeforeTemplate主体的逻辑否定(string.length()!= 0将变成!string.isEmpty());

运行重构

提示:这些说明在HEAD的最新快照中有效,并可能会更改

使用error prone的javac jarerror_prone_refaster jar来编译refaster模板:

wget http://repo1.maven.org/maven2/com/google/errorprone/javac/9-dev-r3297-4/javac-9-dev-r3297-4.jar
wget http://repo1.maven.org/maven2/com/google/errorprone/error_prone_refaster/2.0.18/error_prone_refaster-2.0.18.jar

java -cp javac-9-dev-r3297-4.jar:error_prone_refaster-2.0.18.jar \
  com.google.errorprone.refaster.RefasterRuleCompiler \
  StringIsEmpty.java --out `pwd`/myrule.refaster

您应该在当前目录中看到一个名为myrule.refaster的文件。要使用它来重构代码,请将以下标记添加到Error Prone编译器中(这类似于打补丁):

-XepPatchChecks:refaster:/full/path/to/myrule.refaster
-XepPatchLocation:/full/path/to/your/source/root

这将生成一个名为error-prone.patch的统一的diff文件,您可以类似地应用于应用其他补丁的方式:

cd /full/path/to/your/source/root
patch -p0 -u -i error-prone.patch

……

 参考链接: refaster templates

 类似资料: