mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
CollectionUtils#isCollectionOrMapSize
Used in ToArrayCallWithZeroLengthArrayArgumentInspection and StreamApiMigrationInspection
This commit is contained in:
+9
-14
@@ -299,11 +299,7 @@ class CollectMigration extends BaseStreamApiMigration {
|
||||
AddingTerminal terminal = new AddingTerminal(variable, tb.getVariable(), call, tb.getStreamSourceStatement(), status);
|
||||
if (count == null) return terminal;
|
||||
// like "list.add(x); if(list.size() >= limit) break;"
|
||||
if (!(count instanceof PsiMethodCallExpression)) return null;
|
||||
PsiMethodCallExpression sizeCall = (PsiMethodCallExpression)count;
|
||||
PsiExpression sizeQualifier = sizeCall.getMethodExpression().getQualifierExpression();
|
||||
if (isCallOf(sizeCall, CommonClassNames.JAVA_UTIL_COLLECTION, "size") &&
|
||||
EquivalenceChecker.getCanonicalPsiEquivalence().expressionsAreEquivalent(sizeQualifier, qualifierExpression) &&
|
||||
if (CollectionUtils.isCollectionOrMapSize(count, qualifierExpression) &&
|
||||
InheritanceUtil.isInheritor(PsiUtil.resolveClassInClassTypeOnly(variable.getType()), CommonClassNames.JAVA_UTIL_LIST)) {
|
||||
return terminal;
|
||||
}
|
||||
@@ -824,13 +820,13 @@ class CollectMigration extends BaseStreamApiMigration {
|
||||
return null;
|
||||
}
|
||||
PsiLocalVariable var = tryCast(PsiUtil.skipParenthesizedExprUp(toArrayCandidate.getParent()), PsiLocalVariable.class);
|
||||
String supplier = extractSupplier(toArrayCandidate, terminal);
|
||||
String supplier = extractSupplier(toArrayCandidate);
|
||||
if (supplier == null) return null;
|
||||
return new ToArrayTerminal(terminal, var, intermediateSteps, toArrayCandidate, supplier);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
static String extractSupplier(PsiMethodCallExpression toArrayCandidate, CollectTerminal terminal) {
|
||||
static String extractSupplier(PsiMethodCallExpression toArrayCandidate) {
|
||||
// collection.toArray() or collection.toArray(new Type[0]) or collection.toArray(new Type[collection.size()]);
|
||||
PsiExpression[] args = toArrayCandidate.getArgumentList().getExpressions();
|
||||
if (args.length == 0) return "";
|
||||
@@ -841,13 +837,12 @@ class CollectMigration extends BaseStreamApiMigration {
|
||||
String name = arrayType.getCanonicalText();
|
||||
PsiExpression[] dimensions = newArray.getArrayDimensions();
|
||||
if (dimensions.length != 1) return null;
|
||||
if (ExpressionUtils.isZero(dimensions[0])) return name+"::new";
|
||||
if (!(dimensions[0] instanceof PsiMethodCallExpression)) return null;
|
||||
PsiMethodCallExpression maybeSizeCall = (PsiMethodCallExpression)dimensions[0];
|
||||
if (!isCallOf(maybeSizeCall, CommonClassNames.JAVA_UTIL_COLLECTION, "size")) return null;
|
||||
PsiExpression sizeQualifier = maybeSizeCall.getMethodExpression().getQualifierExpression();
|
||||
if (!terminal.isTargetReference(sizeQualifier)) return null;
|
||||
return name+"::new";
|
||||
PsiExpression qualifier = toArrayCandidate.getMethodExpression().getQualifierExpression();
|
||||
if (ExpressionUtils.isZero(dimensions[0]) ||
|
||||
(qualifier != null && CollectionUtils.isCollectionOrMapSize(dimensions[0], qualifier))) {
|
||||
return name + "::new";
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+15
-4
@@ -631,14 +631,25 @@ public class StreamApiMigrationInspection extends AbstractBaseJavaLocalInspectio
|
||||
PsiExpression dimension = ArrayUtil.getFirstElement(initializer.getArrayDimensions());
|
||||
if (dimension == null) return null;
|
||||
PsiExpression bound = loop.myBound;
|
||||
if (!PsiEquivalenceUtil.areElementsEquivalent(dimension, bound) &&
|
||||
!ExpressionUtils.isReferenceTo(ExpressionUtils.getArrayFromLengthExpression(bound), arrayVariable)) {
|
||||
return null;
|
||||
}
|
||||
if (!isArrayLength(arrayVariable, dimension, bound)) return null;
|
||||
if (VariableAccessUtils.variableIsUsed(arrayVariable, assignment.getRExpression())) return null;
|
||||
return arrayVariable;
|
||||
}
|
||||
|
||||
private static boolean isArrayLength(PsiLocalVariable arrayVariable, PsiExpression dimension, PsiExpression bound) {
|
||||
if (ExpressionUtils.isReferenceTo(ExpressionUtils.getArrayFromLengthExpression(bound), arrayVariable)) return true;
|
||||
if (PsiEquivalenceUtil.areElementsEquivalent(dimension, bound)) return true;
|
||||
if (bound instanceof PsiMethodCallExpression) {
|
||||
PsiExpression qualifier = ((PsiMethodCallExpression)bound).getMethodExpression().getQualifierExpression();
|
||||
if (qualifier != null && CollectionUtils.isCollectionOrMapSize(dimension, qualifier)) return true;
|
||||
}
|
||||
if (dimension instanceof PsiMethodCallExpression) {
|
||||
PsiExpression qualifier = ((PsiMethodCallExpression)dimension).getMethodExpression().getQualifierExpression();
|
||||
if (qualifier != null && CollectionUtils.isCollectionOrMapSize(bound, qualifier)) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Intermediate stream operation representation
|
||||
*/
|
||||
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
// "Replace with toArray" "true"
|
||||
import java.util.*;
|
||||
import java.util.stream.IntStream;
|
||||
|
||||
public class Main {
|
||||
public String[] test(Map<String, String> map) {
|
||||
String[] array = IntStream.range(0, map.size()).mapToObj(String::valueOf).toArray(String[]::new);
|
||||
return array;
|
||||
}
|
||||
}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
// "Replace with toArray" "true"
|
||||
import java.util.*;
|
||||
|
||||
public class Main {
|
||||
public String[] test(Map<String, String> map) {
|
||||
String[] array = new String[map.size()];
|
||||
for(int<caret> i=0; i<map.keySet().size(); i++) {
|
||||
array[i] = String.valueOf(i);
|
||||
}
|
||||
return array;
|
||||
}
|
||||
}
|
||||
+45
@@ -15,9 +15,12 @@
|
||||
*/
|
||||
package com.siyeh.ig.psiutils;
|
||||
|
||||
import com.intellij.codeInsight.PsiEquivalenceUtil;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.util.InheritanceUtil;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
import com.intellij.util.ObjectUtils;
|
||||
import com.siyeh.ig.callMatcher.CallMatcher;
|
||||
import org.jetbrains.annotations.Contract;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -26,6 +29,16 @@ import org.jetbrains.annotations.Nullable;
|
||||
import java.util.*;
|
||||
|
||||
public class CollectionUtils {
|
||||
private static final CallMatcher COLLECTION_MAP_SIZE =
|
||||
CallMatcher.anyOf(
|
||||
CallMatcher.instanceCall(CommonClassNames.JAVA_UTIL_COLLECTION, "size").parameterCount(0),
|
||||
CallMatcher.instanceCall(CommonClassNames.JAVA_UTIL_MAP, "size").parameterCount(0));
|
||||
private static final CallMatcher DERIVED_COLLECTION =
|
||||
CallMatcher.anyOf(
|
||||
CallMatcher.instanceCall(CommonClassNames.JAVA_UTIL_MAP, "keySet", "values", "entrySet").parameterCount(0),
|
||||
CallMatcher.instanceCall("java.util.NavigableMap", "descendingKeySet", "descendingMap", "navigableKeySet").parameterCount(0),
|
||||
CallMatcher.instanceCall("java.util.NavigableSet", "descendingSet").parameterCount(0)
|
||||
);
|
||||
|
||||
/**
|
||||
* @noinspection StaticCollection
|
||||
@@ -244,4 +257,36 @@ public class CollectionUtils {
|
||||
}
|
||||
return s_interfaceForCollection.get(baseName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether supplied expression represents a collection size. It handles some derived collections,
|
||||
* e.g. it's known that {@code map.size()} is the size of {@code map.keySet()}.
|
||||
*
|
||||
* @param expression expression to test
|
||||
* @param collection expected collection or map expression
|
||||
* @return true if the supplied expression represents a collection size
|
||||
*/
|
||||
@Contract("null, _ -> false")
|
||||
public static boolean isCollectionOrMapSize(@Nullable PsiExpression expression, @NotNull PsiExpression collection) {
|
||||
PsiMethodCallExpression sizeCall = ObjectUtils.tryCast(PsiUtil.skipParenthesizedExprDown(expression), PsiMethodCallExpression.class);
|
||||
if (!COLLECTION_MAP_SIZE.test(sizeCall)) return false;
|
||||
PsiExpression sizeQualifier = sizeCall.getMethodExpression().getQualifierExpression();
|
||||
if (sizeQualifier == null) return false;
|
||||
sizeQualifier = getBaseCollection(sizeQualifier);
|
||||
collection = getBaseCollection(collection);
|
||||
return PsiEquivalenceUtil.areElementsEquivalent(sizeQualifier, collection);
|
||||
}
|
||||
|
||||
private static @NotNull PsiExpression getBaseCollection(@NotNull PsiExpression derivedCollection) {
|
||||
while(true) {
|
||||
PsiMethodCallExpression derivedCall =
|
||||
ObjectUtils.tryCast(PsiUtil.skipParenthesizedExprDown(derivedCollection), PsiMethodCallExpression.class);
|
||||
if (DERIVED_COLLECTION.test(derivedCall)) {
|
||||
derivedCollection = ExpressionUtils.getQualifierOrThis(derivedCall.getMethodExpression());
|
||||
}
|
||||
else {
|
||||
return derivedCollection;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+1
-10
@@ -15,7 +15,6 @@
|
||||
*/
|
||||
package com.siyeh.ig.performance;
|
||||
|
||||
import com.intellij.codeInsight.PsiEquivalenceUtil;
|
||||
import com.intellij.codeInspection.ProblemDescriptor;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.ui.VerticalFlowLayout;
|
||||
@@ -34,8 +33,6 @@ import org.jetbrains.annotations.*;
|
||||
import javax.swing.*;
|
||||
|
||||
public class ToArrayCallWithZeroLengthArrayArgumentInspection extends BaseInspection {
|
||||
private static final CallMatcher COLLECTION_SIZE =
|
||||
CallMatcher.instanceCall(CommonClassNames.JAVA_UTIL_COLLECTION, "size").parameterCount(0);
|
||||
private static final CallMatcher COLLECTION_TO_ARRAY =
|
||||
CallMatcher.instanceCall(CommonClassNames.JAVA_UTIL_COLLECTION, "toArray").parameterCount(1);
|
||||
|
||||
@@ -143,13 +140,7 @@ public class ToArrayCallWithZeroLengthArrayArgumentInspection extends BaseInspec
|
||||
if (newExpression == null) return false;
|
||||
PsiExpression[] dimensions = newExpression.getArrayDimensions();
|
||||
if (dimensions.length != 1) return false;
|
||||
PsiMethodCallExpression maybeSizeCall =
|
||||
ObjectUtils.tryCast(PsiUtil.skipParenthesizedExprDown(dimensions[0]), PsiMethodCallExpression.class);
|
||||
if (COLLECTION_SIZE.test(maybeSizeCall)) {
|
||||
PsiExpression sizeQualifier = maybeSizeCall.getMethodExpression().getQualifierExpression();
|
||||
return sizeQualifier != null && PsiEquivalenceUtil.areElementsEquivalent(sizeQualifier, qualifier);
|
||||
}
|
||||
return false;
|
||||
return CollectionUtils.isCollectionOrMapSize(dimensions[0], qualifier);
|
||||
}
|
||||
|
||||
private static class ToArrayCallWithZeroLengthArrayArgumentFix extends InspectionGadgetsFix {
|
||||
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
package com.siyeh.igfixes.performance.to_array_call_with_zero_length_array_argument;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
class IntroduceVariable {
|
||||
String[] keys(Map<String, String> map) {
|
||||
return map.keySet().toArray(new String[0]);
|
||||
}
|
||||
}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
package com.siyeh.igfixes.performance.to_array_call_with_zero_length_array_argument;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
class IntroduceVariable {
|
||||
String[] keys(Map<String, String> map) {
|
||||
return map.keySet().toAr<caret>ray(new String[map.size()]);
|
||||
}
|
||||
}
|
||||
+4
@@ -37,6 +37,10 @@ public class ToArrayCallWithZeroLengthArrayArgumentFixTest extends IGQuickFixesT
|
||||
doFixTest(PreferEmptyArray.ALWAYS, InspectionGadgetsBundle.message("to.array.call.style.quickfix.make.zero"));
|
||||
}
|
||||
|
||||
public void testPresizedToZeroMap() {
|
||||
doFixTest(PreferEmptyArray.ALWAYS, InspectionGadgetsBundle.message("to.array.call.style.quickfix.make.zero"));
|
||||
}
|
||||
|
||||
private void doFixTest(PreferEmptyArray mode, String message) {
|
||||
myInspection.myMode = mode;
|
||||
doTest(getTestName(false), message);
|
||||
|
||||
Reference in New Issue
Block a user