From a0d0315bfafe3584e0496ffc38b9120ff89c187f Mon Sep 17 00:00:00 2001 From: Anna Kozlova Date: Tue, 19 Sep 2017 10:56:06 +0300 Subject: [PATCH] method can be void: don't warn on entry points (IDEA-179191) --- .../unusedReturnValue/UnusedReturnValue.java | 2 +- .../UnusedReturnValueLocalInspection.java | 5 ++- .../quickFix/NoChangeForEntryPoint.java | 9 ++++ .../UnusedReturnValueQuickFixTest.java | 45 +++++++++++++++++++ .../codeInspection/ex/EntryPointsManager.java | 5 ++- .../junit/JUnitExternalLibraryDescriptor.java | 20 +-------- 6 files changed, 63 insertions(+), 23 deletions(-) create mode 100644 java/java-tests/testData/inspection/unusedReturnValue/quickFix/NoChangeForEntryPoint.java diff --git a/java/java-impl/src/com/intellij/codeInspection/unusedReturnValue/UnusedReturnValue.java b/java/java-impl/src/com/intellij/codeInspection/unusedReturnValue/UnusedReturnValue.java index fe32c0f5f132..7e0b701d20db 100644 --- a/java/java-impl/src/com/intellij/codeInspection/unusedReturnValue/UnusedReturnValue.java +++ b/java/java-impl/src/com/intellij/codeInspection/unusedReturnValue/UnusedReturnValue.java @@ -24,7 +24,6 @@ import com.intellij.openapi.util.WriteExternalException; import com.intellij.psi.PsiMethod; import com.intellij.psi.PsiModifier; import com.intellij.psi.PsiReference; -import com.intellij.psi.util.PropertyUtil; import com.intellij.psi.util.PropertyUtilBase; import org.jdom.Element; import org.jetbrains.annotations.NotNull; @@ -51,6 +50,7 @@ public class UnusedReturnValue extends GlobalJavaBatchInspectionTool{ if (refMethod.isConstructor()) return null; if (!refMethod.getSuperMethods().isEmpty()) return null; if (refMethod.getInReferences().size() == 0) return null; + if (refMethod.isEntry()) return null; if (!refMethod.isReturnValueUsed()) { final PsiMethod psiMethod = (PsiMethod)refMethod.getElement(); diff --git a/java/java-impl/src/com/intellij/codeInspection/unusedReturnValue/UnusedReturnValueLocalInspection.java b/java/java-impl/src/com/intellij/codeInspection/unusedReturnValue/UnusedReturnValueLocalInspection.java index 7ec7cffee589..f5bded52eb0f 100644 --- a/java/java-impl/src/com/intellij/codeInspection/unusedReturnValue/UnusedReturnValueLocalInspection.java +++ b/java/java-impl/src/com/intellij/codeInspection/unusedReturnValue/UnusedReturnValueLocalInspection.java @@ -19,11 +19,11 @@ import com.intellij.codeInsight.daemon.impl.UnusedSymbolUtil; import com.intellij.codeInspection.BaseJavaLocalInspectionTool; import com.intellij.codeInspection.InspectionManager; import com.intellij.codeInspection.ProblemDescriptor; +import com.intellij.codeInspection.deadCode.UnusedDeclarationInspectionBase; import com.intellij.codeInspection.reference.RefUtil; import com.intellij.openapi.progress.EmptyProgressIndicator; import com.intellij.patterns.PsiJavaPatterns; import com.intellij.psi.*; -import com.intellij.psi.util.PropertyUtil; import com.intellij.psi.util.PropertyUtilBase; import com.siyeh.ig.psiutils.MethodUtils; import org.jetbrains.annotations.NotNull; @@ -65,7 +65,8 @@ public class UnusedReturnValueLocalInspection extends BaseJavaLocalInspectionToo myGlobal.IGNORE_BUILDER_PATTERN && PropertyUtilBase.isSimplePropertySetter(method) || method.hasModifierProperty(PsiModifier.NATIVE) || MethodUtils.hasSuper(method) || - RefUtil.isImplicitRead(method)) return null; + RefUtil.isImplicitRead(method) || + UnusedDeclarationInspectionBase.findUnusedDeclarationInspection(method).isEntryPoint(method)) return null; final boolean[] atLeastOneUsageExists = new boolean[]{false}; if (UnusedSymbolUtil.processUsages(manager.getProject(), method.getContainingFile(), method, new EmptyProgressIndicator(), null, u -> { diff --git a/java/java-tests/testData/inspection/unusedReturnValue/quickFix/NoChangeForEntryPoint.java b/java/java-tests/testData/inspection/unusedReturnValue/quickFix/NoChangeForEntryPoint.java new file mode 100644 index 000000000000..200bd61c0f3e --- /dev/null +++ b/java/java-tests/testData/inspection/unusedReturnValue/quickFix/NoChangeForEntryPoint.java @@ -0,0 +1,9 @@ +class Test { + public String provider() { + return ""; + } + + { + provider(); + } +} \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/java/codeInspection/UnusedReturnValueQuickFixTest.java b/java/java-tests/testSrc/com/intellij/java/codeInspection/UnusedReturnValueQuickFixTest.java index 9bbe5e8c0478..52e30291c23a 100644 --- a/java/java-tests/testSrc/com/intellij/java/codeInspection/UnusedReturnValueQuickFixTest.java +++ b/java/java-tests/testSrc/com/intellij/java/codeInspection/UnusedReturnValueQuickFixTest.java @@ -16,14 +16,22 @@ package com.intellij.java.codeInspection; import com.intellij.JavaTestUtil; +import com.intellij.ToolExtensionPoints; import com.intellij.codeInsight.daemon.ImplicitUsageProvider; import com.intellij.codeInspection.InspectionsBundle; +import com.intellij.codeInspection.reference.EntryPoint; +import com.intellij.codeInspection.reference.RefElement; import com.intellij.codeInspection.unusedReturnValue.UnusedReturnValue; +import com.intellij.openapi.extensions.ExtensionPointName; import com.intellij.openapi.extensions.Extensions; +import com.intellij.openapi.util.InvalidDataException; +import com.intellij.openapi.util.WriteExternalException; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiMethod; import com.intellij.testFramework.PlatformTestUtil; import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase; +import org.jdom.Element; +import org.jetbrains.annotations.NotNull; /** * @author Bas Leijdekkers @@ -49,6 +57,37 @@ public class UnusedReturnValueQuickFixTest extends LightCodeInsightFixtureTestCa return false; } }, getTestRootDisposable()); + PlatformTestUtil.registerExtension(Extensions.getRootArea(), ExtensionPointName.create(ToolExtensionPoints.DEAD_CODE_TOOL), new EntryPoint() { + @Override + public void readExternal(Element element) throws InvalidDataException { } + + @Override + public void writeExternal(Element element) throws WriteExternalException { } + + @NotNull + @Override + public String getDisplayName() { + return "return value used"; + } + + @Override + public boolean isEntryPoint(@NotNull RefElement refElement, @NotNull PsiElement psiElement) { + return isEntryPoint(psiElement); + } + + @Override + public boolean isEntryPoint(@NotNull PsiElement psiElement) { + return psiElement instanceof PsiMethod && "provider".equals(((PsiMethod)psiElement).getName()); + } + + @Override + public boolean isSelected() { + return true; + } + + @Override + public void setSelected(boolean selected) { } + }, getTestRootDisposable()); myFixture.enableInspections(new UnusedReturnValue()); } @@ -63,6 +102,12 @@ public class UnusedReturnValueQuickFixTest extends LightCodeInsightFixtureTestCa assertEmpty(myFixture.filterAvailableIntentions(InspectionsBundle.message("inspection.unused.return.value.make.void.quickfix"))); } + public void testNoChangeForEntryPoint() { + final String name = getTestName(false); + myFixture.configureByFile(name + ".java"); + assertEmpty(myFixture.filterAvailableIntentions(InspectionsBundle.message("inspection.unused.return.value.make.void.quickfix"))); + } + private void doTest() { final String name = getTestName(false); myFixture.configureByFile(name + ".java"); diff --git a/platform/analysis-api/src/com/intellij/codeInspection/ex/EntryPointsManager.java b/platform/analysis-api/src/com/intellij/codeInspection/ex/EntryPointsManager.java index 2d0387d9b708..2bd27ccf180f 100644 --- a/platform/analysis-api/src/com/intellij/codeInspection/ex/EntryPointsManager.java +++ b/platform/analysis-api/src/com/intellij/codeInspection/ex/EntryPointsManager.java @@ -29,8 +29,6 @@ import com.intellij.psi.PsiElement; import org.jetbrains.annotations.NotNull; import javax.swing.*; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; public abstract class EntryPointsManager implements Disposable { public static EntryPointsManager getInstance(Project project) { @@ -60,5 +58,8 @@ public abstract class EntryPointsManager implements Disposable { public abstract boolean isEntryPoint(@NotNull PsiElement element); + /** + * Returns {@code true} for fields, annotated with "write" annotations + */ public abstract boolean isImplicitWrite(PsiElement element); } diff --git a/plugins/junit/src/com/intellij/execution/junit/JUnitExternalLibraryDescriptor.java b/plugins/junit/src/com/intellij/execution/junit/JUnitExternalLibraryDescriptor.java index efb8e13b1100..c092ef87c06f 100644 --- a/plugins/junit/src/com/intellij/execution/junit/JUnitExternalLibraryDescriptor.java +++ b/plugins/junit/src/com/intellij/execution/junit/JUnitExternalLibraryDescriptor.java @@ -18,14 +18,10 @@ package com.intellij.execution.junit; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.projectRoots.ex.JavaSdkUtil; import com.intellij.openapi.roots.ExternalLibraryDescriptor; -import com.intellij.util.PathUtil; import org.jetbrains.annotations.NotNull; import java.util.Collections; import java.util.List; -import java.util.Objects; -import java.util.stream.Collectors; -import java.util.stream.Stream; /** * @author nik @@ -46,23 +42,11 @@ public abstract class JUnitExternalLibraryDescriptor extends ExternalLibraryDesc return JavaSdkUtil.getJUnit4JarPaths(); } }; - public static final ExternalLibraryDescriptor JUNIT5 = new JUnitExternalLibraryDescriptor("org.junit.jupiter", "junit-jupiter-api", "5") { + public static final ExternalLibraryDescriptor JUNIT5 = new JUnitExternalLibraryDescriptor("org.junit.jupiter", "junit-jupiter-api", "5.0.0") { @NotNull @Override public List getLibraryClassesRoots() { - return Stream.of("org.junit.jupiter.api.Test", "org.opentest4j.AssertionFailedError", - "org.apiguardian.api.API", "org.junit.platform.commons.JUnitException") - .map(className -> { - try { - return PathUtil.getJarPathForClass(Class.forName(className)); - } - catch (ClassNotFoundException e) { - LOG.info(e); - } - return null; - }) - .filter(Objects::nonNull) - .collect(Collectors.toList()); + return Collections.emptyList(); } }; private final String myVersion;