method can be void: don't warn on entry points (IDEA-179191)

This commit is contained in:
Anna Kozlova
2017-09-19 11:02:25 +03:00
parent 13d9d3ac7b
commit a0d0315bfa
6 changed files with 63 additions and 23 deletions
@@ -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();
@@ -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 -> {
@@ -0,0 +1,9 @@
class Test {
public String <caret>provider() {
return "";
}
{
provider();
}
}
@@ -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");
@@ -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);
}
@@ -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<String> 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;