IDEA-161925 Stream API migration: support toArray conversion, fixed mapping to initialized array, fixed final variable status, clean up in RefactoringUtil

This commit is contained in:
Tagir Valeev
2016-09-30 16:12:57 +07:00
parent e3d794ad99
commit 738994f1c0
26 changed files with 459 additions and 29 deletions
@@ -97,6 +97,36 @@ class ReplaceWithCollectFix extends MigrateToStreamFix {
if(status != InitializerUsageStatus.UNKNOWN) {
PsiExpression initializer = variable.getInitializer();
LOG.assertTrue(initializer != null);
PsiMethodCallExpression toArrayExpression =
StreamApiMigrationInspection.extractToArrayExpression(foreachStatement, methodCallExpression);
if(toArrayExpression != null) {
PsiType type = initializer.getType();
if(type instanceof PsiClassType) {
String replacement = StreamApiMigrationInspection.COLLECTION_TO_ARRAY.get(((PsiClassType)type).rawType().getCanonicalText());
if(replacement != null) {
builder.append(".").append(replacement);
PsiExpression[] args = toArrayExpression.getArgumentList().getExpressions();
if(args.length == 0) {
builder.append("()");
} else {
if(args.length != 1 || !(args[0] instanceof PsiNewExpression)) return;
PsiNewExpression newArray = (PsiNewExpression)args[0];
PsiType arrayType = newArray.getType();
if(arrayType == null) return;
String name = arrayType.getCanonicalText();
builder.append('(').append(name).append("::new)");
}
PsiElement result =
toArrayExpression.replace(elementFactory.createExpressionFromText(builder.toString(), toArrayExpression));
removeLoop(foreachStatement);
if(status != InitializerUsageStatus.AT_WANTED_PLACE) {
variable.delete();
}
simplifyAndFormat(project, result);
return;
}
}
}
String callText = builder.append(".collect(java.util.stream.Collectors.")
.append(createInitializerReplacementText(qualifierExpression.getType(), initializer))
.append(")").toString();
@@ -39,7 +39,9 @@ import com.intellij.util.ArrayUtil;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.containers.IntArrayList;
import com.siyeh.ig.psiutils.BoolUtils;
import com.siyeh.ig.psiutils.EquivalenceChecker;
import com.siyeh.ig.psiutils.ExpressionUtils;
import one.util.streamex.EntryStream;
import one.util.streamex.StreamEx;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.Nls;
@@ -57,6 +59,14 @@ import static com.intellij.codeInspection.streamMigration.StreamApiMigrationInsp
public class StreamApiMigrationInspection extends BaseJavaBatchLocalInspectionTool {
private static final Logger LOG = Logger.getInstance("#" + StreamApiMigrationInspection.class.getName());
static final Map<String, String> COLLECTION_TO_ARRAY = EntryStream.of(
CommonClassNames.JAVA_UTIL_ARRAY_LIST, "toArray",
"java.util.LinkedList", "toArray",
CommonClassNames.JAVA_UTIL_HASH_SET, "distinct().toArray",
"java.util.LinkedHashSet", "distinct().toArray",
"java.util.TreeSet", "distinct().sorted().toArray"
).toMap();
public boolean REPLACE_TRIVIAL_FOREACH;
public boolean SUGGEST_FOREACH;
@@ -433,7 +443,8 @@ public class StreamApiMigrationInspection extends BaseJavaBatchLocalInspectionTo
int start = controlFlow.getEndOffset(declaration);
int stop = controlFlow.getStartOffset(nextStatement);
if(ControlFlowUtil.isVariableReferencedBetween(controlFlow, start, stop, var)) return UNKNOWN;
return ControlFlowUtil.isValueUsedWithoutVisitingStop(controlFlow, start, stop, var) ? AT_WANTED_PLACE : AT_WANTED_PLACE_ONLY;
if (!ControlFlowUtil.isValueUsedWithoutVisitingStop(controlFlow, start, stop, var)) return AT_WANTED_PLACE_ONLY;
return var.hasModifierProperty(PsiModifier.FINAL) ? UNKNOWN : AT_WANTED_PLACE;
}
static boolean isDeclarationJustBefore(PsiVariable var, PsiStatement nextStatement) {
@@ -522,7 +533,10 @@ public class StreamApiMigrationInspection extends BaseJavaBatchLocalInspectionTo
} else {
PsiMethodCallExpression methodCallExpression = tb.getSingleMethodCall();
if(canCollect(statement, methodCallExpression)) {
methodName = "collect";
if(extractToArrayExpression(statement, methodCallExpression) != null)
methodName = "toArray";
else
methodName = "collect";
} else {
if (!SUGGEST_FOREACH) return;
methodName = "forEach";
@@ -658,6 +672,73 @@ public class StreamApiMigrationInspection extends BaseJavaBatchLocalInspectionTo
}
}
@Nullable
static PsiMethodCallExpression extractToArrayExpression(PsiForeachStatement statement, PsiMethodCallExpression expression) {
// return collection.toArray() or collection.toArray(new Type[0]) or collection.toArray(new Type[collection.size()]);
PsiElement nextElement = PsiTreeUtil.skipSiblingsForward(statement, PsiComment.class, PsiWhiteSpace.class);
PsiExpression toArrayCandidate;
if (nextElement instanceof PsiReturnStatement) {
toArrayCandidate = ((PsiReturnStatement)nextElement).getReturnValue();
}
else {
PsiAssignmentExpression assignment = ExpressionUtils.getAssignment(nextElement);
if (assignment != null) {
toArrayCandidate = assignment.getRExpression();
}
else if (nextElement instanceof PsiDeclarationStatement) {
PsiElement[] elements = ((PsiDeclarationStatement)nextElement).getDeclaredElements();
if (elements.length == 1 && elements[0] instanceof PsiLocalVariable) {
toArrayCandidate = ((PsiLocalVariable)elements[0]).getInitializer();
}
else {
return null;
}
}
else {
return null;
}
}
if (!(toArrayCandidate instanceof PsiMethodCallExpression)) return null;
PsiMethodCallExpression call = (PsiMethodCallExpression)toArrayCandidate;
PsiReferenceExpression methodExpression = call.getMethodExpression();
if (!"toArray".equals(methodExpression.getReferenceName())) return null;
PsiExpression qualifierExpression = methodExpression.getQualifierExpression();
if (!(qualifierExpression instanceof PsiReferenceExpression)) return null;
PsiLocalVariable collectionVariable = extractCollectionVariable(expression.getMethodExpression().getQualifierExpression());
if (collectionVariable == null || ((PsiReferenceExpression)qualifierExpression).resolve() != collectionVariable) return null;
PsiExpression initializer = collectionVariable.getInitializer();
if (initializer == null) return null;
PsiType type = initializer.getType();
if (!(type instanceof PsiClassType) || !COLLECTION_TO_ARRAY.containsKey(((PsiClassType)type).rawType().getCanonicalText())) {
return null;
}
if (!(nextElement instanceof PsiReturnStatement) && !ReferencesSearch.search(collectionVariable, collectionVariable.getUseScope())
.forEach(ref ->
ref.getElement() == collectionVariable || PsiTreeUtil.isAncestor(statement, ref.getElement(), false) ||
PsiTreeUtil.isAncestor(toArrayCandidate, ref.getElement(), false)
)) {
return null;
}
PsiExpression[] args = call.getArgumentList().getExpressions();
if (args.length == 0) return call;
if (args.length != 1 || !(args[0] instanceof PsiNewExpression)) return null;
PsiNewExpression newArray = (PsiNewExpression)args[0];
PsiExpression[] dimensions = newArray.getArrayDimensions();
if (dimensions.length != 1) return null;
if (ExpressionUtils.isLiteral(dimensions[0], 0)) return call;
if (!(dimensions[0] instanceof PsiMethodCallExpression)) return null;
PsiMethodCallExpression maybeSizeCall = (PsiMethodCallExpression)dimensions[0];
if (maybeSizeCall.getArgumentList().getExpressions().length != 0) return null;
PsiReferenceExpression maybeSizeExpression = maybeSizeCall.getMethodExpression();
if (!"size".equals(maybeSizeExpression.getReferenceName()) || !EquivalenceChecker.getCanonicalPsiEquivalence()
.expressionsAreEquivalent(qualifierExpression, maybeSizeExpression.getQualifierExpression())) {
return null;
}
return call;
}
/**
* Intermediate stream operation representation
*/
@@ -735,7 +816,8 @@ public class StreamApiMigrationInspection extends BaseJavaBatchLocalInspectionTo
} else if(myVariable.getType() instanceof PsiPrimitiveType) {
operationName = "mapToObj";
}
return "." + operationName + "(" + LambdaUtil.createLambda(myVariable, myExpression) + ")";
PsiExpression expression = myType == null ? myExpression : ExpressionUtils.convertInitializerToNormalExpression(myExpression, myType);
return "." + operationName + "(" + LambdaUtil.createLambda(myVariable, expression) + ")";
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
* Copyright 2000-2016 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -38,7 +38,6 @@ import com.intellij.psi.*;
import com.intellij.psi.codeStyle.CodeStyleManager;
import com.intellij.psi.codeStyle.JavaCodeStyleManager;
import com.intellij.psi.codeStyle.VariableKind;
import com.intellij.psi.controlFlow.ControlFlowUtil;
import com.intellij.psi.javadoc.PsiDocComment;
import com.intellij.psi.javadoc.PsiDocTag;
import com.intellij.psi.javadoc.PsiDocTagValue;
@@ -53,7 +52,9 @@ import com.intellij.refactoring.introduceVariable.IntroduceVariableBase;
import com.intellij.util.IncorrectOperationException;
import com.intellij.util.containers.HashMap;
import com.intellij.util.containers.HashSet;
import com.siyeh.ig.psiutils.ExpressionUtils;
import gnu.trove.THashMap;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -129,7 +130,7 @@ public class RefactoringUtil {
}
/**
* @see com.intellij.psi.codeStyle.CodeStyleManager#suggestUniqueVariableName(String, com.intellij.psi.PsiElement, boolean)
* @see JavaCodeStyleManager#suggestUniqueVariableName(String, PsiElement, boolean)
* Cannot use method from code style manager: a collision with fieldToReplace is not a collision
*/
public static String suggestUniqueVariableName(String baseName, PsiElement place, PsiField fieldToReplace) {
@@ -197,11 +198,7 @@ public class RefactoringUtil {
final PsiImportList importList = ((PsiJavaFile)element.getContainingFile()).getImportList();
if (importList != null) {
final PsiImportStaticStatement[] importStaticStatements = importList.getImportStaticStatements();
for(PsiImportStaticStatement stmt: importStaticStatements) {
if (stmt.isOnDemand() && stmt.resolveTargetClass() == aClass) {
return true;
}
}
return Arrays.stream(importStaticStatements).anyMatch(stmt -> stmt.isOnDemand() && stmt.resolveTargetClass() == aClass);
}
}
return false;
@@ -390,7 +387,7 @@ public class RefactoringUtil {
if (type != null && !isFunctionalType && isDenotable) {
return type;
}
ExpectedTypeInfo[] expectedTypes = ExpectedTypesProvider.getInstance(expr.getProject()).getExpectedTypes(expr, false);
ExpectedTypeInfo[] expectedTypes = ExpectedTypesProvider.getExpectedTypes(expr, false);
if (expectedTypes.length == 1 || (isFunctionalType || !isDenotable)&& expectedTypes.length > 0 ) {
type = expectedTypes[0].getType();
if (!type.equalsToText(CommonClassNames.JAVA_LANG_OBJECT)) return type;
@@ -413,7 +410,7 @@ public class RefactoringUtil {
private static PsiType getTypeByExpression(PsiExpression expr, final PsiElementFactory factory) {
PsiType type = RefactoringChangeUtil.getTypeByExpression(expr);
if (PsiType.NULL.equals(type)) {
ExpectedTypeInfo[] infos = ExpectedTypesProvider.getInstance(expr.getProject()).getExpectedTypes(expr, false);
ExpectedTypeInfo[] infos = ExpectedTypesProvider.getExpectedTypes(expr, false);
if (infos.length == 1) {
type = infos[0].getType();
}
@@ -663,7 +660,8 @@ public class RefactoringUtil {
return result;
}
public static PsiExpression convertInitializerToNormalExpression(PsiExpression expression, PsiType forcedReturnType)
@Contract("null, _ -> null")
public static PsiExpression convertInitializerToNormalExpression(@Nullable PsiExpression expression, @Nullable PsiType forcedReturnType)
throws IncorrectOperationException {
if (expression instanceof PsiArrayInitializerExpression && (forcedReturnType == null || forcedReturnType instanceof PsiArrayType)) {
return createNewExpressionFromArrayInitializer((PsiArrayInitializerExpression)expression, forcedReturnType);
@@ -671,8 +669,8 @@ public class RefactoringUtil {
return expression;
}
public static PsiExpression createNewExpressionFromArrayInitializer(PsiArrayInitializerExpression initializer, PsiType forcedType)
throws IncorrectOperationException {
public static PsiExpression createNewExpressionFromArrayInitializer(PsiArrayInitializerExpression initializer,
@Nullable PsiType forcedType) throws IncorrectOperationException {
PsiType initializerType = null;
if (initializer != null) {
if (forcedType != null) {
@@ -686,14 +684,7 @@ public class RefactoringUtil {
return initializer;
}
LOG.assertTrue(initializerType instanceof PsiArrayType);
PsiElementFactory factory = JavaPsiFacade.getInstance(initializer.getProject()).getElementFactory();
PsiNewExpression result =
(PsiNewExpression)factory.createExpressionFromText("new " + initializerType.getPresentableText() + "{}", null);
result = (PsiNewExpression)CodeStyleManager.getInstance(initializer.getProject()).reformat(result);
PsiArrayInitializerExpression arrayInitializer = result.getArrayInitializer();
LOG.assertTrue(arrayInitializer != null);
arrayInitializer.replace(initializer);
return result;
return ExpressionUtils.createNewExpressionFromArrayInitializer(initializer, (PsiArrayType)initializerType);
}
public static void makeMethodAbstract(@NotNull PsiClass targetClass, @NotNull PsiMethod method) throws IncorrectOperationException {
@@ -1100,13 +1091,13 @@ public class RefactoringUtil {
}
public static void fixJavadocsForParams(PsiMethod method, Set<PsiParameter> newParameters) throws IncorrectOperationException {
fixJavadocsForParams(method, newParameters, Conditions.<Pair<PsiParameter,String>>alwaysFalse());
fixJavadocsForParams(method, newParameters, Conditions.alwaysFalse());
}
public static void fixJavadocsForParams(PsiMethod method,
Set<PsiParameter> newParameters,
Condition<Pair<PsiParameter, String>> eqCondition) throws IncorrectOperationException {
fixJavadocsForParams(method, newParameters, eqCondition, Conditions.<String>alwaysTrue());
fixJavadocsForParams(method, newParameters, eqCondition, Conditions.alwaysTrue());
}
public static void fixJavadocsForParams(PsiMethod method,
@@ -1296,7 +1287,7 @@ public class RefactoringUtil {
@Nullable
public static PsiTypeParameterList createTypeParameterListWithUsedTypeParameters(@Nullable final PsiTypeParameterList fromList,
@NotNull final PsiElement... elements) {
return createTypeParameterListWithUsedTypeParameters(fromList, Conditions.<PsiTypeParameter>alwaysTrue(), elements);
return createTypeParameterListWithUsedTypeParameters(fromList, Conditions.alwaysTrue(), elements);
}
@Nullable
@@ -1317,7 +1308,7 @@ public class RefactoringUtil {
PsiTypeParameter[] typeParameters = used.toArray(new PsiTypeParameter[used.size()]);
Arrays.sort(typeParameters, (tp1, tp2) -> tp1.getTextRange().getStartOffset() - tp2.getTextRange().getStartOffset());
Arrays.sort(typeParameters, Comparator.comparingInt(tp -> tp.getTextRange().getStartOffset()));
final PsiElementFactory elementFactory = JavaPsiFacade.getInstance(elements[0].getProject()).getElementFactory();
try {
@@ -1337,7 +1328,7 @@ public class RefactoringUtil {
}
public static void collectTypeParameters(final Set<PsiTypeParameter> used, final PsiElement element) {
collectTypeParameters(used, element, Conditions.<PsiTypeParameter>alwaysTrue());
collectTypeParameters(used, element, Conditions.alwaysTrue());
}
public static void collectTypeParameters(final Set<PsiTypeParameter> used, final PsiElement element,
final Condition<PsiTypeParameter> filter) {
@@ -0,0 +1,10 @@
// "Replace with toArray" "true"
import java.util.ArrayList;
import java.util.List;
public class Main {
public Object[] testToArray(List<String> data) {
return data.stream().filter(str -> !str.isEmpty()).toArray();
}
}
@@ -0,0 +1,13 @@
// "Replace with toArray" "true"
import java.util.ArrayList;
import java.util.List;
public class Main {
public Object[] testToArray(List<String> data) {
Object[] arr;
arr = data.stream().filter(str -> !str.isEmpty()).toArray();
System.out.println(Arrays.toString(arr));
return arr;
}
}
@@ -0,0 +1,12 @@
// "Replace with toArray" "true"
import java.util.ArrayList;
import java.util.List;
public class Main {
public Object[] testToArray(List<String> data) {
Object[] arr = data.stream().filter(str -> !str.isEmpty()).toArray();
System.out.println(Arrays.toString(arr));
return arr;
}
}
@@ -0,0 +1,9 @@
// "Replace with toArray" "true"
import java.util.*;
public class Main {
public List<?>[] testToArray(List<String> data) {
return data.stream().filter(str -> !str.isEmpty()).map(Collections::singletonList).distinct().toArray(List<?>[]::new);
}
}
@@ -0,0 +1,9 @@
// "Replace with toArray" "true"
import java.util.*;
public class Main {
public String[] testToArray(List<String> data) {
return data.stream().filter(str -> !str.isEmpty()).distinct().toArray(String[]::new);
}
}
@@ -0,0 +1,9 @@
// "Replace with toArray" "true"
import java.util.*;
public class Main {
public CharSequence[] testToArray(List<String> data) {
return data.stream().filter(str -> !str.isEmpty()).distinct().toArray(CharSequence[]::new);
}
}
@@ -0,0 +1,14 @@
// "Replace with toArray" "true"
import java.util.*;
public class Main {
public String[] testToArray(List<String> data) {
Set<String> result = new LinkedHashSet<>();
if(!data.isEmpty()) {
return data.stream().filter(str -> !str.isEmpty()).map(String::trim).distinct().toArray(String[]::new);
}
result.add("None");
return result.toArray(new String[1]);
}
}
@@ -0,0 +1,9 @@
// "Replace with toArray" "true"
import java.util.*;
public class Main {
public Object[] testToArray(List<String> data) {
return data.stream().filter(str -> !str.isEmpty()).distinct().sorted().toArray(String[]::new);
}
}
@@ -0,0 +1,9 @@
// "Replace with toArray" "true"
import java.util.*;
public class Main {
public String[][] testToArray(List<String> data) {
return data.stream().filter(str -> !str.isEmpty()).map(str -> new String[]{str}).toArray(String[][]::new);
}
}
@@ -0,0 +1,20 @@
// "Replace with collect" "false"
import java.util.*;
public class Collect {
class Person {
String getName() {
return "";
}
}
void collectNames(List<Person> persons){
final Set<String> names = new HashSet<>(), other = new HashSet<>();
if(persons != null) {
for (Person person : pers<caret>ons) {
names.add(person.getName());
}
}
System.out.println(names);
}
}
@@ -0,0 +1,15 @@
// "Replace with toArray" "true"
import java.util.ArrayList;
import java.util.List;
public class Main {
public Object[] testToArray(List<String> data) {
List<String> result = new ArrayList<>();
for (String str : d<caret>ata) {
if (!str.isEmpty())
result.add(str);
}
return result.toArray();
}
}
@@ -0,0 +1,18 @@
// "Replace with toArray" "true"
import java.util.ArrayList;
import java.util.List;
public class Main {
public Object[] testToArray(List<String> data) {
Object[] arr;
List<String> result = new ArrayList<>();
for (String str : d<caret>ata) {
if (!str.isEmpty())
result.add(str);
}
arr = result.toArray();
System.out.println(Arrays.toString(arr));
return arr;
}
}
@@ -0,0 +1,17 @@
// "Replace with toArray" "true"
import java.util.ArrayList;
import java.util.List;
public class Main {
public Object[] testToArray(List<String> data) {
List<String> result = new ArrayList<>();
for (String str : d<caret>ata) {
if (!str.isEmpty())
result.add(str);
}
Object[] arr = result.toArray();
System.out.println(Arrays.toString(arr));
return arr;
}
}
@@ -0,0 +1,17 @@
// "Replace with toArray" "false"
import java.util.ArrayList;
import java.util.List;
public class Main {
public Object[] testToArray(List<String> data) {
List<String> result = new ArrayList<>();
for (String str : d<caret>ata) {
if (!str.isEmpty())
result.add(str);
}
Object[] arr = result.toArray();
System.out.println(result);
return arr;
}
}
@@ -0,0 +1,16 @@
// "Replace with toArray" "true"
import java.util.*;
public class Main {
public List<?>[] testToArray(List<String> data) {
Set<List<String>> result = new LinkedHashSet<>();
for (String str : dat<caret>a) {
if (!str.isEmpty()) {
List<String> list = Collections.singletonList(str);
result.add(list);
}
}
return result.toArray(new List<?>[0]);
}
}
@@ -0,0 +1,14 @@
// "Replace with toArray" "true"
import java.util.*;
public class Main {
public String[] testToArray(List<String> data) {
Set<String> result = new HashSet<>();
for (String str : d<caret>ata) {
if (!str.isEmpty())
result.add(str);
}
return result.toArray(new String[0]);
}
}
@@ -0,0 +1,15 @@
// "Replace with toArray" "false"
import java.util.ArrayList;
import java.util.List;
public class Main {
public Object[] testToArray(List<String> data) {
Set<String> result = new IdentityHashSet<>();
for (String str : d<caret>ata) {
if (!str.isEmpty())
result.add(str);
}
return result.toArray();
}
}
@@ -0,0 +1,14 @@
// "Replace with toArray" "true"
import java.util.*;
public class Main {
public CharSequence[] testToArray(List<String> data) {
Set<String> result = new LinkedHashSet<>();
for (String str : d<caret>ata) {
if (!str.isEmpty())
result.add(str);
}
return result.toArray(new CharSequence[result.size()]);
}
}
@@ -0,0 +1,19 @@
// "Replace with toArray" "true"
import java.util.*;
public class Main {
public String[] testToArray(List<String> data) {
Set<String> result = new LinkedHashSet<>();
if(!data.isEmpty()) {
for (String str : d<caret>ata) {
if (!str.isEmpty()) {
result.add(str.trim());
}
}
return result.toArray(new String[result.size()]);
}
result.add("None");
return result.toArray(new String[1]);
}
}
@@ -0,0 +1,14 @@
// "Replace with toArray" "true"
import java.util.*;
public class Main {
public Object[] testToArray(List<String> data) {
Set<String> result = new TreeSet<>();
for (String str : d<caret>ata) {
if (!str.isEmpty())
result.add(str);
}
return result.toArray(new String[result.size()]);
}
}
@@ -0,0 +1,16 @@
// "Replace with toArray" "true"
import java.util.*;
public class Main {
public String[][] testToArray(List<String> data) {
List<String[]> result = new ArrayList<>();
for (String str : dat<caret>a) {
if (!str.isEmpty()) {
String[] arr = {str};
result.add(arr);
}
}
return result.toArray(new String[result.size()][]);
}
}
@@ -0,0 +1,15 @@
// "Replace with toArray" "false"
import java.util.ArrayList;
import java.util.List;
public class Main {
public Object[] testToArray(List<String> data) {
List<String> result = new ArrayList<>();
for (String str : d<caret>ata) {
if (!str.isEmpty())
result.add(str);
}
return result.toArray(new String[10]);
}
}
@@ -17,8 +17,10 @@ package com.siyeh.ig.psiutils;
import com.intellij.codeInsight.AnnotationUtil;
import com.intellij.codeInsight.NullableNotNullManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import com.intellij.psi.*;
import com.intellij.psi.codeStyle.CodeStyleManager;
import com.intellij.psi.tree.IElementType;
import com.intellij.psi.util.ConstantExpressionUtil;
import com.intellij.psi.util.PsiTreeUtil;
@@ -35,6 +37,7 @@ import java.util.HashSet;
import java.util.Set;
public class ExpressionUtils {
private static final Logger LOG = Logger.getInstance(ExpressionUtils.class);
@NonNls static final Set<String> convertableBoxedClassNames = new HashSet<>(3);
static {
@@ -789,4 +792,24 @@ public class ExpressionUtils {
}
return true;
}
@Contract("null, _ -> null")
public static PsiExpression convertInitializerToNormalExpression(@Nullable PsiExpression expression, @NotNull PsiType forcedReturnType) {
if (expression instanceof PsiArrayInitializerExpression && forcedReturnType instanceof PsiArrayType) {
return createNewExpressionFromArrayInitializer((PsiArrayInitializerExpression)expression, (PsiArrayType)forcedReturnType);
}
return expression;
}
public static PsiExpression createNewExpressionFromArrayInitializer(@NotNull PsiArrayInitializerExpression initializer,
@NotNull PsiArrayType targetType) {
PsiElementFactory factory = JavaPsiFacade.getInstance(initializer.getProject()).getElementFactory();
PsiNewExpression result =
(PsiNewExpression)factory.createExpressionFromText("new " + targetType.getPresentableText() + "{}", null);
result = (PsiNewExpression)CodeStyleManager.getInstance(initializer.getProject()).reformat(result);
PsiArrayInitializerExpression arrayInitializer = result.getArrayInitializer();
LOG.assertTrue(arrayInitializer != null);
arrayInitializer.replace(initializer);
return result;
}
}