mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-18 09:34:34 +07:00
RedundantExplicitCloseInspection created: IDEA-176630
This commit is contained in:
@@ -532,6 +532,12 @@
|
||||
groupKey="group.names.code.style.issues" enabledByDefault="true" level="WARNING"
|
||||
implementationClass="com.intellij.codeInspection.OptionalIsPresentInspection"
|
||||
displayName="Replace Optional.isPresent() checks with functional-style expressions"/>
|
||||
<localInspection groupPath="Java" language="JAVA" shortName="RedundantExplicitClose"
|
||||
groupBundle="messages.InspectionsBundle"
|
||||
groupKey="group.names.declaration.redundancy" enabledByDefault="true" level="WARNING"
|
||||
bundle="messages.InspectionsBundle"
|
||||
key="inspection.redundant.explicit.close"
|
||||
implementationClass="com.intellij.codeInspection.RedundantExplicitCloseInspection"/>
|
||||
<localInspection groupPath="Java" language="JAVA" shortName="RedundantLambdaParameterType"
|
||||
groupBundle="messages.InspectionsBundle"
|
||||
groupKey="group.names.declaration.redundancy" enabledByDefault="true" level="INFORMATION"
|
||||
|
||||
@@ -0,0 +1,72 @@
|
||||
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package com.intellij.codeInspection;
|
||||
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.psi.*;
|
||||
import com.siyeh.ig.callMatcher.CallMatcher;
|
||||
import com.siyeh.ig.psiutils.CommentTracker;
|
||||
import one.util.streamex.StreamEx;
|
||||
import org.jetbrains.annotations.Nls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import static com.intellij.util.ObjectUtils.tryCast;
|
||||
|
||||
public class RedundantExplicitCloseInspection extends AbstractBaseJavaLocalInspectionTool {
|
||||
CallMatcher CLOSE = CallMatcher.instanceCall(CommonClassNames.JAVA_LANG_AUTO_CLOSEABLE, "close").parameterCount(0);
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public PsiElementVisitor buildVisitor(@NotNull ProblemsHolder holder, boolean isOnTheFly) {
|
||||
return new JavaElementVisitor() {
|
||||
@Override
|
||||
public void visitTryStatement(PsiTryStatement statement) {
|
||||
PsiResourceList resourceList = statement.getResourceList();
|
||||
if (resourceList == null) return;
|
||||
|
||||
PsiCodeBlock tryBlock = statement.getTryBlock();
|
||||
if (tryBlock == null) return;
|
||||
PsiStatement[] statements = tryBlock.getStatements();
|
||||
if(statements.length == 0) return;
|
||||
PsiStatement last = statements[statements.length - 1];
|
||||
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);
|
||||
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;
|
||||
}
|
||||
});
|
||||
if(!isReferenceToResourceVariable) return;
|
||||
holder.registerProblem(last, InspectionsBundle.message("inspection.redundant.explicit.close"),
|
||||
ProblemHighlightType.LIKE_UNUSED_SYMBOL, new DeleteRedundantCloseFix());
|
||||
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private static class DeleteRedundantCloseFix implements LocalQuickFix {
|
||||
@Nls
|
||||
@NotNull
|
||||
@Override
|
||||
public String getFamilyName() {
|
||||
return InspectionsBundle.message("inspection.redundant.explicit.close.fix.name");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) {
|
||||
PsiElement element = descriptor.getStartElement();
|
||||
new CommentTracker().deleteAndRestoreComments(element);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
<html>
|
||||
<body>
|
||||
Inspection reports unnecessary close of resource in the end of try-with-resources block
|
||||
<!-- tooltip end -->
|
||||
<small>New in 2018.1</small>
|
||||
</body>
|
||||
</html>
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
// "Remove redundant close" "true"
|
||||
|
||||
class MyAutoCloseable implements AutoCloseable {
|
||||
@Override
|
||||
void close() {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
class RemoveTry {
|
||||
public static void main(String[] args) {
|
||||
try(MyAutoCloseable ac = new MyAutoCloseable()) {
|
||||
System.out.println("asdasd");
|
||||
}
|
||||
}
|
||||
}
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
// "Remove redundant close" "true"
|
||||
|
||||
class MyAutoCloseable implements AutoCloseable {
|
||||
@Override
|
||||
void close() {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
class RemoveTry {
|
||||
public static void main(String[] args) {
|
||||
try(MyAutoCloseable ac = new MyAutoCloseable()) {
|
||||
System.out.println("asdasd");
|
||||
ac.close<caret>();
|
||||
}
|
||||
}
|
||||
}
|
||||
+31
@@ -0,0 +1,31 @@
|
||||
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package com.intellij.java.codeInsight.daemon.quickFix;
|
||||
|
||||
import com.intellij.codeInsight.daemon.quickFix.LightQuickFixParameterizedTestCase;
|
||||
import com.intellij.codeInspection.LocalInspectionTool;
|
||||
import com.intellij.codeInspection.OptionalIsPresentInspection;
|
||||
import com.intellij.codeInspection.RedundantExplicitCloseInspection;
|
||||
import com.intellij.openapi.projectRoots.Sdk;
|
||||
import com.intellij.testFramework.IdeaTestUtil;
|
||||
import com.intellij.testFramework.LightProjectDescriptor;
|
||||
import com.intellij.testFramework.PsiTestUtil;
|
||||
import com.intellij.testFramework.fixtures.DefaultLightProjectDescriptor;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
|
||||
public class RedundantExplicitCloseInspectionTest extends LightQuickFixParameterizedTestCase {
|
||||
@NotNull
|
||||
@Override
|
||||
protected LocalInspectionTool[] configureLocalInspectionTools() {
|
||||
return new LocalInspectionTool[]{
|
||||
new RedundantExplicitCloseInspection()
|
||||
};
|
||||
}
|
||||
|
||||
public void test() { doAllTests(); }
|
||||
|
||||
@Override
|
||||
protected String getBasePath() {
|
||||
return "/codeInsight/daemonCodeAnalyzer/quickFix/redundantExplicitClose";
|
||||
}
|
||||
}
|
||||
@@ -943,4 +943,7 @@ inspection.endless.stream.description=Non-short-circuit operation consumes the i
|
||||
inspection.redundant.comparator.comparing.display.name=Redundant Comparator.comparing
|
||||
|
||||
inspection.capturing.cleaner=Runnable passed to Cleaner.register() captures ''{0}'' reference
|
||||
inspection.capturing.cleaner.description=Cleaner captures object reference
|
||||
inspection.capturing.cleaner.description=Cleaner captures object reference
|
||||
|
||||
inspection.redundant.explicit.close=Redundant close
|
||||
inspection.redundant.explicit.close.fix.name=Remove redundant close
|
||||
Reference in New Issue
Block a user