google / google-java-format

Reformats Java source code to comply with Google Java Style.
Other
5.49k stars 848 forks source link

Intellij Plugin breaks method inlining and variable extraction from inside if condition #1101

Open DidierLoiseau opened 1 month ago

DidierLoiseau commented 1 month ago

Consider the following code and try inlining isEmpty2:

import java.util.Collection;
import java.util.List;

public class InliningWithJavaFormat {
  static boolean isEmpty(Collection<?> c) {
    return c == null || c.isEmpty();
  }

  static boolean isEmpty2(Collection<?> c) {
    return isEmpty(c);
  }

  public static void main(String[] args){
    var pojo = new MyPojo();
    if (pojo != null && !isEmpty2(pojo.getCollection())) {
      System.out.println("empty");
    }
  }

  static class MyPojo {
    Collection<String> getCollection() {
      return List.of();
    }
  }
}

Not only does it fail (without reporting it), but it adds an additional if (true):

  public static void main(String[] args){
    var pojo = new MyPojo();
    if (pojo != null && !isEmpty2(pojo.getCollection())) {
      if (true) {
        System.out.println("empty");
      }
    }
  }

with the plugin disabled, it works:

  public static void main(String[] args){
    var pojo = new MyPojo();
    if (pojo != null) {
      Collection<?> c = pojo.getCollection();
      if (!isEmpty(c)) {
        System.out.println("empty");
      }
    }
  }

(not the ideal result but at least it does not fail)

In addition, when I do that on my actual project I get an error notification from the plugin and the formatting gets broken: error notification (I did not try to reproduce this with an MRE, I guess it is a side effect of the first issue)

DidierLoiseau commented 1 month ago

I just noticed that the same issue occurs if you simply try to extract a local variable from within the if condition instead of performing an inlining. IntelliJ would normally split the if in a similar way.

I guess this is what IntelliJ tries to do under the hood for the inlining (as shown when the plugin is disabled), and the at the source of the problem.