Skip to content

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

Open

Description

@DidierLoiseau

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)

Activity

  1. DidierLoiseau commented on May 30, 2024

    @DidierLoiseau
    Author

    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.

  2. changed the title [-]Intellij Plugin breaks method inlining inside if condition[/-] [+]Intellij Plugin breaks method inlining and variable extraction from inside if condition[/+] on May 30, 2024
  3. nrayburn-tech commented on Aug 23, 2024

    @nrayburn-tech
    Contributor

    For the first example, the code fails at the line here https://github.com/JetBrains/intellij-community/blob/cd9bfbd98a7dca730fbc469156ce1ed30364afba/java/java-analysis-impl/src/com/siyeh/ig/psiutils/CodeBlockSurrounder.java#L884 due to a ClassCastException.

    After formatting, CodeStyleManager.getInstance(project).reformat() is returning an instance of PsiKeywordImpl instead of the expected PsiIfStatement. Not sure why this is happening. I don't see where we return any PSI elements directly, we only return a string. So, something about how that string is being parsed into PSI elements isn't working as expected.

    Because the exception is thrown, the remaining refactor logic from IntelliJ doesn't seem to be running.

  4. amaembo commented on Oct 17, 2024

    @amaembo

    IntelliJ developer is here. We will work around the problem on the IntelliJ side (ClassCastException in CodeBlockSurrounder). However, the root cause is not identified, and similar problem may still happen in other contexts. Please track IDEA-340109 for details.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions