From 2c7124b0b00a83da994b91074b901ff499b478b3 Mon Sep 17 00:00:00 2001 From: Tagir Valeev Date: Wed, 7 Nov 2018 10:43:54 +0700 Subject: [PATCH] ExpressionUtils#getTopLevelExpression; used in SurroundWithTryCatchFix Fixes EA-131551 - NPE: EnsureCodeBlockImpl.splitIf We need to avoid custom logic for processing && chains, etc. in RefactoringUtil#ensureCodeBlock. --- .../quickfix/SurroundWithTryCatchFix.java | 5 +++-- .../surroundWithTry/afterIncomplete.java | 13 ++++++++++++ .../surroundWithTry/beforeIncomplete.java | 9 +++++++++ .../siyeh/ig/psiutils/ExpressionUtils.java | 20 +++++++++++++++++++ 4 files changed, 45 insertions(+), 2 deletions(-) create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/surroundWithTry/afterIncomplete.java create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/surroundWithTry/beforeIncomplete.java diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/SurroundWithTryCatchFix.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/SurroundWithTryCatchFix.java index 824783f6705f..0a3b4cbb1ae7 100644 --- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/SurroundWithTryCatchFix.java +++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/SurroundWithTryCatchFix.java @@ -28,6 +28,7 @@ import com.intellij.psi.*; import com.intellij.refactoring.util.RefactoringUtil; import com.intellij.util.IncorrectOperationException; import com.siyeh.ig.psiutils.ControlFlowUtils; +import com.siyeh.ig.psiutils.ExpressionUtils; import org.jetbrains.annotations.NotNull; /** @@ -43,7 +44,7 @@ public class SurroundWithTryCatchFix implements IntentionAction { element instanceof PsiResourceVariable || (element instanceof PsiExpression && !(element instanceof PsiMethodReferenceExpression) && - ControlFlowUtils.canExtractStatement((PsiExpression)element, false))) { + ControlFlowUtils.canExtractStatement(ExpressionUtils.getTopLevelExpression((PsiExpression)element)))) { myElement = element; } } @@ -78,7 +79,7 @@ public class SurroundWithTryCatchFix implements IntentionAction { editor.getCaretModel().moveToLogicalPosition(new LogicalPosition(0, 0)); if (myElement instanceof PsiExpression) { - myElement = RefactoringUtil.ensureCodeBlock((PsiExpression)myElement); + myElement = RefactoringUtil.ensureCodeBlock(ExpressionUtils.getTopLevelExpression((PsiExpression)myElement)); } myElement = RefactoringUtil.getParentStatement(myElement, false); if (myElement == null) return; diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/surroundWithTry/afterIncomplete.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/surroundWithTry/afterIncomplete.java new file mode 100644 index 000000000000..d12c542f78e6 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/surroundWithTry/afterIncomplete.java @@ -0,0 +1,13 @@ +// "Surround with try/catch" "true" +class C { + native boolean foo() throws Exception; + + void test() { + try { + if(foo() && foo()) + } catch (Exception e) { + e.printStackTrace(); + } + } + +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/surroundWithTry/beforeIncomplete.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/surroundWithTry/beforeIncomplete.java new file mode 100644 index 000000000000..ba4ed3ea0097 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/surroundWithTry/beforeIncomplete.java @@ -0,0 +1,9 @@ +// "Surround with try/catch" "true" +class C { + native boolean foo() throws Exception; + + void test() { + if(foo() && foo()) + } + +} \ No newline at end of file diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/psiutils/ExpressionUtils.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/psiutils/ExpressionUtils.java index 0dc45042dc6e..6fcd6dc972a6 100644 --- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/psiutils/ExpressionUtils.java +++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/psiutils/ExpressionUtils.java @@ -1394,4 +1394,24 @@ public class ExpressionUtils { public static boolean isArrayCreationExpression(@NotNull PsiNewExpression expression) { return expression.getArrayInitializer() != null || expression.getArrayDimensions().length > 0; } + + /** + * Returns ancestor expression for given subexpression which parent is not an expression anymore (except lambda) + * + * @param expression an expression to find its ancestor + * @return a top-level expression for given expression (may return an expression itself) + */ + @NotNull + public static PsiExpression getTopLevelExpression(@NotNull PsiExpression expression) { + while(true) { + PsiElement parent = expression.getParent(); + if (parent instanceof PsiExpression && !(parent instanceof PsiLambdaExpression)) { + expression = (PsiExpression)parent; + } else if (parent instanceof PsiExpressionList && parent.getParent() instanceof PsiExpression) { + expression = (PsiExpression)parent.getParent(); + } else { + return expression; + } + } + } } \ No newline at end of file