mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
IDEA-259356 inspection 'same parameter value': add option to ignore cases without quick-fix
GitOrigin-RevId: b9f41d65fd21be0052fdae3b2b01027043778ba9
This commit is contained in:
committed by
intellij-monorepo-bot
parent
e6472aeb09
commit
5f70aac2f8
+26
-10
@@ -31,6 +31,7 @@ import com.intellij.refactoring.safeDelete.JavaSafeDeleteProcessor;
|
||||
import com.intellij.refactoring.util.CommonRefactoringUtil;
|
||||
import com.intellij.refactoring.util.InlineUtil;
|
||||
import com.intellij.uast.UastHintedVisitorAdapter;
|
||||
import com.intellij.ui.components.JBCheckBox;
|
||||
import com.intellij.ui.components.fields.IntegerField;
|
||||
import com.intellij.ui.components.fields.valueEditors.ValueEditor;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
@@ -57,11 +58,17 @@ public class SameParameterValueInspection extends GlobalJavaBatchInspectionTool
|
||||
@PsiModifier.ModifierConstant
|
||||
public String highestModifier = DEFAULT_HIGHEST_MODIFIER;
|
||||
public int minimalUsageCount = 1;
|
||||
public boolean ignoreWhenRefactoringIsComplicated = true;
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public JComponent createOptionsPanel() {
|
||||
JPanel panel = new InspectionOptionsPanel();
|
||||
|
||||
final JBCheckBox checkBox = new JBCheckBox(JavaBundle.message("label.ignore.complicated.fix"), ignoreWhenRefactoringIsComplicated);
|
||||
checkBox.addChangeListener((e) -> ignoreWhenRefactoringIsComplicated = checkBox.isSelected());
|
||||
panel.add(checkBox);
|
||||
|
||||
LabeledComponent<VisibilityModifierChooser> component = LabeledComponent.create(new VisibilityModifierChooser(() -> true,
|
||||
highestModifier,
|
||||
(newModifier) -> highestModifier = newModifier),
|
||||
@@ -111,7 +118,9 @@ public class SameParameterValueInspection extends GlobalJavaBatchInspectionTool
|
||||
if (problems == null) problems = new ArrayList<>(1);
|
||||
UParameter parameter = refParameter.getUastElement();
|
||||
if (parameter == null) continue;
|
||||
problems.add(registerProblem(manager, parameter, value, refParameter.isUsedForWriting()));
|
||||
Boolean isFixAvailable = isFixAvailable(parameter, value, refParameter.isUsedForWriting());
|
||||
if (Boolean.FALSE.equals(isFixAvailable) && ignoreWhenRefactoringIsComplicated) return null;
|
||||
problems.add(registerProblem(manager, parameter, value, Boolean.TRUE.equals(isFixAvailable)));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -181,20 +190,17 @@ public class SameParameterValueInspection extends GlobalJavaBatchInspectionTool
|
||||
private ProblemDescriptor registerProblem(@NotNull InspectionManager manager,
|
||||
UParameter parameter,
|
||||
Object value,
|
||||
boolean usedForWriting) {
|
||||
boolean suggestFix) {
|
||||
final String name = parameter.getName();
|
||||
String shortName;
|
||||
String stringPresentation;
|
||||
boolean accessible = true;
|
||||
|
||||
PsiParameter javaParameter = ObjectUtils.tryCast(parameter.getSourcePsi(), PsiParameter.class);
|
||||
if (value instanceof PsiType) {
|
||||
stringPresentation = ((PsiType)value).getCanonicalText() + ".class";
|
||||
shortName = ((PsiType)value).getPresentableText() + ".class";
|
||||
}
|
||||
else {
|
||||
if (value instanceof PsiField) {
|
||||
accessible = javaParameter != null && PsiUtil.isMemberAccessibleAt((PsiMember)value, javaParameter);
|
||||
stringPresentation = PsiFormatUtil.formatVariable((PsiVariable)value,
|
||||
PsiFormatUtilBase.SHOW_NAME | PsiFormatUtilBase.SHOW_CONTAINING_CLASS | PsiFormatUtilBase.SHOW_FQ_NAME,
|
||||
PsiSubstitutor.EMPTY);
|
||||
@@ -209,10 +215,6 @@ public class SameParameterValueInspection extends GlobalJavaBatchInspectionTool
|
||||
stringPresentation = shortName = String.valueOf(value);
|
||||
}
|
||||
}
|
||||
boolean suggestFix = false;
|
||||
if (javaParameter != null) {
|
||||
suggestFix = !javaParameter.isVarArgs() && !usedForWriting && accessible ;
|
||||
}
|
||||
return manager.createProblemDescriptor(ObjectUtils.notNull(UDeclarationKt.getAnchorPsi(parameter), parameter),
|
||||
JavaBundle.message("inspection.same.parameter.problem.descriptor",
|
||||
name,
|
||||
@@ -221,6 +223,17 @@ public class SameParameterValueInspection extends GlobalJavaBatchInspectionTool
|
||||
ProblemHighlightType.GENERIC_ERROR_OR_WARNING, false);
|
||||
}
|
||||
|
||||
protected static @Nullable Boolean isFixAvailable(UParameter parameter, Object value, boolean usedForWriting) {
|
||||
if (usedForWriting) return false;
|
||||
PsiParameter javaParameter = ObjectUtils.tryCast(parameter.getSourcePsi(), PsiParameter.class);
|
||||
if (javaParameter == null) return null;
|
||||
if (javaParameter.isVarArgs()) return false;
|
||||
if (value instanceof PsiField && !PsiUtil.isMemberAccessibleAt((PsiMember)value, javaParameter)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public static final class InlineParameterValueFix implements LocalQuickFix {
|
||||
private final String myValue;
|
||||
private final String myParameterName;
|
||||
@@ -456,7 +469,10 @@ public class SameParameterValueInspection extends GlobalJavaBatchInspectionTool
|
||||
for (int i = 0, length = paramValues.length; i < length; i++) {
|
||||
Object value = paramValues[i];
|
||||
if (value != VALUE_UNDEFINED && value != VALUE_IS_NOT_CONST) {
|
||||
holder.registerProblem(registerProblem(holder.getManager(), parameters.get(i), value, false));
|
||||
final UParameter parameter = parameters.get(i);
|
||||
Boolean isFixAvailable = isFixAvailable(parameter, value, false);
|
||||
if (Boolean.FALSE.equals(isFixAvailable) && ignoreWhenRefactoringIsComplicated) return true;
|
||||
holder.registerProblem(registerProblem(holder.getManager(), parameter, value, Boolean.TRUE.equals(isFixAvailable)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,5 +15,10 @@ public static void main(String[] args) {
|
||||
</code>
|
||||
</pre>
|
||||
<p>The quick-fix inlines the constant value. This may simplify the method implementation.</p>
|
||||
<!-- tooltip end -->
|
||||
<p>
|
||||
Use the checkbox below to ignore cases when complicated refactoring may be required.
|
||||
For example, when the reported parameter is modified inside the method or when the passed parameter value is a reference to inaccessible field.
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<problems>
|
||||
<problem>
|
||||
<file>Test.java</file>
|
||||
<line>10</line>
|
||||
<description>Actual value of parameter 'obj' is always 'A.OBJ'</description>
|
||||
</problem>
|
||||
|
||||
</problems>
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
class A {
|
||||
public static final Object OBJ = new Object();
|
||||
|
||||
void test() {
|
||||
B.use(OBJ);
|
||||
}
|
||||
}
|
||||
|
||||
class B {
|
||||
static void use(Object obj) {
|
||||
System.out.println(obj);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<problems/>
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
class A {
|
||||
private static final Object OBJ = new Object();
|
||||
|
||||
void test() {
|
||||
B.use(OBJ);
|
||||
}
|
||||
}
|
||||
|
||||
class B {
|
||||
static void use(Object obj) {
|
||||
System.out.println(obj);
|
||||
}
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<problems>
|
||||
<problem>
|
||||
<file>Test.java</file>
|
||||
<line>10</line>
|
||||
<description>Actual value of parameter 'obj' is always 'A.OBJ'</description>
|
||||
</problem>
|
||||
|
||||
</problems>
|
||||
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
class A {
|
||||
private static final Object OBJ = new Object();
|
||||
|
||||
void test() {
|
||||
B.use(OBJ);
|
||||
}
|
||||
}
|
||||
|
||||
class B {
|
||||
static void use(Object obj) {
|
||||
System.out.println(obj);
|
||||
}
|
||||
}
|
||||
+14
@@ -80,6 +80,20 @@ public class SameParameterValueLocalTest extends JavaInspectionTestCase {
|
||||
doTest(getGlobalTestDir(), myTool);
|
||||
}
|
||||
|
||||
public void testFixAvailable() { doTest(getGlobalTestDir(), myTool); }
|
||||
|
||||
public void testFixNotAvailable() { doTest(getGlobalTestDir(), myTool); }
|
||||
|
||||
public void testFixNotAvailableIsShown() {
|
||||
boolean previous = myGlobalTool.ignoreWhenRefactoringIsComplicated;
|
||||
try {
|
||||
myGlobalTool.ignoreWhenRefactoringIsComplicated = false;
|
||||
doTest(getGlobalTestDir(), myTool);
|
||||
} finally {
|
||||
myGlobalTool.ignoreWhenRefactoringIsComplicated = previous;
|
||||
}
|
||||
}
|
||||
|
||||
public void testUsageCount() {
|
||||
int previous = myGlobalTool.minimalUsageCount;
|
||||
try {
|
||||
|
||||
+7
-1
@@ -62,7 +62,13 @@ public class SameParameterValueTest extends JavaInspectionTestCase {
|
||||
}
|
||||
|
||||
public void testSimpleVararg() {
|
||||
doTest(getTestDir(), myTool, false, true);
|
||||
boolean previous = myTool.ignoreWhenRefactoringIsComplicated;
|
||||
try {
|
||||
myTool.ignoreWhenRefactoringIsComplicated = false;
|
||||
doTest(getTestDir(), myTool, false, true);
|
||||
} finally {
|
||||
myTool.ignoreWhenRefactoringIsComplicated = previous;
|
||||
}
|
||||
}
|
||||
|
||||
public void testMethodWithSuper() {
|
||||
|
||||
@@ -959,6 +959,7 @@ label.implements.method.of_class_or_interface.name=implements method of {0, choi
|
||||
label.implements.method.of_interfaces=implements methods of the following classes/interfaces:
|
||||
label.maximal.reported.method.visibility=Maximal reported method visibility:
|
||||
label.method=Method ''{0}''
|
||||
label.ignore.complicated.fix=Ignore when complicated refactoring may be required
|
||||
label.minimal.reported.method.usage.count=Minimal reported method usage count:
|
||||
label.minimal.reported.method.visibility=Minimal reported method visibility:
|
||||
label.mutates=Mutates:
|
||||
|
||||
Reference in New Issue
Block a user