diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/miscGenerics/SuspiciousMethodCallUtil.java b/java/java-analysis-impl/src/com/intellij/codeInspection/miscGenerics/SuspiciousMethodCallUtil.java index e5dc66ace264..d127536c7673 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInspection/miscGenerics/SuspiciousMethodCallUtil.java +++ b/java/java-analysis-impl/src/com/intellij/codeInspection/miscGenerics/SuspiciousMethodCallUtil.java @@ -31,6 +31,7 @@ public class SuspiciousMethodCallUtil { final PsiClass collectionClass = javaPsiFacade.findClass(CommonClassNames.JAVA_UTIL_COLLECTION, searchScope); PsiClassType object = PsiType.getJavaLangObject(manager, searchScope); PsiType[] javaLangObject = {object}; + PsiType[] twoObjects = {object, object}; MethodSignature removeSignature = MethodSignatureUtil.createMethodSignature("remove", javaLangObject, PsiTypeParameter.EMPTY_ARRAY, PsiSubstitutor.EMPTY); if (collectionClass != null) { @@ -69,7 +70,7 @@ public class SuspiciousMethodCallUtil { } MethodSignature removeWithDefaultSignature = MethodSignatureUtil.createMethodSignature("remove", - new PsiType[]{object, object}, + twoObjects, PsiTypeParameter.EMPTY_ARRAY, PsiSubstitutor.EMPTY); PsiMethod removeWithDefault = MethodSignatureUtil.findMethodBySignature(mapClass, removeWithDefaultSignature, false); addMethod(removeWithDefault, 0, patternMethods, 0); @@ -88,6 +89,91 @@ public class SuspiciousMethodCallUtil { PsiMethod contains = MethodSignatureUtil.findMethodBySignature(concurrentMapClass, containsSignature, false); addMethod(contains, 1, patternMethods, 0); } + PsiClass guavaTable = javaPsiFacade.findClass("com.google.common.collect.Table", searchScope); + if (guavaTable != null) { + MethodSignature getSignature = + MethodSignatureUtil.createMethodSignature("get", twoObjects, PsiTypeParameter.EMPTY_ARRAY, PsiSubstitutor.EMPTY); + PsiMethod get = MethodSignatureUtil.findMethodBySignature(guavaTable, getSignature, false); + addMethod(get, 0, patternMethods, 0); + addMethod(get, 1, patternMethods, 1); + + MethodSignature containsSignature = + MethodSignatureUtil.createMethodSignature("contains", twoObjects, PsiTypeParameter.EMPTY_ARRAY, PsiSubstitutor.EMPTY); + PsiMethod contains = MethodSignatureUtil.findMethodBySignature(guavaTable, containsSignature, false); + addMethod(contains, 0, patternMethods, 0); + addMethod(contains, 1, patternMethods, 1); + + MethodSignature containsRowSignature = + MethodSignatureUtil.createMethodSignature("containsRow", javaLangObject, PsiTypeParameter.EMPTY_ARRAY, PsiSubstitutor.EMPTY); + PsiMethod containsRow = MethodSignatureUtil.findMethodBySignature(guavaTable, containsRowSignature, false); + addMethod(containsRow, 0, patternMethods, 0); + + MethodSignature containsColumnSignature = + MethodSignatureUtil.createMethodSignature("containsColumn", javaLangObject, PsiTypeParameter.EMPTY_ARRAY, PsiSubstitutor.EMPTY); + PsiMethod containsColumn = MethodSignatureUtil.findMethodBySignature(guavaTable, containsColumnSignature, false); + addMethod(containsColumn, 1, patternMethods, 0); + + MethodSignature containsValueSignature = + MethodSignatureUtil.createMethodSignature("containsValue", javaLangObject, PsiTypeParameter.EMPTY_ARRAY, PsiSubstitutor.EMPTY); + PsiMethod containsValue = MethodSignatureUtil.findMethodBySignature(guavaTable, containsValueSignature, false); + addMethod(containsValue, 2, patternMethods, 0); + + MethodSignature removeByRowAndColumnSignature = + MethodSignatureUtil.createMethodSignature("remove", twoObjects, PsiTypeParameter.EMPTY_ARRAY, PsiSubstitutor.EMPTY); + PsiMethod removeByRowAndColumn = MethodSignatureUtil.findMethodBySignature(guavaTable, removeByRowAndColumnSignature, false); + addMethod(removeByRowAndColumn, 0, patternMethods, 0); + addMethod(removeByRowAndColumn, 1, patternMethods, 1); + } + + PsiClass guavaMultimap = javaPsiFacade.findClass("com.google.common.collect.Multimap", searchScope); + if (guavaMultimap != null) { + MethodSignature containsKeySignature = + MethodSignatureUtil.createMethodSignature("containsKey", javaLangObject, PsiTypeParameter.EMPTY_ARRAY, PsiSubstitutor.EMPTY); + PsiMethod containsKey = MethodSignatureUtil.findMethodBySignature(guavaMultimap, containsKeySignature, false); + addMethod(containsKey, 0, patternMethods, 0); + + MethodSignature containsValueSignature = + MethodSignatureUtil.createMethodSignature("containsValue", javaLangObject, PsiTypeParameter.EMPTY_ARRAY, PsiSubstitutor.EMPTY); + PsiMethod containsValue = MethodSignatureUtil.findMethodBySignature(guavaMultimap, containsValueSignature, false); + addMethod(containsValue, 1, patternMethods, 0); + + MethodSignature containsEntrySignature = + MethodSignatureUtil.createMethodSignature("containsEntry", twoObjects, PsiTypeParameter.EMPTY_ARRAY, PsiSubstitutor.EMPTY); + PsiMethod containsEntry = MethodSignatureUtil.findMethodBySignature(guavaMultimap, containsEntrySignature, false); + addMethod(containsEntry, 0, patternMethods, 0); + addMethod(containsEntry, 1, patternMethods, 1); + + MethodSignature removeByKeyAndValueSignature = + MethodSignatureUtil.createMethodSignature("remove", twoObjects, PsiTypeParameter.EMPTY_ARRAY, PsiSubstitutor.EMPTY); + PsiMethod removeByKeyAndValue = MethodSignatureUtil.findMethodBySignature(guavaMultimap, removeByKeyAndValueSignature, false); + addMethod(removeByKeyAndValue, 0, patternMethods, 0); + addMethod(removeByKeyAndValue, 1, patternMethods, 1); + + MethodSignature removeAllSignature = + MethodSignatureUtil.createMethodSignature("removeAll", javaLangObject, PsiTypeParameter.EMPTY_ARRAY, PsiSubstitutor.EMPTY); + PsiMethod removeAll = MethodSignatureUtil.findMethodBySignature(guavaMultimap, removeAllSignature, false); + addMethod(removeAll, 0, patternMethods, 0); + } + + PsiClass guavaMultiset = javaPsiFacade.findClass("com.google.common.collect.Multiset", searchScope); + if (guavaMultiset != null) { + MethodSignature countSignature = + MethodSignatureUtil.createMethodSignature("count", javaLangObject, PsiTypeParameter.EMPTY_ARRAY, PsiSubstitutor.EMPTY); + PsiMethod count = MethodSignatureUtil.findMethodBySignature(guavaMultiset, countSignature, false); + addMethod(count, 0, patternMethods, 0); + } + + PsiClass guavaCache = javaPsiFacade.findClass("com.google.common.cache.Cache", searchScope); + if (guavaCache != null) { + MethodSignature getIfPresentSignature = + MethodSignatureUtil.createMethodSignature("getIfPresent", javaLangObject, PsiTypeParameter.EMPTY_ARRAY, PsiSubstitutor.EMPTY); + PsiMethod getIfPresent = MethodSignatureUtil.findMethodBySignature(guavaCache, getIfPresentSignature, false); + addMethod(getIfPresent, 0, patternMethods, 0); + MethodSignature invalidateSignature = + MethodSignatureUtil.createMethodSignature("invalidate", javaLangObject, PsiTypeParameter.EMPTY_ARRAY, PsiSubstitutor.EMPTY); + PsiMethod invalidate = MethodSignatureUtil.findMethodBySignature(guavaCache, invalidateSignature, false); + addMethod(invalidate, 0, patternMethods, 0); + } } private static void addSingleParameterMethod(List patternMethods, diff --git a/java/java-tests/testData/inspection/suspiciousCalls/Guava.java b/java/java-tests/testData/inspection/suspiciousCalls/Guava.java new file mode 100644 index 000000000000..22ce24865fd0 --- /dev/null +++ b/java/java-tests/testData/inspection/suspiciousCalls/Guava.java @@ -0,0 +1,57 @@ +package com.google.common.collect; +import com.google.common.cache.Cache; + +import java.util.Collection; + +class Guava { + public static void main(Table table, + Multimap multimap, + Multiset multiset, + Cache cache + ) { + table.get(new Object(), 12); + table.get("11", new Object()); + table.contains(new Object(), 10); + table.contains("9", new Object()); + table.containsRow(new Object()); + table.containsColumn(new Object()); + table.containsValue(new Object()); + table.remove(new Object(), 8); + table.remove("7", new Object()); + + multimap.containsKey(new Object()); + multimap.containsValue(new Object()); + multimap.containsEntry(new Object(), 6L); + multimap.containsEntry("5", new Object()); + multimap.remove(new Object(), 4L); + multimap.remove("3", new Object()); + multimap.removeAll(new Object()); + + multiset.count(new Object()); + multiset.remove(new Object()); + + cache.getIfPresent(new Object()); + cache.invalidate(new Object()); + } +} + +interface Table { + V get(Object r, Object c); + boolean contains(Object r, Object c); + boolean containsRow(Object r); + boolean containsColumn(Object c); + boolean containsValue(Object v); + V remove(Object r, Object c); +} + +interface Multimap { + boolean containsKey(Object k); + boolean containsValue(Object v); + boolean containsEntry(Object k, Object v); + boolean remove(Object k, Object v); + Collection removeAll(Object k); +} + +interface Multiset extends Collection { + int count(Object o); +} \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/java/codeInspection/SuspiciousCollectionMethodCallsTest.java b/java/java-tests/testSrc/com/intellij/java/codeInspection/SuspiciousCollectionMethodCallsTest.java index c4b82e881c71..ab95a34220e9 100644 --- a/java/java-tests/testSrc/com/intellij/java/codeInspection/SuspiciousCollectionMethodCallsTest.java +++ b/java/java-tests/testSrc/com/intellij/java/codeInspection/SuspiciousCollectionMethodCallsTest.java @@ -46,6 +46,11 @@ public class SuspiciousCollectionMethodCallsTest extends LightCodeInsightFixture public void testSetList() { doTest(); } public void testUseDfa() { doTest(); } public void testWildcard() { doTest(); } + public void testGuava() { + myFixture.addClass("package com.google.common.cache;" + + "public interface Cache {V getIfPresent(Object k);void invalidate(Object k);}"); + doTest(); + } public void testPolyConditionalExpressionPassedToMapGetCall() { doTest(); } public void testNewExpressionPassedToMapContains() { doTest(); } public void testIgnoreConvertible() {