question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

`formatAnnotations()` contradicts Google Java style

See original GitHub issue

I’m using formatAnnotations() together with googleJavaFormat() and introducing the former also brought surprising changes. Type annotations on class and method declarations are affected:

-@Value
-@Jacksonized
+@Value @Jacksonized
 @Builder
 public class Example {
   @Bean
-  @Qualifier("example")
-  RestTemplate example() {
+  @Qualifier("example") RestTemplate example() {

However, Google’s Java Style Guide, section “4.8.5 Annotations” says that

Annotations applying to a class appear immediately after the documentation block, and each annotation is listed on a line of its own (that is, one annotation per line).

and the same applies to method and constructor annotations, without mentioning any exception for type annotations.

Moreover, the claim that “Type annotations should be on the same line as the type that they qualify.” in Spotless Gradle plugin’s README doesn’t cite any source.

So which of these formatters is right?

My Spotless configuration for Java:

spotless {
    encoding("UTF-8")
    java {
        target("src/*/java/**/*.java")
        targetExclude("**/build/")
        importOrder()
        removeUnusedImports()
        googleJavaFormat()
        formatAnnotations()
    }
}

Spotless 6.11.0 with Gradle 7.5.1

Issue Analytics

  • State:closed
  • Created a year ago
  • Comments:5 (3 by maintainers)

github_iconTop GitHub Comments

2reactions
mernstcommented, Oct 15, 2022

Thanks for bringing up this issue!

Type annotations on method declarations are affected:

   @Bean
-  @Qualifier("example")
-  RestTemplate example() {
+  @Qualifier("example") RestTemplate example() {

There is no such thing as a type annotation on a method declaration. In your example, @Qualifier modifies the type RestTemplate (it does not modify the method example), so the formatting is correct.

With regard to class annotations, you are right that style guidelines are not explicit. The preferred style is:

@DeclarationAnnotation1
@DeclarationAnnotation2
public @TypeAnnotation1 @TypeAnnotation2 class MyClass {
  ...
}

Note that this is similar to the case for methods. The preferred style for methods is:

@DeclarationAnnotation1
@DeclarationAnnotation2
public @TypeAnnotation1 @TypeAnnotation2 ReturnType myMethod {
  ...
}

If you write the annotations in the correct places (before/after modifiers such as public), Spotless enforces the correct formatting.

As noted at https://github.com/diffplug/spotless/blob/main/plugin-gradle/README.md#formatAnnotations, Spotless does not currently reorder annotations. It does not move annotations around modifiers. Spotless also does not reorder annotations of a particular variety (say, putting all declaration annotations in a canonical order, such as alphabetical order. These could be enhancement requests.

As you point out, the Spotless test suite lacks test cases for the dispreferred style, and it entirely lacks test cases for annotations on class declarations. I’ll add some at https://github.com/diffplug/spotless/pull/1368.

Moreover, the claim that “Type annotations should be on the same line as the type that they qualify.” in Spotless Gradle plugin’s README doesn’t cite any source.

The reason is that the qualified type is, in your example, @Qualifier RestTemplate. That is a logical unit. Breaking that logical unit across lines is misleading. For instance, it may give a reader the impression that the annotation qualifies the method.

Here are some code examples from Oracle showing the preferred style:

https://docs.oracle.com/javase/tutorial/java/annotations/basics.html https://docs.oracle.com/javase/tutorial/java/annotations/type_annotations.html

Here are citations from Google:

https://google.github.io/styleguide/javaguide.html#s4.8.5-annotations https://github.com/google/google-java-format/issues/5

Note that the GJF manual incorrectly uses the name “type-use annotation” when it should use the standard term “type annotation”.

Here is one from the Checker Framework:

https://checkerframework.org/manual/#declaration-annotations-moved

I can also be considered an authority. I designed Java’s type annotations feature, and the javac implementation is by a group of people including me.

0reactions
mernstcommented, Oct 17, 2022

@edysli No problem! Thanks again for bringing up the issue.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Handle type annotations · Issue #5 · google/google-java-format
We always want to format type annotations in-line: @Nullable ... formatAnnotations() contradicts Google Java style diffplug/spotless#1366.
Read more >
Google Java Style Guide
This document serves as the complete definition of Google's coding standards for source code in the Java™ Programming Language. A Java source file...
Read more >
Intellij with google-java-format - how to make Java annotations ...
I'm using IntelliJ IDEA 2018.1 (Community Edition) on MacOs and install google-java-format plugin, however when I format the code by Command ...
Read more >
Configure Onap Code Style for Idea IDE
ONAP Java Code Style is based on Google Style with two modifications ... Surprisingly, it also seems to contradict the Google Style Guide...
Read more >
Clang-Format Style Options — Clang 16.0.0git documentation
When using clang-format command line utility or clang::format::reformat(...) functions from code, one can either use one of the predefined styles (LLVM, Google, ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found