mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
[java-inspections] SequencedCollectionMethodCanBeUsedInspection should ignore named constants
#IDEA-367961 fixed Merge-request: IJ-MR-155974 Merged-by: Bartek Pacia <bartek.pacia@jetbrains.com> GitOrigin-RevId: aa16bf0758ef523f21c0eeaf73e27e418fc0cd89
This commit is contained in:
committed by
intellij-monorepo-bot
parent
15d703aa85
commit
bb7efcadba
@@ -1244,6 +1244,7 @@ negated.if.else.ignore.negated.zero.option=Ignore '!= 0' comparisons
|
||||
negated.if.else.invert.quickfix=Invert 'if' condition
|
||||
overly.complex.boolean.expression.max.terms.option=Maximum number of terms:
|
||||
pointless.boolean.expression.ignore.option=Ignore named constants in determining pointless expressions
|
||||
sequenced.collection.method.can.be.used.ignore.option=Ignore named constants used as arguments
|
||||
simplifiable.conditional.expression.problem.descriptor=<code>{1}</code> can be simplified to ''{0}'' #loc
|
||||
switch.statement.density.min.option=Minimum density of branches: %
|
||||
switch.statement.density.problem.descriptor=<code>#ref</code> branch density is too low ({0}%) #loc
|
||||
@@ -2538,4 +2539,4 @@ inspection.redundant.embedded.expression.fix.family.name=Inline embedded express
|
||||
auto.closeable.resource.quickfix.preview=Add method <code>{0}</code> to the list of ignored methods
|
||||
inspection.while.can.be.replaced.with.do.while.display.name='while' can be replaced with 'do while'
|
||||
inspection.while.can.be.replaced.with.do.while.message=Replace 'while' with 'do while'
|
||||
inspection.while.can.be.replaced.with.do.while.family.name=Replace 'while' with 'do while'
|
||||
inspection.while.can.be.replaced.with.do.while.family.name=Replace 'while' with 'do while'
|
||||
|
||||
+28
-2
@@ -1,6 +1,7 @@
|
||||
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package com.intellij.codeInspection;
|
||||
|
||||
import com.intellij.codeInspection.options.OptPane;
|
||||
import com.intellij.java.JavaBundle;
|
||||
import com.intellij.modcommand.ModPsiUpdater;
|
||||
import com.intellij.modcommand.PsiUpdateModCommandQuickFix;
|
||||
@@ -11,6 +12,7 @@ import com.intellij.psi.util.InheritanceUtil;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import com.siyeh.InspectionGadgetsBundle;
|
||||
import com.siyeh.ig.callMatcher.CallMatcher;
|
||||
import com.siyeh.ig.psiutils.*;
|
||||
import one.util.streamex.StreamEx;
|
||||
@@ -19,6 +21,9 @@ import org.jetbrains.annotations.NotNull;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
|
||||
import static com.intellij.codeInspection.options.OptPane.checkbox;
|
||||
import static com.intellij.codeInspection.options.OptPane.pane;
|
||||
|
||||
public final class SequencedCollectionMethodCanBeUsedInspection extends AbstractBaseJavaLocalInspectionTool {
|
||||
private static final CallMatcher LIST_GET_REMOVE = CallMatcher.instanceCall(CommonClassNames.JAVA_UTIL_LIST, "get", "remove")
|
||||
.parameterTypes("int");
|
||||
@@ -29,6 +34,14 @@ public final class SequencedCollectionMethodCanBeUsedInspection extends Abstract
|
||||
private static final CallMatcher COLLECTION_ITERATOR = CallMatcher.instanceCall("java.util.Collection", "iterator")
|
||||
.parameterCount(0);
|
||||
|
||||
public boolean m_ignoreExpressionsContainingConstants = true;
|
||||
|
||||
@Override
|
||||
public @NotNull OptPane getOptionsPane() {
|
||||
return pane(
|
||||
checkbox("m_ignoreExpressionsContainingConstants", InspectionGadgetsBundle.message("sequenced.collection.method.can.be.used.ignore.option")));
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull Set<@NotNull JavaFeature> requiredFeatures() {
|
||||
return Set.of(JavaFeature.SEQUENCED_COLLECTIONS);
|
||||
@@ -72,11 +85,12 @@ public final class SequencedCollectionMethodCanBeUsedInspection extends Abstract
|
||||
PsiExpression list = PsiUtil.skipParenthesizedExprDown(methodExpr.getQualifierExpression());
|
||||
if (list == null || list instanceof PsiThisExpression) return;
|
||||
PsiExpression arg = PsiUtil.skipParenthesizedExprDown(call.getArgumentList().getExpressions()[0]);
|
||||
if (m_ignoreExpressionsContainingConstants && isArgConstant(arg)) return;
|
||||
if (ExpressionUtils.isZero(arg) && !hasDifferentIndexNearby(call)) {
|
||||
report(call, "addFirst");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Do not warn if we have series of calls with different constant indices like {@code list.get(0); list.get(1); ...}
|
||||
private static boolean hasDifferentIndexNearby(@NotNull PsiMethodCallExpression call) {
|
||||
PsiMethod method = call.resolveMethod();
|
||||
@@ -86,7 +100,7 @@ public final class SequencedCollectionMethodCanBeUsedInspection extends Abstract
|
||||
PsiCodeBlock block = PsiTreeUtil.getParentOfType(call, PsiCodeBlock.class, true, PsiLambdaExpression.class, PsiMember.class);
|
||||
if (block == null) return false;
|
||||
PsiStatement[] statements = block.getStatements();
|
||||
int index = (int) StreamEx.of(statements).indexOf(s -> PsiTreeUtil.isAncestor(s, call, true)).orElse(-1);
|
||||
int index = (int)StreamEx.of(statements).indexOf(s -> PsiTreeUtil.isAncestor(s, call, true)).orElse(-1);
|
||||
if (index == -1) return false;
|
||||
for (int i = Math.max(0, index - 2); i <= Math.min(statements.length - 1, index + 2); i++) {
|
||||
Integer otherIndex = SyntaxTraverser.psiTraverser(statements[i]).filter(PsiMethodCallExpression.class)
|
||||
@@ -106,12 +120,24 @@ public final class SequencedCollectionMethodCanBeUsedInspection extends Abstract
|
||||
return false;
|
||||
}
|
||||
|
||||
private static boolean isArgConstant(PsiExpression arg) {
|
||||
if (arg instanceof PsiReferenceExpression referenceExpr) {
|
||||
PsiElement resolvedArg = referenceExpr.resolve();
|
||||
if (resolvedArg instanceof PsiField field && ExpressionUtils.isConstant(field)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private void processListGetRemove(@NotNull PsiMethodCallExpression call) {
|
||||
PsiReferenceExpression methodExpr = call.getMethodExpression();
|
||||
String name = methodExpr.getReferenceName();
|
||||
PsiExpression list = PsiUtil.skipParenthesizedExprDown(methodExpr.getQualifierExpression());
|
||||
if (list == null || list instanceof PsiThisExpression) return;
|
||||
PsiExpression arg = PsiUtil.skipParenthesizedExprDown(call.getArgumentList().getExpressions()[0]);
|
||||
if (m_ignoreExpressionsContainingConstants && isArgConstant(arg)) return;
|
||||
if (ExpressionUtils.isZero(arg) && !hasDifferentIndexNearby(call)) {
|
||||
report(call, name + "First");
|
||||
}
|
||||
|
||||
@@ -4,6 +4,8 @@ import java.util.*;
|
||||
interface Foo extends SequencedCollection<String> {}
|
||||
|
||||
public class Test {
|
||||
private static final int SOME_CONSTANT = 0;
|
||||
|
||||
public static void main(Foo foo, String[] args) {
|
||||
List<String> list = List.of(args);
|
||||
|
||||
@@ -14,6 +16,11 @@ public class Test {
|
||||
var e5 = list.removeLast();
|
||||
list.remove("e");
|
||||
list.get(1);
|
||||
|
||||
var e6 = list.get(SOME_CONSTANT);
|
||||
var e7 = list.remove(SOME_CONSTANT);
|
||||
list.addFirst("hello");
|
||||
list.add(SOME_CONSTANT, "world");
|
||||
}
|
||||
|
||||
void testAdd(List<String> list) {
|
||||
|
||||
@@ -4,6 +4,8 @@ import java.util.*;
|
||||
interface Foo extends SequencedCollection<String> {}
|
||||
|
||||
public class Test {
|
||||
private static final int SOME_CONSTANT = 0;
|
||||
|
||||
public static void main(Foo foo, String[] args) {
|
||||
List<String> list = List.of(args);
|
||||
|
||||
@@ -14,6 +16,11 @@ public class Test {
|
||||
var e5 = list.remove(list.size() - 1);
|
||||
list.remove("e");
|
||||
list.get(1);
|
||||
|
||||
var e6 = list.get(SOME_CONSTANT);
|
||||
var e7 = list.remove(SOME_CONSTANT);
|
||||
list.add(0, "hello");
|
||||
list.add(SOME_CONSTANT, "world");
|
||||
}
|
||||
|
||||
void testAdd(List<String> list) {
|
||||
|
||||
Reference in New Issue
Block a user