mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
disable for->foreach inspection if iterator is used in method reference qualifier (IDEA-136642)
This commit is contained in:
+34
-45
@@ -178,14 +178,12 @@ public class ForCanBeForeachInspectionBase extends BaseInspection {
|
||||
return visitor.isIndexVariableUsedOnlyAsIndex();
|
||||
}
|
||||
|
||||
static boolean isCollectionLoopStatement(
|
||||
PsiForStatement forStatement, boolean ignoreUntypedCollections) {
|
||||
static boolean isCollectionLoopStatement(PsiForStatement forStatement, boolean ignoreUntypedCollections) {
|
||||
final PsiStatement initialization = forStatement.getInitialization();
|
||||
if (!(initialization instanceof PsiDeclarationStatement)) {
|
||||
return false;
|
||||
}
|
||||
final PsiDeclarationStatement declaration =
|
||||
(PsiDeclarationStatement)initialization;
|
||||
final PsiDeclarationStatement declaration = (PsiDeclarationStatement)initialization;
|
||||
final PsiElement[] declaredElements = declaration.getDeclaredElements();
|
||||
if (declaredElements.length != 1) {
|
||||
return false;
|
||||
@@ -195,9 +193,7 @@ public class ForCanBeForeachInspectionBase extends BaseInspection {
|
||||
return false;
|
||||
}
|
||||
final PsiVariable variable = (PsiVariable)declaredElement;
|
||||
if (!TypeUtils.variableHasTypeOrSubtype(variable,
|
||||
CommonClassNames.JAVA_UTIL_ITERATOR,
|
||||
"java.util.ListIterator")) {
|
||||
if (!TypeUtils.variableHasTypeOrSubtype(variable, CommonClassNames.JAVA_UTIL_ITERATOR, "java.util.ListIterator")) {
|
||||
return false;
|
||||
}
|
||||
final PsiExpression initialValue = variable.getInitializer();
|
||||
@@ -207,14 +203,10 @@ public class ForCanBeForeachInspectionBase extends BaseInspection {
|
||||
if (!(initialValue instanceof PsiMethodCallExpression)) {
|
||||
return false;
|
||||
}
|
||||
final PsiMethodCallExpression initialCall =
|
||||
(PsiMethodCallExpression)initialValue;
|
||||
final PsiReferenceExpression initialMethodExpression =
|
||||
initialCall.getMethodExpression();
|
||||
@NonNls final String initialCallName =
|
||||
initialMethodExpression.getReferenceName();
|
||||
if (!HardcodedMethodConstants.ITERATOR.equals(initialCallName) &&
|
||||
!"listIterator".equals(initialCallName)) {
|
||||
final PsiMethodCallExpression initialCall = (PsiMethodCallExpression)initialValue;
|
||||
final PsiReferenceExpression initialMethodExpression = initialCall.getMethodExpression();
|
||||
@NonNls final String initialCallName = initialMethodExpression.getReferenceName();
|
||||
if (!HardcodedMethodConstants.ITERATOR.equals(initialCallName) && !"listIterator".equals(initialCallName)) {
|
||||
return false;
|
||||
}
|
||||
final PsiExpressionList argumentList = initialCall.getArgumentList();
|
||||
@@ -222,12 +214,10 @@ public class ForCanBeForeachInspectionBase extends BaseInspection {
|
||||
if (arguments.length != 0) {
|
||||
return false;
|
||||
}
|
||||
final PsiExpression qualifier =
|
||||
initialMethodExpression.getQualifierExpression();
|
||||
final PsiExpression qualifier = initialMethodExpression.getQualifierExpression();
|
||||
final PsiClass qualifierClass;
|
||||
if (qualifier == null) {
|
||||
qualifierClass =
|
||||
ClassUtils.getContainingClass(initialMethodExpression);
|
||||
qualifierClass = ClassUtils.getContainingClass(initialMethodExpression);
|
||||
if (ignoreUntypedCollections) {
|
||||
final PsiClassType type = (PsiClassType)variable.getType();
|
||||
final PsiType[] parameters = type.getParameters();
|
||||
@@ -255,10 +245,8 @@ public class ForCanBeForeachInspectionBase extends BaseInspection {
|
||||
if (qualifierClass == null) {
|
||||
return false;
|
||||
}
|
||||
if (!InheritanceUtil.isInheritor(qualifierClass,
|
||||
CommonClassNames.JAVA_LANG_ITERABLE) &&
|
||||
!InheritanceUtil.isInheritor(qualifierClass,
|
||||
CommonClassNames.JAVA_UTIL_COLLECTION)) {
|
||||
if (!InheritanceUtil.isInheritor(qualifierClass, CommonClassNames.JAVA_LANG_ITERABLE) &&
|
||||
!InheritanceUtil.isInheritor(qualifierClass, CommonClassNames.JAVA_UTIL_COLLECTION)) {
|
||||
return false;
|
||||
}
|
||||
final PsiExpression condition = forStatement.getCondition();
|
||||
@@ -289,16 +277,13 @@ public class ForCanBeForeachInspectionBase extends BaseInspection {
|
||||
if (body == null) {
|
||||
return 0;
|
||||
}
|
||||
final NumCallsToIteratorNextVisitor visitor =
|
||||
new NumCallsToIteratorNextVisitor(iterator);
|
||||
final NumCallsToIteratorNextVisitor visitor = new NumCallsToIteratorNextVisitor(iterator);
|
||||
body.accept(visitor);
|
||||
return visitor.getNumCallsToIteratorNext();
|
||||
}
|
||||
|
||||
private static boolean isIteratorMethodCalled(PsiVariable iterator,
|
||||
PsiStatement body) {
|
||||
final IteratorMethodCallVisitor visitor =
|
||||
new IteratorMethodCallVisitor(iterator);
|
||||
private static boolean isIteratorMethodCalled(PsiVariable iterator, PsiStatement body) {
|
||||
final IteratorMethodCallVisitor visitor = new IteratorMethodCallVisitor(iterator);
|
||||
body.accept(visitor);
|
||||
return visitor.isMethodCalled();
|
||||
}
|
||||
@@ -308,29 +293,25 @@ public class ForCanBeForeachInspectionBase extends BaseInspection {
|
||||
if (!(condition instanceof PsiMethodCallExpression)) {
|
||||
return false;
|
||||
}
|
||||
final PsiMethodCallExpression call =
|
||||
(PsiMethodCallExpression)condition;
|
||||
final PsiMethodCallExpression call = (PsiMethodCallExpression)condition;
|
||||
final PsiExpressionList argumentList = call.getArgumentList();
|
||||
final PsiExpression[] arguments = argumentList.getExpressions();
|
||||
if (arguments.length != 0) {
|
||||
return false;
|
||||
}
|
||||
final PsiReferenceExpression methodExpression =
|
||||
call.getMethodExpression();
|
||||
final PsiReferenceExpression methodExpression = call.getMethodExpression();
|
||||
final String methodName = methodExpression.getReferenceName();
|
||||
if (!HardcodedMethodConstants.HAS_NEXT.equals(methodName)) {
|
||||
return false;
|
||||
}
|
||||
final PsiExpression qualifier =
|
||||
methodExpression.getQualifierExpression();
|
||||
final PsiExpression qualifier = methodExpression.getQualifierExpression();
|
||||
if (qualifier == null) {
|
||||
return true;
|
||||
}
|
||||
if (!(qualifier instanceof PsiReferenceExpression)) {
|
||||
return false;
|
||||
}
|
||||
final PsiReferenceExpression referenceExpression =
|
||||
(PsiReferenceExpression)qualifier;
|
||||
final PsiReferenceExpression referenceExpression = (PsiReferenceExpression)qualifier;
|
||||
final PsiElement target = referenceExpression.resolve();
|
||||
return iterator.equals(target);
|
||||
}
|
||||
@@ -636,31 +617,39 @@ public class ForCanBeForeachInspectionBase extends BaseInspection {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitMethodCallExpression(
|
||||
@NotNull PsiMethodCallExpression expression) {
|
||||
public void visitMethodCallExpression(@NotNull PsiMethodCallExpression expression) {
|
||||
if (methodCalled) {
|
||||
return;
|
||||
}
|
||||
super.visitMethodCallExpression(expression);
|
||||
final PsiReferenceExpression methodExpression =
|
||||
expression.getMethodExpression();
|
||||
final PsiReferenceExpression methodExpression = expression.getMethodExpression();
|
||||
final String name = methodExpression.getReferenceName();
|
||||
if (HardcodedMethodConstants.NEXT.equals(name)) {
|
||||
return;
|
||||
}
|
||||
final PsiExpression qualifier =
|
||||
methodExpression.getQualifierExpression();
|
||||
final PsiExpression qualifier = methodExpression.getQualifierExpression();
|
||||
if (!(qualifier instanceof PsiReferenceExpression)) {
|
||||
return;
|
||||
}
|
||||
final PsiReferenceExpression referenceExpression =
|
||||
(PsiReferenceExpression)qualifier;
|
||||
final PsiReferenceExpression referenceExpression = (PsiReferenceExpression)qualifier;
|
||||
final PsiElement target = referenceExpression.resolve();
|
||||
if (iterator.equals(target)) {
|
||||
methodCalled = true;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitMethodReferenceExpression(PsiMethodReferenceExpression expression) {
|
||||
if (methodCalled) {
|
||||
return;
|
||||
}
|
||||
super.visitMethodReferenceExpression(expression);
|
||||
final PsiExpression qualifierExpression = expression.getQualifierExpression();
|
||||
if (qualifierExpression instanceof PsiReferenceExpression && iterator.equals(((PsiReferenceExpression)qualifierExpression).resolve())) {
|
||||
methodCalled = true;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isMethodCalled() {
|
||||
return methodCalled;
|
||||
}
|
||||
|
||||
+14
@@ -273,6 +273,20 @@ public class ForCanBeForEach {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static class WithMethodRefs {
|
||||
private static final List<String> STRINGS = new ArrayList<>(Arrays.asList("Hello", "World"));
|
||||
|
||||
public void test3() {
|
||||
for (ListIterator<String> stringListIterator = STRINGS.listIterator(); stringListIterator.hasNext(); ) {
|
||||
System.out.println(stringListIterator.next());
|
||||
|
||||
List<String> strings2 = new ArrayList<>(Collections.singletonList("!"));
|
||||
|
||||
strings2.forEach(stringListIterator::add);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
class OuterClass
|
||||
{
|
||||
|
||||
+8
@@ -1,7 +1,9 @@
|
||||
package com.siyeh.ig.migration;
|
||||
|
||||
import com.intellij.codeInspection.InspectionProfileEntry;
|
||||
import com.intellij.testFramework.LightProjectDescriptor;
|
||||
import com.siyeh.ig.LightInspectionTestCase;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class ForCanBeForeachInspectionTest extends LightInspectionTestCase {
|
||||
|
||||
@@ -18,4 +20,10 @@ public class ForCanBeForeachInspectionTest extends LightInspectionTestCase {
|
||||
protected String getBasePath() {
|
||||
return "/plugins/InspectionGadgets/test/com/siyeh/igtest/migration/foreach";
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
protected LightProjectDescriptor getProjectDescriptor() {
|
||||
return JAVA_8;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user