BT

Facilitating the Spread of Knowledge and Innovation in Professional Software Development

Write for InfoQ

Topics

Choose your language

InfoQ Homepage News Error Prone Support Introduces New Bug Checks and Refaster Templates

Error Prone Support Introduces New Bug Checks and Refaster Templates

Picnic, the "supermarket on wheels" company, has released Error Prone Support, an open source project that extends Google's Error Prone, that contains thirty new bug checks to detect, and optionally resolve, possible mistakes during compilation of a Java project. More than fifty new Refaster rule collections are available to improve code uniformity by automatically rewriting the codebase.

Error Prone is a Java compiler plugin, open sourced by Google, which performs static analysis during compilation to detect bugs or suggest possible improvements. The plugin contains more than 500 pre-defined bug checks and allows third party and custom plugins. After detecting issues, Error Prone can display a warning or automatically change the code with a predefined solution.

One of the thirty new bug checks provided by the recently released Error Prone Support is the EmptyMethod class, a bug check which will display a warning or optionally remove the following methods:

void method() {}
static void staticMethod() {}

Whenever an empty method is necessary, the false positive may be suppressed with the following annotation:

@SuppressWarnings("EmptyMethod")

The AutowiredConstructor bug check removes the redundant @Autowired annotation whenever a class has just one constructor as in the following examples:

class Course {
	@Autowired
	Course() {}
}

class Student {
	@Autowired
	Student(String name) {}
}

The MethodReferenceUsage class detects lambda expressions and converts them to method references. For example, () -> course.method() is changed to course::method.

Writing a bug check in Error Prone involves working with abstract syntax trees (AST) and Error Prone’s APIs. This is often necessary to detect bugs, but mostly not when rewriting code. Google's Refaster is easier to use and now part of Error Prone. Refaster rules may be used to define rewrite rules in Java with @BeforeTemplate and @AfterTemplate annotations. Error Prone Support offers more than fifty new Refaster rule collections containing more than 500 Refaster templates, such as the StringRules class, which replaces various expressions to evaluate whether a String is empty with the String.isEmpty() method:

@BeforeTemplate
boolean before(String str) {
    return Refaster.anyOf(str.length() == 0, str.length() <= 0,   
        str.length() < 1);
}

@AfterTemplate
@AlsoNegation
boolean after(String str) {
    return str.isEmpty();
}

The @AlsoNegation annotation indicates that the rule can also match the logical negation of the @BeforeTemplate bodies. For example, the code str.length() != 0 will be changed to !str.isEmpty().

The TimeRules class contains various rewrite rules for time expressions such as replacing various Zone offsets with UTC:

@BeforeTemplate
ZoneId before() {
    // `ZoneId.of("Z")` is not listed, because Error Prone flags it out of the box.
    return Refaster.anyOf(
        ZoneId.of("GMT"),
        ZoneId.of("UTC"),
        ZoneId.of("+0"),
        ZoneId.of("-0"),
        UTC.normalized(),
        ZoneId.from(UTC));
}

@AfterTemplate
ZoneOffset after() {
    return UTC;
}

Or replacing the compareTo method with the more readable isBefore method:

@BeforeTemplate
boolean before(Instant a, Instant b) {
    return a.compareTo(b) < 0;
}

@AfterTemplate
@AlsoNegation
boolean after(Instant a, Instant b) {
    return a.isBefore(b);
}

The installation instructions for Error Prone can be used as a basis, as Error Prone Support is built on top of it. After that, the relevant Error Prone Support modules should be added to the annotationProcessorPaths, for example, with the maven-compiler-plugin:

<annotationProcessorPaths>
    <!-- Error Prone. -->
    <path>
        <groupId>com.google.errorprone</groupId>
        <artifactId>error_prone_core</artifactId>
        <version>${error-prone.version}</version>
    </path>
    <!-- Error Prone Support's bug checks. -->
    <path>
        <groupId>tech.picnic.error-prone-support</groupId>
        <artifactId>error-prone-contrib</artifactId>
        <version>${error-prone-support.version}</version>
    </path>
    <!-- Error Prone Support's Refaster rules. -->
    <path>
        <groupId>tech.picnic.error-prone-support</groupId>
        <artifactId>refaster-runner</artifactId>
        <version>${error-prone-support.version}</version>
    </path>
</annotationProcessorPaths>

InfoQ spoke to Rick Ossendrijver, software engineer at Picnic and one of the creators of Error Prone Support.

InfoQ: What made you decide to create Error Prone Support instead of adding the bug checks to Error Prone?

Rick Ossendrijver: Google Error Prone doesn't accept many new checks and Error Prone Support contains some Picnic-opinionated checks. Releasing the bug checks separately also prevents overloading the Google maintainers of Error Prone with contributions. A separate project also allows us to release faster and more often without being dependent on the Error Prone maintainers.

InfoQ: Is the focus of Error Prone Support on code uniformity, bug detection, or both?

Ossendrijver: We definitely focus on both. We highly value code consistency (uniformity). For code uniformity we prefer refaster rules as they are easier to write than bug checks which require more in-depth Java knowledge. For bug detection, one usually needs to write a bug check as a more thorough analysis is required.

InfoQ: Can you already tell us something about upcoming features?

Ossendrijver: Yes for sure, we plan a number of improvements. First of all, the existing matching algorithm is relatively slow and we made some major improvements to speed up Refaster.

Next to that, Error Prone bug checks show compilation warnings or errors as shown in the example on the website. The message provides a link to the documentation of that specific bug check. We have support for running Refaster rules "as a bug check". That means that we also show compilation warnings or errors. Soon we will add links to the documentation website when a Refaster rule matches in the code. On top of that, we will be introducing new annotations and processing thereof, to provide better error messages when a Refaster rule flags something.

Lastly, we will introduce more bug checks and Refaster rules. Our Maven `self-check` profile applies those bug checks and Refaster rules on the codebase itself. That way we can easily increase the quality of our codebase.

Error Prone Support welcomes contributions and provides contribution guidelines.

About the Author

Rate this Article

Adoption
Style

BT