From f6e0f4bd7a3c886daddba58cc585bfd430324642 Mon Sep 17 00:00:00 2001 From: anna Date: Mon, 10 Dec 2012 11:57:24 +0100 Subject: [PATCH] inline: disable for multiline methods inlined in super/this constructor calls (IDEA-96962) --- .../inline/InlineMethodHandler.java | 13 +++++++++-- .../inline/InlineMethodProcessor.java | 19 ++++++++++++++++ .../refactoring/inlineMethod/InSuperCall.java | 22 +++++++++++++++++++ .../refactoring/inline/InlineMethodTest.java | 5 +++++ 4 files changed, 57 insertions(+), 2 deletions(-) create mode 100644 java/java-tests/testData/refactoring/inlineMethod/InSuperCall.java 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 21658bae25e2..166e6f2aa493 100644 --- a/java/java-impl/src/com/intellij/refactoring/inline/InlineMethodHandler.java +++ b/java/java-impl/src/com/intellij/refactoring/inline/InlineMethodHandler.java @@ -41,7 +41,8 @@ class InlineMethodHandler extends JavaInlineActionHandler { public void inlineElement(final Project project, Editor editor, PsiElement element) { PsiMethod method = (PsiMethod)element.getNavigationElement(); - if (method.getBody() == null){ + final PsiCodeBlock methodBody = method.getBody(); + if (methodBody == null){ String message; if (method.hasModifierProperty(PsiModifier.ABSTRACT)) { message = RefactoringBundle.message("refactoring.cannot.be.applied.to.abstract.methods", REFACTORING_NAME); @@ -85,7 +86,15 @@ class InlineMethodHandler extends JavaInlineActionHandler { CommonRefactoringUtil.showErrorHint(project, editor, REFACTORING_NAME + " cannot be applied to method references", REFACTORING_NAME, HelpID.INLINE_METHOD); return; } - + + if (reference != null) { + final String errorMessage = InlineMethodProcessor.checkCalledInSuperOrThisExpr(methodBody, reference.getElement()); + if (errorMessage != null) { + CommonRefactoringUtil.showErrorHint(project, editor, errorMessage, REFACTORING_NAME, HelpID.INLINE_METHOD); + return; + } + } + if (method.isConstructor()) { if (method.isVarArgs()) { String message = RefactoringBundle.message("refactoring.cannot.be.applied.to.vararg.constructors", REFACTORING_NAME); 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 527e52fbfa6e..ab77b8bf82af 100644 --- a/java/java-impl/src/com/intellij/refactoring/inline/InlineMethodProcessor.java +++ b/java/java-impl/src/com/intellij/refactoring/inline/InlineMethodProcessor.java @@ -16,6 +16,7 @@ package com.intellij.refactoring.inline; import com.intellij.codeInsight.ChangeContextUtil; +import com.intellij.codeInsight.daemon.impl.analysis.HighlightUtil; import com.intellij.history.LocalHistory; import com.intellij.history.LocalHistoryAction; import com.intellij.lang.Language; @@ -194,6 +195,11 @@ public class InlineMethodProcessor extends BaseRefactoringProcessor { if (element instanceof PsiMethodReferenceExpression) { conflicts.putValue(element, "Inlined method is used in method reference"); } + + final String errorMessage = checkCalledInSuperOrThisExpr(myMethod.getBody(), element); + if (errorMessage != null) { + conflicts.putValue(element, errorMessage); + } } } @@ -1424,6 +1430,19 @@ public class InlineMethodProcessor extends BaseRefactoringProcessor { return ((PsiAssignmentExpression)expression).getRExpression(); } + public static String checkCalledInSuperOrThisExpr(PsiCodeBlock methodBody, final PsiElement element) { + if (methodBody.getStatements().length > 1) { + PsiExpression expr = PsiTreeUtil.getParentOfType(element, PsiExpression.class); + while (expr != null) { + if (HighlightUtil.isSuperOrThisMethodCall(expr)) { + return "Inline cannot be applied to multiline method in constructor call"; + } + expr = PsiTreeUtil.getParentOfType(expr, PsiExpression.class, true); + } + } + return null; + } + public static boolean checkBadReturns(PsiMethod method) { PsiReturnStatement[] returns = RefactoringUtil.findReturnStatements(method); if (returns.length == 0) return false; diff --git a/java/java-tests/testData/refactoring/inlineMethod/InSuperCall.java b/java/java-tests/testData/refactoring/inlineMethod/InSuperCall.java new file mode 100644 index 000000000000..3e70c42c09a2 --- /dev/null +++ b/java/java-tests/testData/refactoring/inlineMethod/InSuperCall.java @@ -0,0 +1,22 @@ +class BBB { + public BBB(String x) { + } + + void foo(String s) {} +} + +class AAA extends BBB { + public AAA(String x) { + super(test(x)); + } + + private static String test(String x) { + String y = x.trim(); + return y.length() > 0 ? y : "aaaa"; + } + + @Override + void foo(String s) { + super.foo(test(s)); //To change body of overridden methods use File | Settings | File Templates. + } +} \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/refactoring/inline/InlineMethodTest.java b/java/java-tests/testSrc/com/intellij/refactoring/inline/InlineMethodTest.java index d69085c4e5c3..59f27ab992f3 100644 --- a/java/java-tests/testSrc/com/intellij/refactoring/inline/InlineMethodTest.java +++ b/java/java-tests/testSrc/com/intellij/refactoring/inline/InlineMethodTest.java @@ -198,6 +198,11 @@ public class InlineMethodTest extends LightRefactoringTestCase { doTestConflict("Inlined result would contain parse errors"); } + + public void testInSuperCall() throws Exception { + doTestConflict("Inline cannot be applied to multiline method in constructor call"); + } + private void doTestConflict(final String conflict) throws Exception { try { doTest();