diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/ContractValue.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/ContractValue.java index a5f705c9de29..f68af8326297 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/ContractValue.java +++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/ContractValue.java @@ -219,7 +219,7 @@ public abstract class ContractValue { @Override public String toString() { - return myQualifier + "." + myField.getMethodName() + "()"; + return myQualifier + "." + myField + "()"; } } diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/ControlFlowAnalyzer.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/ControlFlowAnalyzer.java index bb38df7c9756..d4ecaa44aaa5 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/ControlFlowAnalyzer.java +++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/ControlFlowAnalyzer.java @@ -1861,12 +1861,11 @@ public class ControlFlowAnalyzer extends JavaElementVisitor { private DfaValue getPrecalculatedNewValue(PsiNewExpression expression) { PsiType type = expression.getType(); if (type != null && ConstructionUtils.isEmptyCollectionInitializer(expression)) { - SpecialField sizeField = InheritanceUtil.isInheritor(type, JAVA_UTIL_MAP) ? SpecialField.MAP_SIZE : SpecialField.COLLECTION_SIZE; DfaFactMap facts = DfaFactMap.EMPTY .with(DfaFactType.TYPE_CONSTRAINT, TypeConstraint.exact(myFactory.createDfaType(type))) .with(DfaFactType.NULLABILITY, DfaNullability.NOT_NULL) .with(DfaFactType.LOCALITY, true) - .with(DfaFactType.SPECIAL_FIELD_VALUE, sizeField.withValue(myFactory.getInt(0))); + .with(DfaFactType.SPECIAL_FIELD_VALUE, SpecialField.COLLECTION_SIZE.withValue(myFactory.getInt(0))); return myFactory.getFactFactory().createValue(facts); } return null; @@ -2188,7 +2187,7 @@ public class ControlFlowAnalyzer extends JavaElementVisitor { static final CallInliner[] INLINERS = { new OptionalChainInliner(), new LambdaInliner(), new CollectionFactoryInliner(), new StreamChainInliner(), new MapUpdateInliner(), new AssumeInliner(), new ClassMethodsInliner(), - new AssertAllInliner(), new BoxingInliner(), new SimpleMethodInliner() + new AssertAllInliner(), new BoxingInliner(), new SimpleMethodInliner(), new CollectionMethodInliner() }; } diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DfaFactType.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DfaFactType.java index 950009a20882..36da82871d02 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DfaFactType.java +++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DfaFactType.java @@ -257,7 +257,7 @@ public abstract class DfaFactType extends Key { @NotNull @Override public String getName(SpecialFieldValue fact) { - return fact == null ? super.getName(null) : StringUtil.wordsToBeginFromUpperCase(fact.getField().getMethodName()); + return fact == null ? super.getName(null) : StringUtil.wordsToBeginFromUpperCase(fact.getField().toString()); } @Nullable diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/HardcodedContracts.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/HardcodedContracts.java index 3e1eb3682d27..c1ed5020c8dd 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/HardcodedContracts.java +++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/HardcodedContracts.java @@ -91,24 +91,22 @@ public class HardcodedContracts { (call, cnt) -> getSubstringContracts(cnt == 2)) .register(instanceCall(JAVA_LANG_STRING, "isEmpty").parameterCount(0), ContractProvider.of(SpecialField.STRING_LENGTH.getEmptyContracts())) - .register(instanceCall(JAVA_UTIL_COLLECTION, "isEmpty").parameterCount(0), + .register(anyOf(instanceCall(JAVA_UTIL_COLLECTION, "isEmpty").parameterCount(0), + instanceCall(JAVA_UTIL_MAP, "isEmpty").parameterCount(0)), ContractProvider.of(SpecialField.COLLECTION_SIZE.getEmptyContracts())) - .register(instanceCall(JAVA_UTIL_MAP, "isEmpty").parameterCount(0), - ContractProvider.of(SpecialField.MAP_SIZE.getEmptyContracts())) .register(instanceCall(JAVA_LANG_STRING, "equalsIgnoreCase").parameterCount(1), ContractProvider.of(SpecialField.STRING_LENGTH.getEqualsContracts())) .register(anyOf(instanceCall(JAVA_UTIL_SET, "equals").parameterTypes(JAVA_LANG_OBJECT), - instanceCall(JAVA_UTIL_LIST, "equals").parameterTypes(JAVA_LANG_OBJECT)), + instanceCall(JAVA_UTIL_LIST, "equals").parameterTypes(JAVA_LANG_OBJECT), + instanceCall(JAVA_UTIL_MAP, "equals").parameterTypes(JAVA_LANG_OBJECT)), ContractProvider.of(SpecialField.COLLECTION_SIZE.getEqualsContracts())) - .register(instanceCall(JAVA_UTIL_MAP, "equals").parameterTypes(JAVA_LANG_OBJECT), - ContractProvider.of(SpecialField.MAP_SIZE.getEqualsContracts())) .register(instanceCall(JAVA_UTIL_COLLECTION, "contains").parameterCount(1), ContractProvider.of(singleConditionContract( ContractValue.qualifier().specialField(SpecialField.COLLECTION_SIZE), RelationType.EQ, ContractValue.zero(), returnFalse()))) .register(instanceCall(JAVA_UTIL_MAP, "containsKey", "containsValue").parameterCount(1), ContractProvider.of(singleConditionContract( - ContractValue.qualifier().specialField(SpecialField.MAP_SIZE), RelationType.EQ, ContractValue.zero(), returnFalse()))) + ContractValue.qualifier().specialField(SpecialField.COLLECTION_SIZE), RelationType.EQ, ContractValue.zero(), returnFalse()))) .register(instanceCall(JAVA_UTIL_LIST, "get").parameterTypes("int"), ContractProvider.of(nonnegativeArgumentContract(0), specialFieldRangeContract(0, RelationType.LT, SpecialField.COLLECTION_SIZE))) diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/SpecialField.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/SpecialField.java index b635b9f112fd..8c06878f994e 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/SpecialField.java +++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/SpecialField.java @@ -10,7 +10,6 @@ import com.intellij.psi.util.PsiUtil; import com.intellij.psi.util.TypeConversionUtil; import com.siyeh.ig.callMatcher.CallMatcher; import com.siyeh.ig.psiutils.ExpressionUtils; -import com.siyeh.ig.psiutils.MethodUtils; import com.siyeh.ig.psiutils.TypeUtils; import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.NotNull; @@ -27,7 +26,7 @@ import static com.intellij.psi.CommonClassNames.*; * @author Tagir Valeev */ public enum SpecialField implements VariableDescriptor { - ARRAY_LENGTH(null, "length", true) { + ARRAY_LENGTH("length", true) { @Override boolean isMyQualifierType(PsiType type) { return type instanceof PsiArrayType; @@ -59,20 +58,61 @@ public enum SpecialField implements VariableDescriptor { return null; } }, - STRING_LENGTH(JAVA_LANG_STRING, "length", true) { + STRING_LENGTH("length", true) { @Override DfaValue fromInitializer(DfaValueFactory factory, PsiExpression initializer) { return fromConstant(factory, ExpressionUtils.computeConstantExpression(initializer)); } + @Override + boolean isMyQualifierType(PsiType type) { + return TypeUtils.isJavaLangString(type); + } + + @Override + boolean isMyAccessor(PsiMember accessor) { + if (!(accessor instanceof PsiMethod) || !"length".equals(accessor.getName()) || !((PsiMethod)accessor).getParameterList().isEmpty()) { + return false; + } + PsiClass containingClass = accessor.getContainingClass(); + return containingClass != null && JAVA_LANG_STRING.equals(containingClass.getQualifiedName()); + } + @Override public DfaValue fromConstant(DfaValueFactory factory, @Nullable Object obj) { return obj instanceof String ? factory.getInt(((String)obj).length()) : null; } }, - COLLECTION_SIZE(JAVA_UTIL_COLLECTION, "size", false), - MAP_SIZE(JAVA_UTIL_MAP, "size", false), - UNBOX(null, "value", true) { + COLLECTION_SIZE("size", false) { + private final CallMatcher SIZE_METHODS = CallMatcher.anyOf(CallMatcher.instanceCall(JAVA_UTIL_COLLECTION, "size").parameterCount(0), + CallMatcher.instanceCall(JAVA_UTIL_MAP, "size").parameterCount(0)); + private final CallMatcher MAP_COLLECTIONS = CallMatcher.instanceCall(JAVA_UTIL_MAP, "keySet", "entrySet", "values") + .parameterCount(0); + + @Override + boolean isMyQualifierType(PsiType type) { + return InheritanceUtil.isInheritor(type, JAVA_UTIL_MAP) || InheritanceUtil.isInheritor(type, JAVA_UTIL_COLLECTION); + } + + @Override + boolean isMyAccessor(PsiMember accessor) { + return accessor instanceof PsiMethod && SIZE_METHODS.methodMatches((PsiMethod)accessor); + } + + @NotNull + @Override + public DfaValue createValue(@NotNull DfaValueFactory factory, @Nullable DfaValue qualifier, boolean forAccessor) { + if (qualifier instanceof DfaVariableValue) { + DfaVariableValue var = (DfaVariableValue)qualifier; + PsiModifierListOwner owner = var.getPsiVariable(); + if (var.getQualifier() != null && owner instanceof PsiMethod && MAP_COLLECTIONS.methodMatches((PsiMethod)owner)) { + return super.createValue(factory, var.getQualifier(), forAccessor); + } + } + return super.createValue(factory, qualifier, forAccessor); + } + }, + UNBOX("value", true) { private final CallMatcher UNBOXING_CALL = CallMatcher.anyOf( CallMatcher.exactInstanceCall(JAVA_LANG_INTEGER, "intValue").parameterCount(0), CallMatcher.exactInstanceCall(JAVA_LANG_LONG, "longValue").parameterCount(0), @@ -114,7 +154,7 @@ public enum SpecialField implements VariableDescriptor { return accessor instanceof PsiMethod && UNBOXING_CALL.methodMatches((PsiMethod)accessor); } }, - OPTIONAL_VALUE(null, "value", true) { + OPTIONAL_VALUE("value", true) { @Override public PsiType getType(DfaVariableValue variableValue) { return OptionalUtil.getOptionalElementType(variableValue.getType()); @@ -153,13 +193,11 @@ public enum SpecialField implements VariableDescriptor { }; private static final SpecialField[] VALUES = values(); - private final String myClassName; - private final String myMethodName; + private final String myTitle; private final boolean myFinal; - SpecialField(String className, String methodName, boolean isFinal) { - myClassName = className; - myMethodName = methodName; + SpecialField(String title, boolean isFinal) { + myTitle = title; myFinal = isFinal; } @@ -167,14 +205,8 @@ public enum SpecialField implements VariableDescriptor { public boolean isStable() { return myFinal; } - - public String getMethodName() { - return myMethodName; - } - boolean isMyQualifierType(PsiType type) { - return InheritanceUtil.isInheritor(type, myClassName); - } + abstract boolean isMyQualifierType(PsiType type); /** * Checks whether supplied accessor (field or method) can be used to read this special field @@ -182,9 +214,7 @@ public enum SpecialField implements VariableDescriptor { * @param accessor accessor to test to test * @return true if supplied accessor can be used to read this special field */ - boolean isMyAccessor(PsiMember accessor) { - return accessor instanceof PsiMethod && MethodUtils.methodMatches((PsiMethod)accessor, myClassName, null, myMethodName); - } + abstract boolean isMyAccessor(PsiMember accessor); public String getPresentationText(@NotNull DfaValue value, @Nullable PsiType type) { return value.toString(); @@ -336,6 +366,6 @@ public enum SpecialField implements VariableDescriptor { @Override public String toString() { - return myMethodName; + return myTitle; } } diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/inliner/CollectionFactoryInliner.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/inliner/CollectionFactoryInliner.java index 3f60e8506d9b..31becfbf04d3 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/inliner/CollectionFactoryInliner.java +++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/inliner/CollectionFactoryInliner.java @@ -26,7 +26,6 @@ import com.siyeh.ig.psiutils.MethodCallUtils; import org.jetbrains.annotations.NotNull; import static com.intellij.codeInspection.dataFlow.SpecialField.COLLECTION_SIZE; -import static com.intellij.codeInspection.dataFlow.SpecialField.MAP_SIZE; import static com.intellij.psi.CommonClassNames.*; import static com.siyeh.ig.callMatcher.CallMatcher.anyOf; import static com.siyeh.ig.callMatcher.CallMatcher.staticCall; @@ -35,24 +34,22 @@ public class CollectionFactoryInliner implements CallInliner { static final class FactoryInfo { final boolean myNotNull; final int mySize; - final SpecialField mySizeField; - FactoryInfo(int size, SpecialField sizeField) { - this(size, sizeField, false); + FactoryInfo(int size) { + this(size, false); } - FactoryInfo(int size, SpecialField sizeField, boolean notNull) { + FactoryInfo(int size, boolean notNull) { mySize = size; - mySizeField = sizeField; myNotNull = notNull; } } private static final CallMapper STATIC_FACTORIES = new CallMapper() - .register(staticCall(JAVA_UTIL_COLLECTIONS, "emptyList", "emptySet").parameterCount(0), new FactoryInfo(0, COLLECTION_SIZE)) - .register(staticCall(JAVA_UTIL_COLLECTIONS, "singletonList", "singleton").parameterCount(1), new FactoryInfo(1, COLLECTION_SIZE)) - .register(staticCall(JAVA_UTIL_COLLECTIONS, "emptyMap").parameterCount(0), new FactoryInfo(0, MAP_SIZE)) - .register(staticCall(JAVA_UTIL_COLLECTIONS, "singletonMap").parameterCount(2), new FactoryInfo(1, MAP_SIZE)); + .register(staticCall(JAVA_UTIL_COLLECTIONS, "emptyList", "emptySet").parameterCount(0), new FactoryInfo(0)) + .register(staticCall(JAVA_UTIL_COLLECTIONS, "singletonList", "singleton").parameterCount(1), new FactoryInfo(1)) + .register(staticCall(JAVA_UTIL_COLLECTIONS, "emptyMap").parameterCount(0), new FactoryInfo(0)) + .register(staticCall(JAVA_UTIL_COLLECTIONS, "singletonMap").parameterCount(2), new FactoryInfo(1)); private static final CallMatcher JDK9_MAP_FACTORIES = staticCall(JAVA_UTIL_MAP, "of", "ofEntries"); @@ -73,13 +70,13 @@ public class CollectionFactoryInliner implements CallInliner { if (JDK9_FACTORIES.test(call)) { int size = JDK9_ARRAY_FACTORIES.test(call) && !MethodCallUtils.isVarArgCall(call) ? -1 : call.getArgumentList().getExpressionCount(); - return new FactoryInfo(size, COLLECTION_SIZE, true); + return new FactoryInfo(size, true); } if (JDK9_MAP_FACTORIES.test(call)) { boolean ofEntries = "ofEntries".equals(call.getMethodExpression().getReferenceName()); int size = ofEntries && !MethodCallUtils.isVarArgCall(call) ? -1 : call.getArgumentList().getExpressionCount() / (ofEntries ? 1 : 2); - return new FactoryInfo(size, MAP_SIZE, true); + return new FactoryInfo(size, true); } return null; } @@ -97,7 +94,7 @@ public class CollectionFactoryInliner implements CallInliner { } DfaValueFactory factory = builder.getFactory(); SpecialFieldValue sizeConstraint = - factoryInfo.mySize == -1 ? null : factoryInfo.mySizeField.withValue(factory.getInt(factoryInfo.mySize)); + factoryInfo.mySize == -1 ? null : COLLECTION_SIZE.withValue(factory.getInt(factoryInfo.mySize)); DfaFactMap facts = DfaFactMap.EMPTY .with(DfaFactType.TYPE_CONSTRAINT, factory.createDfaType(callType).asConstraint()) .with(DfaFactType.NULLABILITY, DfaNullability.NOT_NULL) diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/inliner/CollectionMethodInliner.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/inliner/CollectionMethodInliner.java new file mode 100644 index 000000000000..3a1348a734f9 --- /dev/null +++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/inliner/CollectionMethodInliner.java @@ -0,0 +1,42 @@ +// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. +package com.intellij.codeInspection.dataFlow.inliner; + +import com.intellij.codeInspection.dataFlow.CFGBuilder; +import com.intellij.codeInspection.dataFlow.SpecialField; +import com.intellij.codeInspection.dataFlow.value.DfaValueFactory; +import com.intellij.psi.PsiExpression; +import com.intellij.psi.PsiMethodCallExpression; +import com.siyeh.ig.callMatcher.CallMatcher; +import org.jetbrains.annotations.NotNull; + +import static com.intellij.psi.CommonClassNames.JAVA_UTIL_COLLECTION; +import static com.intellij.psi.CommonClassNames.JAVA_UTIL_MAP; +import static com.siyeh.ig.callMatcher.CallMatcher.anyOf; +import static com.siyeh.ig.callMatcher.CallMatcher.instanceCall; + +public class CollectionMethodInliner implements CallInliner { + private static final CallMatcher CLEAR = anyOf(instanceCall(JAVA_UTIL_COLLECTION, "clear").parameterCount(0), + instanceCall(JAVA_UTIL_MAP, "clear").parameterCount(0)); + + @Override + public boolean tryInlineCall(@NotNull CFGBuilder builder, @NotNull PsiMethodCallExpression call) { + PsiExpression qualifier = call.getMethodExpression().getQualifierExpression(); + if (qualifier == null) return false; + if (CLEAR.matches(call)) { + inlineClear(builder, qualifier); + return true; + } + return false; + } + + private static void inlineClear(@NotNull CFGBuilder builder, @NotNull PsiExpression qualifier) { + DfaValueFactory factory = builder.getFactory(); + builder + .pushExpression(qualifier) + .unwrap(SpecialField.COLLECTION_SIZE) + .push(factory.getInt(0)) + .assign() + .pop() + .pushUnknown(); + } +} diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/inliner/MapUpdateInliner.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/inliner/MapUpdateInliner.java index 964204f8f59f..5ed4fbd7e1f8 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/inliner/MapUpdateInliner.java +++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/inliner/MapUpdateInliner.java @@ -88,7 +88,7 @@ public class MapUpdateInliner implements CallInliner { private static void flushSize(PsiExpression qualifier, CFGBuilder builder) { DfaValueFactory factory = builder.getFactory(); DfaValue value = factory.createValue(qualifier); - DfaValue size = SpecialField.MAP_SIZE.createValue(factory, value); + DfaValue size = SpecialField.COLLECTION_SIZE.createValue(factory, value); builder.assignAndPop(size, DfaUnknownValue.getInstance()); } diff --git a/java/java-tests/testData/inspection/dataFlow/fixture/ClearZeroesSize.java b/java/java-tests/testData/inspection/dataFlow/fixture/ClearZeroesSize.java new file mode 100644 index 000000000000..b06534242283 --- /dev/null +++ b/java/java-tests/testData/inspection/dataFlow/fixture/ClearZeroesSize.java @@ -0,0 +1,20 @@ +import java.util.*; + +class X { + void test(Collection c, List l, Map map) { + if(map.isEmpty()) {} + map.clear(); + if(map.isEmpty()) {} + if(map.keySet().isEmpty()) {} + if(map.values().isEmpty()) {} + if(map.entrySet().isEmpty()) {} + + if(c.isEmpty()) {} + c.clear(); + if(c.isEmpty()) {} + if(l.isEmpty()) {} + l.clear(); + if(l.isEmpty()) {} + } + +} \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/java/codeInspection/DataFlowInspection8Test.java b/java/java-tests/testSrc/com/intellij/java/codeInspection/DataFlowInspection8Test.java index 11db0a8c1321..804a47106d02 100644 --- a/java/java-tests/testSrc/com/intellij/java/codeInspection/DataFlowInspection8Test.java +++ b/java/java-tests/testSrc/com/intellij/java/codeInspection/DataFlowInspection8Test.java @@ -248,4 +248,5 @@ public class DataFlowInspection8Test extends DataFlowInspectionTestCase { public void testLambdaAfterNullCheck() { doTest(); } public void testFlatMapSideEffect() { doTest(); } public void testOptionalValueTracking() { doTest(); } + public void testClearZeroesSize() { doTest(); } } \ No newline at end of file diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/redundancy/RedundantOperationOnEmptyContainerInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/redundancy/RedundantOperationOnEmptyContainerInspection.java index 5d9b4bc91273..71ec588d9380 100644 --- a/plugins/InspectionGadgets/src/com/siyeh/ig/redundancy/RedundantOperationOnEmptyContainerInspection.java +++ b/plugins/InspectionGadgets/src/com/siyeh/ig/redundancy/RedundantOperationOnEmptyContainerInspection.java @@ -96,7 +96,7 @@ public class RedundantOperationOnEmptyContainerInspection extends AbstractBaseJa lengthField = SpecialField.COLLECTION_SIZE; message = InspectionsBundle.message("inspection.redundant.operation.on.empty.collection.message"); } else if (InheritanceUtil.isInheritor(type, JAVA_UTIL_MAP)) { - lengthField = SpecialField.MAP_SIZE; + lengthField = SpecialField.COLLECTION_SIZE; message = InspectionsBundle.message("inspection.redundant.operation.on.empty.map.message"); } else { return null; diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/redundancy/redundant_operation_on_empty_container/IterationOverEmptyContainer.java b/plugins/InspectionGadgets/test/com/siyeh/igtest/redundancy/redundant_operation_on_empty_container/IterationOverEmptyContainer.java index 28f2b8e78357..e2b67dc01094 100644 --- a/plugins/InspectionGadgets/test/com/siyeh/igtest/redundancy/redundant_operation_on_empty_container/IterationOverEmptyContainer.java +++ b/plugins/InspectionGadgets/test/com/siyeh/igtest/redundancy/redundant_operation_on_empty_container/IterationOverEmptyContainer.java @@ -69,4 +69,12 @@ class ForEachOverEmpty { System.out.println("hello"); } } -} \ No newline at end of file +} +class MapSubCollections { + void testMap(Map map) { + if(!map.isEmpty()) return; + for(String s : map.keySet()) {} + for(String s : map.values()) {} + for(Map.Entry s : map.entrySet()) {} + } +} diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/redundancy/redundant_operation_on_empty_container/MethodCallsOnEmptyContainer.java b/plugins/InspectionGadgets/test/com/siyeh/igtest/redundancy/redundant_operation_on_empty_container/MethodCallsOnEmptyContainer.java index c2bf4a101def..d8f292da5245 100644 --- a/plugins/InspectionGadgets/test/com/siyeh/igtest/redundancy/redundant_operation_on_empty_container/MethodCallsOnEmptyContainer.java +++ b/plugins/InspectionGadgets/test/com/siyeh/igtest/redundancy/redundant_operation_on_empty_container/MethodCallsOnEmptyContainer.java @@ -11,23 +11,50 @@ class Calls { void testCollection() { List list = Collections.emptyList(); list.clear(); + + list = Collections.emptyList(); list.remove("foo"); + + list = Collections.emptyList(); list.replaceAll(String::trim); + + list = Collections.emptyList(); list.forEach(System.out::println); + + list = Collections.emptyList(); list.iterator(); + + list = Collections.emptyList(); list.spliterator(); + + list = Collections.emptyList(); list.sort(null); } void testMap() { Map map = Collections.emptyMap(); map.get("foo"); + + map = Collections.emptyMap(); map.remove("foo"); + + map = Collections.emptyMap(); map.remove("foo", "bar"); + + map = Collections.emptyMap(); map.replace("foo", "bar"); + + map = Collections.emptyMap(); map.replace("foo", "bar", "baz"); + + map = Collections.emptyMap(); map.forEach((k, v) -> { }); } + void testClear(List list) { + list.clear(); + list.clear(); + } + } \ No newline at end of file diff --git a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/redundancy/RedundantOperationOnEmptyContainerInspectionTest.java b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/redundancy/RedundantOperationOnEmptyContainerInspectionTest.java index a5d9a6e0b5a3..e1f68d86d581 100644 --- a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/redundancy/RedundantOperationOnEmptyContainerInspectionTest.java +++ b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/redundancy/RedundantOperationOnEmptyContainerInspectionTest.java @@ -11,7 +11,7 @@ public class RedundantOperationOnEmptyContainerInspectionTest extends LightInspe @NotNull @Override protected LightProjectDescriptor getProjectDescriptor() { - return JAVA_8; + return JAVA_8_ANNOTATED; } public void testIterationOverEmptyContainer() {