From 4b0cf1bf1f9b6f9d4d010f4988938fa2fdb2f964 Mon Sep 17 00:00:00 2001 From: Dmitry Batkovich Date: Wed, 5 Sep 2018 16:29:42 +0300 Subject: [PATCH] same parameter value: introduce an option for minimal usage count --- .../reference/RefParameter.java | 4 +++ .../reference/RefParameterImpl.java | 8 ++++- .../SameParameterValueInspection.java | 30 ++++++++++++++++--- .../usageCount/expected.xml | 10 +++++++ .../usageCount/src/Test.java | 23 ++++++++++++++ .../SameParameterValueLocalTest.java | 11 +++++++ .../SameParameterValueTest.java | 11 +++++++ 7 files changed, 92 insertions(+), 5 deletions(-) create mode 100644 java/java-tests/testData/inspection/sameParameterValue/usageCount/expected.xml create mode 100644 java/java-tests/testData/inspection/sameParameterValue/usageCount/src/Test.java diff --git a/java/java-analysis-api/src/com/intellij/codeInspection/reference/RefParameter.java b/java/java-analysis-api/src/com/intellij/codeInspection/reference/RefParameter.java index 7db8c53466c2..d297aa26afa5 100644 --- a/java/java-analysis-api/src/com/intellij/codeInspection/reference/RefParameter.java +++ b/java/java-analysis-api/src/com/intellij/codeInspection/reference/RefParameter.java @@ -68,4 +68,8 @@ public interface RefParameter extends RefJavaElement { @Override PsiParameter getElement(); + + default int getUsageCount() { + throw new UnsupportedOperationException(); + } } diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/reference/RefParameterImpl.java b/java/java-analysis-impl/src/com/intellij/codeInspection/reference/RefParameterImpl.java index 7f7a9b54522d..312508115b69 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInspection/reference/RefParameterImpl.java +++ b/java/java-analysis-impl/src/com/intellij/codeInspection/reference/RefParameterImpl.java @@ -17,9 +17,9 @@ public class RefParameterImpl extends RefJavaElementImpl implements RefParameter private static final int USED_FOR_READING_MASK = 0x10000; private static final int USED_FOR_WRITING_MASK = 0x20000; - private final short myIndex; private Object myActualValueTemplate; + private int myUsageCount; RefParameterImpl(PsiParameter parameter, int index, RefManager manager) { super(parameter, manager); @@ -55,6 +55,11 @@ public class RefParameterImpl extends RefJavaElementImpl implements RefParameter return (PsiParameter)super.getElement(); } + @Override + public int getUsageCount() { + return myUsageCount; + } + @Override public boolean isUsedForWriting() { return checkFlag(USED_FOR_WRITING_MASK); @@ -92,6 +97,7 @@ public class RefParameterImpl extends RefJavaElementImpl implements RefParameter } void updateTemplateValue(PsiExpression expression, @Nullable PsiElement accessPlace) { + myUsageCount++; if (myActualValueTemplate == VALUE_IS_NOT_CONST) return; Object newTemplate = getAccessibleExpressionValue(expression, () -> accessPlace == null ? getContainingFile() : accessPlace); diff --git a/java/java-impl/src/com/intellij/codeInspection/sameParameterValue/SameParameterValueInspection.java b/java/java-impl/src/com/intellij/codeInspection/sameParameterValue/SameParameterValueInspection.java index 0ab6d7cfb782..c165bc48c752 100644 --- a/java/java-impl/src/com/intellij/codeInspection/sameParameterValue/SameParameterValueInspection.java +++ b/java/java-impl/src/com/intellij/codeInspection/sameParameterValue/SameParameterValueInspection.java @@ -30,6 +30,10 @@ import com.intellij.refactoring.safeDelete.JavaSafeDeleteProcessor; import com.intellij.refactoring.ui.ConflictsDialog; import com.intellij.refactoring.util.CommonRefactoringUtil; import com.intellij.refactoring.util.InlineUtil; +import com.intellij.ui.components.JBCheckBox; +import com.intellij.ui.components.fields.IntegerField; +import com.intellij.ui.components.fields.valueEditors.IntegerValueEditor; +import com.intellij.ui.components.fields.valueEditors.ValueEditor; import com.intellij.util.IncorrectOperationException; import com.intellij.util.ObjectUtils; import com.intellij.util.VisibilityUtil; @@ -39,6 +43,8 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import javax.swing.*; +import javax.swing.event.ChangeEvent; +import javax.swing.event.ChangeListener; import java.awt.*; import java.util.List; import java.util.*; @@ -55,18 +61,31 @@ public class SameParameterValueInspection extends GlobalJavaBatchInspectionTool private static final String DEFAULT_HIGHEST_MODIFIER = PsiModifier.PROTECTED; @PsiModifier.ModifierConstant public String highestModifier = DEFAULT_HIGHEST_MODIFIER; + public int minimalUsageCount = 1; @Nullable @Override public JComponent createOptionsPanel() { + JPanel panel = new JPanel(new GridBagLayout()); LabeledComponent component = LabeledComponent.create(new VisibilityModifierChooser(() -> true, highestModifier, (newModifier) -> highestModifier = newModifier), - "Methods to report:", + "Minimal reported method visibility:", BorderLayout.WEST); + panel.add(component, new GridBagConstraints(0, 0, 1, 1, 1.0, 0.0, GridBagConstraints.FIRST_LINE_START, GridBagConstraints.NONE, JBUI.emptyInsets(), 0, 0)); - JPanel panel = new JPanel(new GridBagLayout()); - panel.add(component, new GridBagConstraints(0, 0, 1, 1, 1.0, 1.0, GridBagConstraints.FIRST_LINE_START, GridBagConstraints.NORTHEAST, JBUI.emptyInsets(), 0, 0)); + + IntegerField minimalUsageCountEditor = new IntegerField(null, 1, Integer.MAX_VALUE); + minimalUsageCountEditor.getValueEditor().addListener(new ValueEditor.Listener() { + @Override + public void valueChanged(@NotNull Integer newValue) { + minimalUsageCount = newValue; + } + }); + minimalUsageCountEditor.setValue(minimalUsageCount); + minimalUsageCountEditor.setColumns(4); + panel.add(LabeledComponent.create(minimalUsageCountEditor, "Minimal reported method usage count:", BorderLayout.WEST), + new GridBagConstraints(0, 1, 1, 1, 1.0, 1.0, GridBagConstraints.FIRST_LINE_START, GridBagConstraints.NORTHWEST, JBUI.emptyInsets(), 0, 0)); return panel; } @@ -94,6 +113,7 @@ public class SameParameterValueInspection extends GlobalJavaBatchInspectionTool for (RefParameter refParameter : parameters) { Object value = refParameter.getActualConstValue(); if (value != VALUE_IS_NOT_CONST && value != VALUE_UNDEFINED) { + if (minimalUsageCount != 0 && refParameter.getUsageCount() < minimalUsageCount) continue; if (!globalContext.shouldCheck(refParameter, this)) continue; if (problems == null) problems = new ArrayList<>(1); problems.add(registerProblem(manager, refParameter.getElement(), value, refParameter.isUsedForWriting())); @@ -412,10 +432,11 @@ public class SameParameterValueInspection extends GlobalJavaBatchInspectionTool } Arrays.fill(paramValues, VALUE_UNDEFINED); + int[] usageCount = {0}; if (UnusedSymbolUtil .processUsages(holder.getProject(), method.getContainingFile(), method, new EmptyProgressIndicator(), null, info -> { PsiElement element = info.getElement(); - + usageCount[0]++; if (!(element instanceof PsiReferenceExpression)) { return false; } @@ -447,6 +468,7 @@ public class SameParameterValueInspection extends GlobalJavaBatchInspectionTool return needFurtherProcess; })) { + if (minimalUsageCount != 0 && usageCount[0] < minimalUsageCount) return; for (int i = 0, length = paramValues.length; i < length; i++) { Object value = paramValues[i]; if (value != VALUE_UNDEFINED && value != VALUE_IS_NOT_CONST) { diff --git a/java/java-tests/testData/inspection/sameParameterValue/usageCount/expected.xml b/java/java-tests/testData/inspection/sameParameterValue/usageCount/expected.xml new file mode 100644 index 000000000000..a505578e83c6 --- /dev/null +++ b/java/java-tests/testData/inspection/sameParameterValue/usageCount/expected.xml @@ -0,0 +1,10 @@ + + + + Test.java + 16 + Actual method parameter is the same constant + Actual value of parameter 'val' is always '239' + + + diff --git a/java/java-tests/testData/inspection/sameParameterValue/usageCount/src/Test.java b/java/java-tests/testData/inspection/sameParameterValue/usageCount/src/Test.java new file mode 100644 index 000000000000..deeb361ef721 --- /dev/null +++ b/java/java-tests/testData/inspection/sameParameterValue/usageCount/src/Test.java @@ -0,0 +1,23 @@ +public class Main { + + public static void main(String[] args) { + fooFooFooBarBaz(239); + fooFooFooBarBaz(239); + fooFooFooBarBaz(239); + fooFooFooBarBaz(239); + fooFooFooBarBaz(239); + + bazSomeSome(239); + bazSomeSome(239); + bazSomeSome(239); + bazSomeSome(239); + } + + private static void fooFooFooBarBaz(int val) { + + } + + private static void bazSomeSome(int val) { + + } +} diff --git a/java/java-tests/testSrc/com/intellij/java/codeInspection/SameParameterValueLocalTest.java b/java/java-tests/testSrc/com/intellij/java/codeInspection/SameParameterValueLocalTest.java index 7a80754a075e..e8791b970dd3 100644 --- a/java/java-tests/testSrc/com/intellij/java/codeInspection/SameParameterValueLocalTest.java +++ b/java/java-tests/testSrc/com/intellij/java/codeInspection/SameParameterValueLocalTest.java @@ -75,4 +75,15 @@ public class SameParameterValueLocalTest extends InspectionTestCase { public void testNegativeDouble() { doTest(getGlobalTestDir(), myTool); } + + public void testUsageCount() { + int previous = myGlobalTool.minimalUsageCount; + try { + myGlobalTool.minimalUsageCount = 5; + doTest(getGlobalTestDir(), myTool); + } + finally { + myGlobalTool.minimalUsageCount = previous; + } + } } diff --git a/java/java-tests/testSrc/com/intellij/java/codeInspection/SameParameterValueTest.java b/java/java-tests/testSrc/com/intellij/java/codeInspection/SameParameterValueTest.java index 8ee2e5525835..dceb58779935 100644 --- a/java/java-tests/testSrc/com/intellij/java/codeInspection/SameParameterValueTest.java +++ b/java/java-tests/testSrc/com/intellij/java/codeInspection/SameParameterValueTest.java @@ -86,4 +86,15 @@ public class SameParameterValueTest extends InspectionTestCase { public void testClassObject() { doTest(getTestDir(), myTool, false, true); } + + public void testUsageCount() { + int previous = myTool.minimalUsageCount; + try { + myTool.minimalUsageCount = 5; + doTest(getTestDir(), myTool, false, true); + } + finally { + myTool.minimalUsageCount = previous; + } + } }