diff --git a/java/java-impl/src/com/intellij/refactoring/inline/InlineMethodHandler.java b/java/java-impl/src/com/intellij/refactoring/inline/InlineMethodHandler.java index a086d22b565e..f8dfac7453e5 100644 --- a/java/java-impl/src/com/intellij/refactoring/inline/InlineMethodHandler.java +++ b/java/java-impl/src/com/intellij/refactoring/inline/InlineMethodHandler.java @@ -84,7 +84,7 @@ class InlineMethodHandler extends JavaInlineActionHandler { } if (reference != null) { - final String errorMessage = InlineMethodProcessor.checkCalledInSuperOrThisExpr(methodBody, reference.getElement()); + final String errorMessage = InlineMethodProcessor.checkUnableToInsertCodeBlock(methodBody, reference.getElement()); if (errorMessage != null) { CommonRefactoringUtil.showErrorHint(project, editor, errorMessage, REFACTORING_NAME, HelpID.INLINE_METHOD); return; diff --git a/java/java-impl/src/com/intellij/refactoring/inline/InlineMethodProcessor.java b/java/java-impl/src/com/intellij/refactoring/inline/InlineMethodProcessor.java index fad0cd5482b2..8e807c2f5500 100644 --- a/java/java-impl/src/com/intellij/refactoring/inline/InlineMethodProcessor.java +++ b/java/java-impl/src/com/intellij/refactoring/inline/InlineMethodProcessor.java @@ -52,6 +52,7 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.*; +import java.util.function.Predicate; public class InlineMethodProcessor extends BaseRefactoringProcessor { private static final Logger LOG = Logger.getInstance("#com.intellij.refactoring.inline.InlineMethodProcessor"); @@ -214,7 +215,7 @@ public class InlineMethodProcessor extends BaseRefactoringProcessor { } } - final String errorMessage = checkCalledInSuperOrThisExpr(myMethod.getBody(), element); + final String errorMessage = checkUnableToInsertCodeBlock(myMethod.getBody(), element); if (errorMessage != null) { conflicts.putValue(element, errorMessage); } @@ -1507,17 +1508,42 @@ public class InlineMethodProcessor extends BaseRefactoringProcessor { return ((PsiAssignmentExpression)expression).getRExpression(); } + @Deprecated public static String checkCalledInSuperOrThisExpr(PsiCodeBlock methodBody, final PsiElement element) { - if (methodBody.getStatements().length > 1) { + return checkUnableToInsertCodeBlock(methodBody, element, + expr -> RefactoringChangeUtil.isSuperOrThisMethodCall(expr) && expr.getMethodExpression() != element) + ? "Inline cannot be applied to multiline method in constructor call" + : null; + } + + public static String checkUnableToInsertCodeBlock(PsiCodeBlock methodBody, final PsiElement element) { + if (checkUnableToInsertCodeBlock(methodBody, element, + expr -> RefactoringChangeUtil.isSuperOrThisMethodCall(expr) && expr.getMethodExpression() != element)) { + return "Inline cannot be applied to multiline method in constructor call"; + } + return checkUnableToInsertCodeBlock(methodBody, element, + expr -> { + PsiElement parent = expr.getParent(); + return parent instanceof PsiLoopStatement && PsiUtil.isCondition(expr, parent); + }) + ? "Inline cannot be applied to multiline method in loop condition" + : null; + } + + private static boolean checkUnableToInsertCodeBlock(final PsiCodeBlock methodBody, + final PsiElement element, + final Predicate errorCondition) { + PsiStatement[] statements = methodBody.getStatements(); + if (statements.length > 1 || statements.length == 1 && !(statements[0] instanceof PsiExpressionStatement)) { PsiMethodCallExpression expr = PsiTreeUtil.getParentOfType(element, PsiMethodCallExpression.class, true, PsiStatement.class); while (expr != null) { - if (RefactoringChangeUtil.isSuperOrThisMethodCall(expr) && expr.getMethodExpression() != element) { - return "Inline cannot be applied to multiline method in constructor call"; + if (errorCondition.test(expr)) { + return true; } expr = PsiTreeUtil.getParentOfType(expr, PsiMethodCallExpression.class, true, PsiStatement.class); } } - return null; + return false; } public static boolean checkBadReturns(PsiMethod method) { diff --git a/java/java-tests/testData/refactoring/inlineMethod/UnableToInlineCodeBlockToSuper.java b/java/java-tests/testData/refactoring/inlineMethod/UnableToInlineCodeBlockToSuper.java new file mode 100644 index 000000000000..10a828bbaff7 --- /dev/null +++ b/java/java-tests/testData/refactoring/inlineMethod/UnableToInlineCodeBlockToSuper.java @@ -0,0 +1,16 @@ + +class Main { + public Main() { + this(foo()); + } + + public Main(boolean b) { } + + private static boolean foo() { + if (2 < 1) { + return true; + } else { + return false; + } + } +} \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/java/refactoring/inline/InlineMethodTest.java b/java/java-tests/testSrc/com/intellij/java/refactoring/inline/InlineMethodTest.java index a78ada47db22..2c57cdb4ebac 100644 --- a/java/java-tests/testSrc/com/intellij/java/refactoring/inline/InlineMethodTest.java +++ b/java/java-tests/testSrc/com/intellij/java/refactoring/inline/InlineMethodTest.java @@ -327,6 +327,10 @@ public class InlineMethodTest extends LightRefactoringTestCase { doTestConflict("Inlined method is used in method reference with side effects in qualifier"); } + public void testUnableToInlineCodeBlockToSuper() { + doTestConflict("Inline cannot be applied to multiline method in constructor call"); + } + public void testRedundantCastOnMethodReferenceToLambda() { doTest(); }