IDEA-169223 - added an option to be able to highlight unused parameters apart from hierarchy and quick fix to replace parameter name to "ignored"

GitOrigin-RevId: 4ffc252043c5c1532ec123c146e199e5ce950328
This commit is contained in:
Ilyas Selimov
2021-09-03 14:57:20 +00:00
committed by intellij-monorepo-bot
parent ae7df334bf
commit 4590cb7fea
17 changed files with 288 additions and 28 deletions
@@ -390,7 +390,9 @@ public abstract class QuickFixFactory {
@NotNull
public abstract IntentionAction createOptimizeImportsFix(boolean onTheFly);
public abstract void registerFixesForUnusedParameter(@NotNull PsiParameter parameter, @NotNull Object highlightInfo);
public abstract void registerFixesForUnusedParameter(@NotNull PsiParameter parameter,
@NotNull Object highlightInfo,
boolean excludingHierarchy);
@NotNull
public abstract IntentionAction createAddToDependencyInjectionAnnotationsFix(@NotNull Project project, @NotNull String qualifiedName);
@@ -402,7 +404,7 @@ public abstract class QuickFixFactory {
public abstract IntentionAction createCreateGetterOrSetterFix(boolean createGetter, boolean createSetter, @NotNull PsiField field);
@NotNull
public abstract IntentionAction createRenameToIgnoredFix(@NotNull PsiNamedElement namedElement);
public abstract IntentionAction createRenameToIgnoredFix(@NotNull PsiNamedElement namedElement, boolean useElementNameAsSuffix);
@NotNull
public abstract IntentionAction createEnableOptimizeImportsOnTheFlyFix();
@@ -205,9 +205,18 @@ class PostHighlightingVisitor {
return processField(myProject, (PsiField)parent, identifier, progress, helper);
}
if (parent instanceof PsiParameter) {
final PsiElement declarationScope = ((PsiParameter)parent).getDeclarationScope();
if (declarationScope instanceof PsiMethod ? compareVisibilities((PsiModifierListOwner)declarationScope, myUnusedSymbolInspection.getParameterVisibility())
: myUnusedSymbolInspection.LOCAL_VARIABLE) {
PsiElement declarationScope = ((PsiParameter)parent).getDeclarationScope();
final boolean needToProcessParameter;
if (declarationScope instanceof PsiMethod || declarationScope instanceof PsiLambdaExpression) {
if (declarationScope instanceof PsiLambdaExpression) {
declarationScope = PsiTreeUtil.getParentOfType(declarationScope, PsiModifierListOwner.class);
}
needToProcessParameter = compareVisibilities((PsiModifierListOwner)declarationScope, myUnusedSymbolInspection.getParameterVisibility());
}
else {
needToProcessParameter = myUnusedSymbolInspection.LOCAL_VARIABLE;
}
if (needToProcessParameter) {
if (SuppressionUtil.isSuppressed(identifier, UnusedSymbolLocalInspectionBase.UNUSED_PARAMETERS_SHORT_NAME)) return null;
return processParameter(myProject, (PsiParameter)parent, identifier);
}
@@ -252,7 +261,7 @@ class PostHighlightingVisitor {
IntentionAction fix = null;
if (!myRefCountHolder.isReferenced(variable)) {
message = JavaErrorBundle.message("local.variable.is.never.used", identifier.getText());
fix = variable instanceof PsiResourceVariable ? QuickFixFactory.getInstance().createRenameToIgnoredFix(variable)
fix = variable instanceof PsiResourceVariable ? QuickFixFactory.getInstance().createRenameToIgnoredFix(variable, false)
: QuickFixFactory.getInstance().createRemoveUnusedVariableFix(variable);
}
@@ -379,6 +388,7 @@ class PostHighlightingVisitor {
private HighlightInfo processParameter(@NotNull Project project,
@NotNull PsiParameter parameter,
@NotNull PsiIdentifier identifier) {
if (PsiUtil.isIgnoredName(parameter.getName())) return null;
PsiElement declarationScope = parameter.getDeclarationScope();
if (declarationScope instanceof PsiMethod) {
PsiMethod method = (PsiMethod)declarationScope;
@@ -387,30 +397,32 @@ class PostHighlightingVisitor {
method.hasModifierProperty(PsiModifier.PRIVATE) ||
method.hasModifierProperty(PsiModifier.STATIC) ||
!method.hasModifierProperty(PsiModifier.ABSTRACT) &&
!isOverriddenOrOverrides(method)) &&
(!isOverriddenOrOverrides(method) || myUnusedSymbolInspection.checkParameterExcludingHierarchy())) &&
!method.hasModifierProperty(PsiModifier.NATIVE) &&
!JavaHighlightUtil.isSerializationRelatedMethod(method, method.getContainingClass()) &&
!PsiClassImplUtil.isMainOrPremainMethod(method)) {
if (UnusedSymbolUtil.isInjected(project, method)) return null;
HighlightInfo highlightInfo = checkUnusedParameter(parameter, identifier, method);
if (highlightInfo != null) {
QuickFixFactory.getInstance().registerFixesForUnusedParameter(parameter, highlightInfo);
QuickFixFactory.getInstance()
.registerFixesForUnusedParameter(parameter, highlightInfo, myUnusedSymbolInspection.checkParameterExcludingHierarchy() &&
isOverriddenOrOverrides(method));
return highlightInfo;
}
}
}
else if (declarationScope instanceof PsiForeachStatement && !PsiUtil.isIgnoredName(parameter.getName())) {
else if (declarationScope instanceof PsiForeachStatement) {
HighlightInfo highlightInfo = checkUnusedParameter(parameter, identifier, null);
if (highlightInfo != null) {
QuickFixAction.registerQuickFixAction(highlightInfo, QuickFixFactory.getInstance().createRenameToIgnoredFix(parameter), myDeadCodeKey);
QuickFixAction.registerQuickFixAction(highlightInfo, QuickFixFactory.getInstance().createRenameToIgnoredFix(parameter, false), myDeadCodeKey);
return highlightInfo;
}
}
else if (parameter instanceof PsiPatternVariable && !PsiUtil.isIgnoredName(parameter.getName())) {
else if (parameter instanceof PsiPatternVariable) {
HighlightInfo highlightInfo = checkUnusedParameter(parameter, identifier, null);
if (highlightInfo != null) {
if (parameter.getDeclarationScope().getParent() instanceof PsiSwitchBlock) {
QuickFixAction.registerQuickFixAction(highlightInfo, QuickFixFactory.getInstance().createRenameToIgnoredFix(parameter));
if (declarationScope.getParent() instanceof PsiSwitchBlock) {
QuickFixAction.registerQuickFixAction(highlightInfo, QuickFixFactory.getInstance().createRenameToIgnoredFix(parameter, false));
}
else {
QuickFixAction.registerQuickFixAction(highlightInfo, QuickFixFactory.getInstance().createDeleteFix(parameter));
@@ -418,6 +430,13 @@ class PostHighlightingVisitor {
return highlightInfo;
}
}
else if (myUnusedSymbolInspection.checkParameterExcludingHierarchy() && declarationScope instanceof PsiLambdaExpression) {
HighlightInfo highlightInfo = checkUnusedParameter(parameter, identifier, null);
if (highlightInfo != null) {
QuickFixFactory.getInstance().registerFixesForUnusedParameter(parameter, highlightInfo, true);
return highlightInfo;
}
}
return null;
}
@@ -17,20 +17,39 @@ import com.intellij.psi.PsiManager;
import com.intellij.util.ReflectionUtil;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.util.function.Function;
public class SetInspectionOptionFix implements OnTheFlyLocalFix, LowPriorityAction, Iconable {
private final String myID;
private final String myProperty;
private final @IntentionName String myMessage;
private final boolean myValue;
@Nullable
private final Function<InspectionProfileEntry, InspectionProfileEntry> myExtractor;
public SetInspectionOptionFix(LocalInspectionTool inspection, @NonNls String property, @IntentionName String message, boolean value) {
myID = inspection.getID();
this(inspection.getID(), property, message, value, null);
}
private SetInspectionOptionFix(@NotNull String id, @NonNls String property, @IntentionName String message, boolean value,
@Nullable Function<InspectionProfileEntry, InspectionProfileEntry> extractor) {
myID = id;
myProperty = property;
myMessage = message;
myValue = value;
myExtractor = extractor;
}
/**
* @param extractor may be useful for composed inspections e.g. unused declaration, when you need to unwrap a nested inspection's instance
*/
@NotNull
public static SetInspectionOptionFix createFix(@NotNull String id, @NonNls String property, @IntentionName String message, boolean value,
@NotNull Function<InspectionProfileEntry, InspectionProfileEntry> extractor) {
return new SetInspectionOptionFix(id, property, message, value, extractor);
}
@NotNull
@@ -52,7 +71,11 @@ public class SetInspectionOptionFix implements OnTheFlyLocalFix, LowPriorityActi
@Override
public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) {
VirtualFile vFile = descriptor.getPsiElement().getContainingFile().getVirtualFile();
applyFix(project, descriptor.getPsiElement().getContainingFile());
}
public void applyFix(@NotNull Project project, @NotNull PsiFile psiFile) {
VirtualFile vFile = psiFile.getVirtualFile();
setOption(project, vFile, myValue);
UndoManager.getInstance(project).undoableActionPerformed(new BasicUndoableAction(vFile) {
@Override
@@ -72,8 +95,11 @@ public class SetInspectionOptionFix implements OnTheFlyLocalFix, LowPriorityActi
if (file == null) return;
InspectionProfileModifiableModelKt.modifyAndCommitProjectProfile(project, model -> {
InspectionToolWrapper tool = model.getToolById(myID, file);
if(tool == null) return;
if (tool == null) return;
InspectionProfileEntry inspection = tool.getTool();
if (myExtractor != null) {
inspection = myExtractor.apply(inspection);
}
ReflectionUtil.setField(inspection.getClass(), inspection, boolean.class, myProperty, value);
});
}
@@ -34,7 +34,7 @@ public class UnusedSymbolLocalInspectionBase extends AbstractBaseJavaLocalInspec
protected String myMethodVisibility = PsiModifier.PUBLIC;
protected String myParameterVisibility = PsiModifier.PUBLIC;
private boolean myIgnoreAccessors = false;
protected boolean myCheckParameterExcludingHierarchy = false;
@PsiModifier.ModifierConstant
@Nullable
@@ -62,6 +62,10 @@ public class UnusedSymbolLocalInspectionBase extends AbstractBaseJavaLocalInspec
return myParameterVisibility;
}
public boolean checkParameterExcludingHierarchy() {
return myCheckParameterExcludingHierarchy;
}
@PsiModifier.ModifierConstant
@Nullable
public String getInnerClassVisibility() {
@@ -90,6 +94,10 @@ public class UnusedSymbolLocalInspectionBase extends AbstractBaseJavaLocalInspec
this.myParameterVisibility = parameterVisibility;
}
public void setCheckParameterExcludingHierarchy(boolean checkParameterExcludingHierarchy) {
this.myCheckParameterExcludingHierarchy = checkParameterExcludingHierarchy;
}
public boolean isIgnoreAccessors() {
return myIgnoreAccessors;
}
@@ -142,6 +150,7 @@ public class UnusedSymbolLocalInspectionBase extends AbstractBaseJavaLocalInspec
if (!INNER_CLASS) {
node.setAttribute("INNER_CLASS", Boolean.toString(false));
}
node.setAttribute("checkParameterExcludingHierarchy", Boolean.toString(myCheckParameterExcludingHierarchy));
super.writeSettings(node);
}
@@ -171,9 +180,11 @@ public class UnusedSymbolLocalInspectionBase extends AbstractBaseJavaLocalInspec
myMethodVisibility = readVisibility(node, "method");
myParameterVisibility = readVisibility(node, "parameter", getParameterDefaultVisibility());
final String ignoreAccessors = node.getAttributeValue("ignoreAccessors");
myIgnoreAccessors = ignoreAccessors != null && Boolean.parseBoolean(ignoreAccessors);
myIgnoreAccessors = Boolean.parseBoolean(ignoreAccessors);
final String innerClassEnabled = node.getAttributeValue("INNER_CLASS");
INNER_CLASS = innerClassEnabled == null || Boolean.parseBoolean(innerClassEnabled);
final String checkParameterExcludingHierarchy = node.getAttributeValue("checkParameterExcludingHierarchy");
myCheckParameterExcludingHierarchy = Boolean.parseBoolean(checkParameterExcludingHierarchy);
}
private static String readVisibility(@NotNull Element node, final String type) {
@@ -15,12 +15,29 @@
*/
package com.intellij.codeInsight.daemon.impl.quickfix;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.PsiNamedElement;
import com.intellij.psi.codeStyle.JavaCodeStyleManager;
import org.jetbrains.annotations.NotNull;
public class RenameToIgnoredFix extends RenameElementFix {
public RenameToIgnoredFix(@NotNull PsiNamedElement element) {
super(element, JavaCodeStyleManager.getInstance(element.getProject()).suggestUniqueVariableName("ignored", element, true));
private static final String PREFIX = "ignored";
private RenameToIgnoredFix(@NotNull PsiNamedElement place, @NotNull String suffix) {
super(place, JavaCodeStyleManager.getInstance(place.getProject()).suggestUniqueVariableName(PREFIX + suffix, place, true));
}
/**
* @param useElementNameAsSuffix if true, let the fix suggest the variable name that consists of the "ignored" and name of the element
* e.g. ignoredVar
* <p>if false, let the fix suggest the variable that consists of the "ignored" and some number
* e.g. ignored1
*/
public static RenameToIgnoredFix createRenameToIgnoreFix(@NotNull PsiNamedElement element, boolean useElementNameAsSuffix) {
if (useElementNameAsSuffix) {
String elementName = element.getName();
if (elementName != null) return new RenameToIgnoredFix(element, StringUtil.capitalize(elementName));
}
return new RenameToIgnoredFix(element, "");
}
}
@@ -4,6 +4,7 @@ package com.intellij.codeInsight.intention.impl.config;
import com.intellij.codeInsight.CodeInsightWorkspaceSettings;
import com.intellij.codeInsight.actions.OptimizeImportsProcessor;
import com.intellij.codeInsight.daemon.HighlightDisplayKey;
import com.intellij.codeInsight.daemon.JavaErrorBundle;
import com.intellij.codeInsight.daemon.QuickFixActionRegistrar;
import com.intellij.codeInsight.daemon.QuickFixBundle;
import com.intellij.codeInsight.daemon.impl.*;
@@ -11,6 +12,7 @@ import com.intellij.codeInsight.daemon.impl.analysis.IncreaseLanguageLevelFix;
import com.intellij.codeInsight.daemon.impl.quickfix.*;
import com.intellij.codeInsight.daemon.quickFix.CreateClassOrPackageFix;
import com.intellij.codeInsight.daemon.quickFix.CreateFieldOrPropertyFix;
import com.intellij.codeInsight.intention.AbstractIntentionAction;
import com.intellij.codeInsight.intention.IntentionAction;
import com.intellij.codeInsight.intention.IntentionManager;
import com.intellij.codeInsight.intention.QuickFixFactory;
@@ -18,6 +20,7 @@ import com.intellij.codeInsight.intention.impl.*;
import com.intellij.codeInspection.*;
import com.intellij.codeInspection.actions.UnimplementInterfaceAction;
import com.intellij.codeInspection.dataFlow.fix.DeleteSwitchLabelFix;
import com.intellij.codeInspection.deadCode.UnusedDeclarationInspectionBase;
import com.intellij.codeInspection.ex.EntryPointsManagerBase;
import com.intellij.codeInspection.unusedSymbol.UnusedSymbolLocalInspectionBase;
import com.intellij.codeInspection.util.IntentionName;
@@ -691,7 +694,7 @@ public final class QuickFixFactoryImpl extends QuickFixFactory {
}
@Override
public void registerFixesForUnusedParameter(@NotNull PsiParameter parameter, @NotNull Object highlightInfo) {
public void registerFixesForUnusedParameter(@NotNull PsiParameter parameter, @NotNull Object highlightInfo, boolean excludingHierarchy) {
Project myProject = parameter.getProject();
InspectionProfile profile = InspectionProjectProfileManager.getInstance(myProject).getCurrentProfile();
BatchSuppressableTool unusedParametersInspection = profile.getUnwrappedTool(UnusedSymbolLocalInspectionBase.SHORT_NAME, parameter);
@@ -703,9 +706,35 @@ public final class QuickFixFactoryImpl extends QuickFixFactory {
SuppressQuickFix[] batchSuppressActions = unusedParametersInspection.getBatchSuppressActions(parameter);
Collections.addAll(options, SuppressIntentionActionFromFix.convertBatchToSuppressIntentionActions(batchSuppressActions));
}
//need suppress from Unused Parameters but settings from Unused Symbol
QuickFixAction.registerQuickFixAction((HighlightInfo)highlightInfo, new SafeDeleteFix(parameter),
options, HighlightDisplayKey.getDisplayNameByKey(myUnusedSymbolKey));
HighlightInfo info = (HighlightInfo)highlightInfo;
IntentionAction intentionAction;
if (excludingHierarchy) {
intentionAction = new AbstractIntentionAction() {
@Override
public @NotNull String getText() {
return JavaErrorBundle.message("parameter.excluding.hierarchy.disable.text");
}
@Override
public void invoke(@NotNull Project project, Editor editor, PsiFile file) throws IncorrectOperationException {
SetInspectionOptionFix.createFix(UnusedSymbolLocalInspectionBase.SHORT_NAME,
"myCheckParameterExcludingHierarchy",
JavaErrorBundle.message("parameter.excluding.hierarchy.disable.text"), false,
in -> {
return in instanceof UnusedDeclarationInspectionBase
? ((UnusedDeclarationInspectionBase)in).getSharedLocalInspectionTool()
: in;
})
.applyFix(project, file);
}
};
}
else {
//need suppress from Unused Parameters but settings from Unused Symbol
intentionAction = new SafeDeleteFix(parameter);
}
info.registerFix(intentionAction, options, HighlightDisplayKey.getDisplayNameByKey(myUnusedSymbolKey), null, null);
QuickFixAction.registerQuickFixAction(info, createRenameToIgnoredFix(parameter, true), myUnusedSymbolKey);
}
@NotNull
@@ -734,8 +763,8 @@ public final class QuickFixFactoryImpl extends QuickFixFactory {
@NotNull
@Override
public IntentionAction createRenameToIgnoredFix(@NotNull PsiNamedElement namedElement) {
return new RenameToIgnoredFix(namedElement);
public IntentionAction createRenameToIgnoredFix(@NotNull PsiNamedElement namedElement, boolean useElementNameAsSuffix) {
return RenameToIgnoredFix.createRenameToIgnoreFix(namedElement, useElementNameAsSuffix);
}
@NotNull
@@ -169,6 +169,15 @@
</constraints>
<properties/>
</component>
<component id="a82ad" class="javax.swing.JCheckBox" binding="myCheckParameterExcludingHierarchyCheckBox">
<constraints>
<grid row="0" column="3" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
<gridbag weightx="0.0" weighty="0.0"/>
</constraints>
<properties>
<text resource-bundle="messages/JavaBundle" key="inspection.unused.symbol.check.parameters.excluding.hierarchy"/>
</properties>
</component>
</children>
</grid>
</children>
@@ -45,6 +45,7 @@ public class UnusedSymbolLocalInspection extends UnusedSymbolLocalInspectionBase
private JLabel myFieldVisibilityCb;
private JLabel myMethodVisibilityCb;
private JLabel myMethodParameterVisibilityCb;
private JCheckBox myCheckParameterExcludingHierarchyCheckBox;
private JCheckBox myInnerClassesCheckBox;
private JLabel myInnerClassVisibilityCb;
@@ -55,6 +56,7 @@ public class UnusedSymbolLocalInspection extends UnusedSymbolLocalInspectionBase
myCheckMethodsCheckBox.setSelected(METHOD);
myInnerClassesCheckBox.setSelected(INNER_CLASS);
myCheckParametersCheckBox.setSelected(PARAMETER);
myCheckParameterExcludingHierarchyCheckBox.setSelected(myCheckParameterExcludingHierarchy);
myAccessors.setSelected(!isIgnoreAccessors());
updateEnableState();
@@ -68,6 +70,7 @@ public class UnusedSymbolLocalInspection extends UnusedSymbolLocalInspectionBase
METHOD = myCheckMethodsCheckBox.isSelected();
setIgnoreAccessors(!myAccessors.isSelected());
PARAMETER = myCheckParametersCheckBox.isSelected();
setCheckParameterExcludingHierarchy(myCheckParameterExcludingHierarchyCheckBox.isSelected());
updateEnableState();
}
@@ -77,6 +80,7 @@ public class UnusedSymbolLocalInspection extends UnusedSymbolLocalInspectionBase
myCheckMethodsCheckBox.addActionListener(listener);
myCheckClassesCheckBox.addActionListener(listener);
myCheckParametersCheckBox.addActionListener(listener);
myCheckParameterExcludingHierarchyCheckBox.addActionListener(listener);
myInnerClassesCheckBox.addActionListener(listener);
myAccessors.addActionListener(listener);
}
@@ -87,6 +91,7 @@ public class UnusedSymbolLocalInspection extends UnusedSymbolLocalInspectionBase
UIUtil.setEnabled(myFieldVisibilityCb, FIELD, true);
UIUtil.setEnabled(myMethodVisibilityCb, METHOD, true);
UIUtil.setEnabled(myMethodParameterVisibilityCb, PARAMETER, true);
setEnabledExcludingHierarchyCheckbox(getParameterVisibility());
myAccessors.setEnabled(METHOD);
}
@@ -114,7 +119,10 @@ public class UnusedSymbolLocalInspection extends UnusedSymbolLocalInspectionBase
myMethodParameterVisibilityCb = new VisibilityModifierChooser(() -> PARAMETER,
myParameterVisibility,
modifier -> setParameterVisibility(modifier));
modifier -> {
setParameterVisibility(modifier);
setEnabledExcludingHierarchyCheckbox(modifier);
});
myAccessors = new JCheckBox() {
@Override
@@ -123,6 +131,10 @@ public class UnusedSymbolLocalInspection extends UnusedSymbolLocalInspectionBase
}
};
}
private void setEnabledExcludingHierarchyCheckbox(@Nullable String modifier) {
myCheckParameterExcludingHierarchyCheckBox.setVisible(!PsiModifier.PRIVATE.equals(modifier));
}
}
@Override
@@ -49,7 +49,7 @@ public final class PsiUtil extends PsiUtilCore {
public static final int ACCESS_LEVEL_PRIVATE = 1;
public static final Key<Boolean> VALID_VOID_TYPE_IN_CODE_FRAGMENT = Key.create("VALID_VOID_TYPE_IN_CODE_FRAGMENT");
private static final Pattern IGNORED_NAMES = Pattern.compile("ignored?\\d*");
private static final Pattern IGNORED_NAMES = Pattern.compile("ignored?[A-Z]?[a-z]*\\d*");
private PsiUtil() {}
@@ -298,6 +298,7 @@ field.is.not.used=Field ''{0}'' is never used
field.is.not.used.for.reading={0} field ''{1}'' is assigned but never accessed
private.field.is.not.assigned=Private field ''{0}'' is never assigned
parameter.is.not.used=Parameter ''{0}'' is never used
parameter.excluding.hierarchy.disable.text=Do not highlight parameters for inherited methods
pattern.variable.is.not.used=Pattern variable ''{0}'' is never used
private.method.is.not.used=Private method ''{0}'' is never used
method.is.not.used=Method ''{0}'' is never used
@@ -0,0 +1,14 @@
class Test {
public static void main(String[] args) {
I i2 = new I() {
@Override
public void foo(int <warning descr="Parameter 'p' is never used"><caret>p</warning>) {
}
};
System.out.println(i2);
}
}
interface I {
void foo(int i);
}
@@ -0,0 +1,10 @@
class Test {
public static void main(String[] args) {
I i1 = <warning descr="Parameter 'p' is never used"><caret>p</warning> -> System.out.println();
System.out.println(i1);
}
}
interface I {
void foo(int i);
}
@@ -0,0 +1,9 @@
interface I {
void foo(int i);
}
class A implements I {
@Override
public void foo(int <warning descr="Parameter 'p' is never used"><caret>p</warning>) {
}
}
@@ -0,0 +1,4 @@
class Test {
void bar(int <warning descr="Parameter 'p' is never used"><caret>p</warning>) {
}
}
@@ -0,0 +1,28 @@
class Test {
public static void main(String[] args) {
I i1 = p -> System.out.println();
System.out.println(i1);
I i2 = new I() {
@Override
public void foo(int p) {
}
};
System.out.println(i2);
}
static void foo(int <warning descr="Parameter 'i' is never used">i</warning>) {
}
public void bar(int <warning descr="Parameter 'i' is never used">i</warning>) {
}
}
interface I {
void foo(int i);
}
class A implements I {
@Override
public void foo(int i) {
}
}
@@ -0,0 +1,68 @@
// Copyright 2000-2021 JetBrains s.r.o. and contributors. 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;
import com.intellij.JavaTestUtil;
import com.intellij.codeInspection.deadCode.UnusedDeclarationInspection;
import com.intellij.testFramework.LightProjectDescriptor;
import com.intellij.testFramework.fixtures.LightJavaCodeInsightFixtureTestCase;
import org.jetbrains.annotations.NotNull;
public class UnusedParameterInHierarchyTest extends LightJavaCodeInsightFixtureTestCase {
private UnusedDeclarationInspection inspection;
@Override
protected String getBasePath() {
return JavaTestUtil.getRelativeJavaTestDataPath() + "/codeInsight/daemonCodeAnalyzer/unusedParameterInHierarchy";
}
@NotNull
@Override
protected LightProjectDescriptor getProjectDescriptor() {
return JAVA_16;
}
@Override
protected void setUp() throws Exception {
super.setUp();
inspection = new UnusedDeclarationInspection();
myFixture.enableInspections(inspection);
}
public void testExcludingHierarchyInAnonymousClass() {
inspection.getSharedLocalInspectionTool().setCheckParameterExcludingHierarchy(true);
doTest();
assertNotNull(myFixture.getAvailableIntention("Rename 'p' to 'ignoredP'"));
assertNotNull(myFixture.getAvailableIntention("Do not highlight parameters for inherited methods"));
}
public void testExcludingHierarchyInLambda() {
inspection.getSharedLocalInspectionTool().setCheckParameterExcludingHierarchy(true);
doTest();
assertNotNull(myFixture.getAvailableIntention("Rename 'p' to 'ignoredP'"));
assertNotNull(myFixture.getAvailableIntention("Do not highlight parameters for inherited methods"));
}
public void testExcludingHierarchyInOverriddenMethod() {
inspection.getSharedLocalInspectionTool().setCheckParameterExcludingHierarchy(true);
doTest();
assertNotNull(myFixture.getAvailableIntention("Rename 'p' to 'ignoredP'"));
assertNotNull(myFixture.getAvailableIntention("Do not highlight parameters for inherited methods"));
}
public void testExcludingHierarchyInPlainMethod() {
inspection.getSharedLocalInspectionTool().setCheckParameterExcludingHierarchy(true);
doTest();
assertNotNull(myFixture.getAvailableIntention("Rename 'p' to 'ignoredP'"));
assertNull(myFixture.getAvailableIntention("Do not highlight parameters for inherited methods"));
}
public void testIncludingHierarchy() {
inspection.getSharedLocalInspectionTool().setCheckParameterExcludingHierarchy(false);
doTest();
}
private void doTest() {
myFixture.configureByFile(getTestName(false) + ".java");
myFixture.checkHighlighting();
}
}
@@ -740,6 +740,7 @@ inspection.unused.symbol.check.inner.classes=Inner classes:
inspection.unused.symbol.check.localvars=Local variables
inspection.unused.symbol.check.methods=Methods:
inspection.unused.symbol.check.parameters=Parameters in
inspection.unused.symbol.check.parameters.excluding.hierarchy=Excluding hierarchy
inspection.value.based.warnings=Value-based warnings
inspection.preview.feature=Preview Feature warning
inspection.value.based.warnings.synchronization=Attempt to synchronize on an instance of a value-based class