diff --git a/java/java-impl/src/com/intellij/codeInspection/RedundantExplicitCloseInspection.java b/java/java-impl/src/com/intellij/codeInspection/RedundantExplicitCloseInspection.java index 0d572e77f402..5b033f6e6d07 100644 --- a/java/java-impl/src/com/intellij/codeInspection/RedundantExplicitCloseInspection.java +++ b/java/java-impl/src/com/intellij/codeInspection/RedundantExplicitCloseInspection.java @@ -3,8 +3,11 @@ package com.intellij.codeInspection; import com.intellij.openapi.project.Project; import com.intellij.psi.*; +import com.intellij.psi.util.PsiUtil; +import com.intellij.util.ArrayUtil; import com.siyeh.ig.callMatcher.CallMatcher; import com.siyeh.ig.psiutils.CommentTracker; +import com.siyeh.ig.psiutils.EquivalenceChecker; import one.util.streamex.StreamEx; import org.jetbrains.annotations.Nls; import org.jetbrains.annotations.NotNull; @@ -25,28 +28,21 @@ public class RedundantExplicitCloseInspection extends AbstractBaseJavaLocalInspe PsiCodeBlock tryBlock = statement.getTryBlock(); if (tryBlock == null) return; - PsiStatement[] statements = tryBlock.getStatements(); - if(statements.length == 0) return; - PsiStatement last = statements[statements.length - 1]; + PsiStatement last = ArrayUtil.getLastElement(tryBlock.getStatements()); PsiExpressionStatement expressionStatement = tryCast(last, PsiExpressionStatement.class); if(expressionStatement == null) return; PsiMethodCallExpression call = tryCast(expressionStatement.getExpression(), PsiMethodCallExpression.class); if (!CLOSE.test(call)) return; - PsiReferenceExpression reference = tryCast(call.getMethodExpression().getQualifierExpression(), PsiReferenceExpression.class); + PsiExpression qualifier = call.getMethodExpression().getQualifierExpression(); + PsiReferenceExpression reference = tryCast(PsiUtil.skipParenthesizedExprDown(qualifier), PsiReferenceExpression.class); if(reference == null) return; PsiVariable variable = tryCast(reference.resolve(), PsiVariable.class); if(variable == null) return; - boolean isReferenceToResourceVariable = StreamEx.of(resourceList.iterator()) - .anyMatch(element -> { - if (element instanceof PsiResourceVariable && variable == element) { - return true; - } - else { - PsiReferenceExpression ref = tryCast(element, PsiReferenceExpression.class); - if (ref == null) return false; - return ref.resolve() == variable; - } - }); + boolean isReferenceToResourceVariable = StreamEx.of(resourceList.iterator()).anyMatch( + element -> variable == element || + element instanceof PsiResourceExpression && + EquivalenceChecker.getCanonicalPsiEquivalence() + .expressionsAreEquivalent(reference, ((PsiResourceExpression)element).getExpression())); if(!isReferenceToResourceVariable) return; holder.registerProblem(last, InspectionsBundle.message("inspection.redundant.explicit.close"), ProblemHighlightType.LIKE_UNUSED_SYMBOL, new DeleteRedundantCloseFix()); diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/redundantExplicitClose/afterRemoveTry.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/redundantExplicitClose/afterRemoveTry.java index 43da9cdeb83f..13863fc0c498 100644 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/redundantExplicitClose/afterRemoveTry.java +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/redundantExplicitClose/afterRemoveTry.java @@ -2,7 +2,7 @@ class MyAutoCloseable implements AutoCloseable { @Override - void close() { + public void close() { } } diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/redundantExplicitClose/afterRemoveTryFieldJava9.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/redundantExplicitClose/afterRemoveTryFieldJava9.java new file mode 100644 index 000000000000..3e1742d2e585 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/redundantExplicitClose/afterRemoveTryFieldJava9.java @@ -0,0 +1,18 @@ +// "Remove redundant close" "true" + +class MyAutoCloseable implements AutoCloseable { + @Override + public void close() { + + } +} + +class RemoveTry { + final MyAutoCloseable ac; + + public void main(RemoveTry other) { + try(other.ac) { + System.out.println("asdasd"); + } + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/redundantExplicitClose/afterRemoveTryJava9.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/redundantExplicitClose/afterRemoveTryJava9.java new file mode 100644 index 000000000000..451757a9422c --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/redundantExplicitClose/afterRemoveTryJava9.java @@ -0,0 +1,16 @@ +// "Remove redundant close" "true" + +class MyAutoCloseable implements AutoCloseable { + @Override + public void close() { + + } +} + +class RemoveTry { + public static void main(MyAutoCloseable ac) { + try(ac) { + System.out.println("asdasd"); + } + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/redundantExplicitClose/beforeRemoveTry.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/redundantExplicitClose/beforeRemoveTry.java index e9e6de0d431b..6551fe122fc9 100644 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/redundantExplicitClose/beforeRemoveTry.java +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/redundantExplicitClose/beforeRemoveTry.java @@ -2,7 +2,7 @@ class MyAutoCloseable implements AutoCloseable { @Override - void close() { + public void close() { } } @@ -11,7 +11,7 @@ class RemoveTry { public static void main(String[] args) { try(MyAutoCloseable ac = new MyAutoCloseable()) { System.out.println("asdasd"); - ac.close(); + (ac).close(); } } } \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/redundantExplicitClose/beforeRemoveTryField2Java9.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/redundantExplicitClose/beforeRemoveTryField2Java9.java new file mode 100644 index 000000000000..46d7b2b7c968 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/redundantExplicitClose/beforeRemoveTryField2Java9.java @@ -0,0 +1,19 @@ +// "Remove redundant close" "false" + +class MyAutoCloseable implements AutoCloseable { + @Override + public void close() { + + } +} + +class RemoveTry { + final MyAutoCloseable ac; + + public void main(RemoveTry other) { + try(other.ac) { + System.out.println("asdasd"); + this.ac.close(); + } + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/redundantExplicitClose/beforeRemoveTryFieldJava9.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/redundantExplicitClose/beforeRemoveTryFieldJava9.java new file mode 100644 index 000000000000..bcc22ed2d9b3 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/redundantExplicitClose/beforeRemoveTryFieldJava9.java @@ -0,0 +1,19 @@ +// "Remove redundant close" "true" + +class MyAutoCloseable implements AutoCloseable { + @Override + public void close() { + + } +} + +class RemoveTry { + final MyAutoCloseable ac; + + public void main(RemoveTry other) { + try(other.ac) { + System.out.println("asdasd"); + other.ac.close(); + } + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/redundantExplicitClose/beforeRemoveTryJava9.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/redundantExplicitClose/beforeRemoveTryJava9.java new file mode 100644 index 000000000000..9a351da9e219 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/redundantExplicitClose/beforeRemoveTryJava9.java @@ -0,0 +1,17 @@ +// "Remove redundant close" "true" + +class MyAutoCloseable implements AutoCloseable { + @Override + public void close() { + + } +} + +class RemoveTry { + public static void main(MyAutoCloseable ac) { + try(ac) { + System.out.println("asdasd"); + (ac).close(); + } + } +} \ No newline at end of file