inline: disable for multiline methods inlined in super/this constructor calls (IDEA-96962)

This commit is contained in:
anna
2012-12-10 12:56:06 +01:00
parent e9a5107186
commit f6e0f4bd7a
4 changed files with 57 additions and 2 deletions
@@ -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);
@@ -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;
@@ -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 t<caret>est(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.
}
}
@@ -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();