inline method: check code block on inline in super/this/loop condition

IDEA-60341
This commit is contained in:
Anna.Kozlova
2017-11-16 18:39:19 +01:00
parent 369b037f4b
commit 85b4d20080
4 changed files with 52 additions and 6 deletions
@@ -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;
@@ -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<PsiMethodCallExpression> 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) {
@@ -0,0 +1,16 @@
class Main {
public Main() {
this(f<caret>oo());
}
public Main(boolean b) { }
private static boolean foo() {
if (2 < 1) {
return true;
} else {
return false;
}
}
}
@@ -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();
}