mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
[java-inspections] IDEA-300159 Redundant close(): Search closing statements in if statements
PR#2106 Reviewed-by: Tagir Valeev <tagir.valeev@jetbrains.com> GitOrigin-RevId: 501e4fee7441bf38e1d0ad19f826d3a7b565920b
This commit is contained in:
committed by
intellij-monorepo-bot
parent
76800e0899
commit
4efbdf1fb5
+42
-33
@@ -1,17 +1,21 @@
|
||||
// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package com.intellij.codeInspection;
|
||||
|
||||
import com.intellij.codeInsight.daemon.impl.quickfix.DeleteElementFix;
|
||||
import com.intellij.java.JavaBundle;
|
||||
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.ControlFlowUtils;
|
||||
import com.siyeh.ig.psiutils.EquivalenceChecker;
|
||||
import one.util.streamex.StreamEx;
|
||||
import org.jetbrains.annotations.Nls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import static com.intellij.util.ObjectUtils.tryCast;
|
||||
|
||||
@@ -29,40 +33,45 @@ public class RedundantExplicitCloseInspection extends AbstractBaseJavaLocalInspe
|
||||
|
||||
PsiCodeBlock tryBlock = statement.getTryBlock();
|
||||
if (tryBlock == null) return;
|
||||
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;
|
||||
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 -> variable == element ||
|
||||
element instanceof PsiResourceExpression &&
|
||||
EquivalenceChecker.getCanonicalPsiEquivalence()
|
||||
.expressionsAreEquivalent(reference, ((PsiResourceExpression)element).getExpression()));
|
||||
if(!isReferenceToResourceVariable) return;
|
||||
holder.registerProblem(last, JavaBundle.message("inspection.redundant.explicit.close"), new DeleteRedundantCloseFix());
|
||||
|
||||
List<PsiStatement> terminatingStatements = getTerminatingStatements(ArrayUtil.getLastElement(tryBlock.getStatements()));
|
||||
for (PsiStatement last : terminatingStatements) {
|
||||
PsiExpressionStatement expressionStatement = tryCast(last, PsiExpressionStatement.class);
|
||||
if(expressionStatement == null) return;
|
||||
PsiMethodCallExpression call = tryCast(expressionStatement.getExpression(), PsiMethodCallExpression.class);
|
||||
if (!CLOSE.test(call)) return;
|
||||
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 -> variable == element ||
|
||||
element instanceof PsiResourceExpression &&
|
||||
EquivalenceChecker.getCanonicalPsiEquivalence()
|
||||
.expressionsAreEquivalent(reference, ((PsiResourceExpression)element).getExpression()));
|
||||
if(!isReferenceToResourceVariable) return;
|
||||
holder.registerProblem(last, JavaBundle.message("inspection.redundant.explicit.close"), new DeleteElementFix(last, CommonQuickFixBundle.message("fix.remove.redundant", "close()")));
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private static class DeleteRedundantCloseFix implements LocalQuickFix {
|
||||
@Nls
|
||||
@NotNull
|
||||
@Override
|
||||
public String getFamilyName() {
|
||||
return CommonQuickFixBundle.message("fix.remove.redundant", "close()");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) {
|
||||
PsiElement element = descriptor.getStartElement();
|
||||
new CommentTracker().deleteAndRestoreComments(element);
|
||||
@NotNull
|
||||
private static List<PsiStatement> getTerminatingStatements(@Nullable PsiStatement last) {
|
||||
if (last == null) return Collections.emptyList();
|
||||
List<PsiStatement> terminatingStatements = new ArrayList<>();
|
||||
PsiIfStatement ifStatement = tryCast(last, PsiIfStatement.class);
|
||||
if (ifStatement != null) {
|
||||
PsiStatement[] thenStatements = ControlFlowUtils.unwrapBlock(ifStatement.getThenBranch());
|
||||
terminatingStatements.addAll(getTerminatingStatements(ArrayUtil.getLastElement(thenStatements)));
|
||||
PsiStatement elseBranch = ifStatement.getElseBranch();
|
||||
if (elseBranch != null) {
|
||||
PsiStatement[] elseStatements = ControlFlowUtils.unwrapBlock(elseBranch);
|
||||
terminatingStatements.addAll(getTerminatingStatements(ArrayUtil.getLastElement(elseStatements)));
|
||||
}
|
||||
} else {
|
||||
terminatingStatements.add(last);
|
||||
}
|
||||
return terminatingStatements;
|
||||
}
|
||||
}
|
||||
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
// "Remove redundant 'close()'" "true-preview"
|
||||
|
||||
class MyAutoCloseable implements AutoCloseable {
|
||||
@Override
|
||||
public void close() {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
class RemoveTry {
|
||||
public static void main(String[] args) {
|
||||
try(MyAutoCloseable ac = new MyAutoCloseable()) {
|
||||
System.out.println("Number of parameters?");
|
||||
if (args.length == 0) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
// "Remove redundant 'close()'" "true-preview"
|
||||
|
||||
class MyAutoCloseable implements AutoCloseable {
|
||||
@Override
|
||||
public void close() {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
class RemoveTry {
|
||||
public static void main(String[] args) {
|
||||
try(MyAutoCloseable ac = new MyAutoCloseable()) {
|
||||
if (args.length == 0) {
|
||||
System.out.println("No parameters");
|
||||
} else if (args.length == 1) {
|
||||
System.out.println("One parameter: " + args[0]);
|
||||
} else if (args.length > 1) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
// "Remove redundant 'close()'" "true-preview"
|
||||
|
||||
class MyAutoCloseable implements AutoCloseable {
|
||||
@Override
|
||||
public void close() {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
class RemoveTry {
|
||||
public static void main(String[] args) {
|
||||
try(MyAutoCloseable ac = new MyAutoCloseable()) {
|
||||
System.out.println("Number of parameters?");
|
||||
if (args.length == 0) ac.close<caret>();
|
||||
}
|
||||
}
|
||||
}
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
// "Remove redundant 'close()'" "true-preview"
|
||||
|
||||
class MyAutoCloseable implements AutoCloseable {
|
||||
@Override
|
||||
public void close() {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
class RemoveTry {
|
||||
public static void main(String[] args) {
|
||||
try(MyAutoCloseable ac = new MyAutoCloseable()) {
|
||||
if (args.length == 0) {
|
||||
System.out.println("No parameters");
|
||||
ac.close<caret>();
|
||||
} else if (args.length == 1) {
|
||||
System.out.println("One parameter: " + args[0]);
|
||||
} else if (args.length > 1) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
class MyAutoCloseable implements AutoCloseable {
|
||||
@Override
|
||||
public void close() {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
class C {
|
||||
public static void main(String[] args) {
|
||||
try(MyAutoCloseable ac = new MyAutoCloseable()) {
|
||||
if (args.length == 0) {
|
||||
System.out.println("No parameters");
|
||||
<warning descr="Redundant 'close()'">ac.close();</warning>
|
||||
} else if (args.length == 1) {
|
||||
System.out.println("One parameter: " + args[0]);
|
||||
} else if (args.length > 1) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+1
-2
@@ -6,8 +6,7 @@ import com.intellij.codeInspection.LocalInspectionTool;
|
||||
import com.intellij.codeInspection.RedundantExplicitCloseInspection;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
|
||||
public class RedundantExplicitCloseInspectionTest extends LightQuickFixParameterizedTestCase {
|
||||
public class RedundantExplicitCloseFixTest extends LightQuickFixParameterizedTestCase {
|
||||
@Override
|
||||
protected LocalInspectionTool @NotNull [] configureLocalInspectionTools() {
|
||||
return new LocalInspectionTool[]{
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package com.intellij.java.codeInspection;
|
||||
|
||||
import com.intellij.JavaTestUtil;
|
||||
import com.intellij.codeInspection.InspectionProfileEntry;
|
||||
import com.intellij.codeInspection.RedundantExplicitCloseInspection;
|
||||
import com.siyeh.ig.LightJavaInspectionTestCase;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public class RedundantExplicitCloseInspectionTest extends LightJavaInspectionTestCase {
|
||||
@Override
|
||||
protected String getTestDataPath() {
|
||||
return JavaTestUtil.getJavaTestDataPath() + "/inspection/redundantExplicitClose/";
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
protected InspectionProfileEntry getInspection() {
|
||||
return new RedundantExplicitCloseInspection();
|
||||
}
|
||||
|
||||
public void testRedundantExplicitClose() { doTest(); }
|
||||
}
|
||||
Reference in New Issue
Block a user