Java: When generating return statement where the returned type is an array use raw type in array creation (IDEA-163341)

This commit is contained in:
Pavel Dolgov
2017-01-30 13:37:29 +03:00
parent 853c8cb41f
commit 14b3a1b38f
8 changed files with 62 additions and 8 deletions
@@ -24,6 +24,7 @@ import com.intellij.psi.*;
import com.intellij.psi.util.InheritanceUtil;
import com.intellij.psi.util.PsiTypesUtil;
import com.intellij.psi.util.PsiUtil;
import com.intellij.psi.util.TypeConversionUtil;
import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -88,7 +89,13 @@ public class AddReturnFix implements IntentionAction {
}
// then try to find a conversion of local variable to the required type
for (PsiVariable variable : variables) {
String conversion = getConversionToType(variable, type);
String conversion = getConversionToType(variable, type, true);
if (conversion != null) {
return conversion;
}
}
for (PsiVariable variable : variables) {
String conversion = getConversionToType(variable, type, false);
if (conversion != null) {
return conversion;
}
@@ -96,19 +103,22 @@ public class AddReturnFix implements IntentionAction {
return PsiTypesUtil.getDefaultValueOfType(type);
}
private String getConversionToType(@NotNull PsiVariable variable, @Nullable PsiType type) {
private String getConversionToType(@NotNull PsiVariable variable, @Nullable PsiType type, boolean preciseTypeReqired) {
PsiType varType = variable.getType();
if (type instanceof PsiArrayType) {
PsiType arrayComponentType = ((PsiArrayType)type).getComponentType();
if (!(arrayComponentType instanceof PsiPrimitiveType) &&
!(PsiUtil.resolveClassInType(arrayComponentType) instanceof PsiTypeParameter) &&
InheritanceUtil.isInheritor(varType, CommonClassNames.JAVA_UTIL_COLLECTION)) {
PsiType collectionItemType = JavaGenericsUtil.getCollectionItemType(varType, myMethod.getResolveScope());
if (collectionItemType != null && arrayComponentType.isAssignableFrom(collectionItemType)) {
if (arrayComponentType.equalsToText(CommonClassNames.JAVA_LANG_OBJECT)) {
return variable.getName() + ".toArray()";
PsiType erasedComponentType = TypeConversionUtil.erasure(arrayComponentType);
if (!preciseTypeReqired || arrayComponentType.equals(erasedComponentType)) {
PsiType collectionItemType = JavaGenericsUtil.getCollectionItemType(varType, myMethod.getResolveScope());
if (collectionItemType != null && erasedComponentType.isAssignableFrom(collectionItemType)) {
if (erasedComponentType.equalsToText(CommonClassNames.JAVA_LANG_OBJECT)) {
return variable.getName() + ".toArray()";
}
return variable.getName() + ".toArray(new " + erasedComponentType.getCanonicalText() + "[0])";
}
return variable.getName() + ".toArray(new " + arrayComponentType.getCanonicalText() + "[0])";
}
}
}
@@ -74,10 +74,11 @@ public class PsiTypesUtil {
}
}
PsiType erasedComponentType = TypeConversionUtil.erasure(componentType);
StringBuilder buffer = new StringBuilder();
buffer.append(PsiKeyword.NEW);
buffer.append(" ");
buffer.append(componentType.getCanonicalText());
buffer.append(erasedComponentType.getCanonicalText());
buffer.append("[0]");
for (int i = 0; i < count; i++) {
buffer.append("[]");
@@ -0,0 +1,8 @@
// "Add 'return' statement" "true"
import java.util.*;
class A<T> {
List<T>[] f(T a, T b) {
List<List<T>> list = Arrays.asList(Collections.singletonList(a), Collections.singletonList(b));
return list.toArray(new List[0]);
}
}
@@ -0,0 +1,7 @@
// "Add 'return' statement" "true"
import java.util.*;
class A<T> {
List<T>[] f() {
return new List[0];
}
}
@@ -0,0 +1,8 @@
// "Add 'return' statement" "true"
import java.util.*;
class A<T> {
Object[] f() {
List<T> list = new ArrayList<>();
return list.toArray();
}
}
@@ -0,0 +1,7 @@
// "Add 'return' statement" "true"
import java.util.*;
class A<T> {
List<T>[] f(T a, T b) {
List<List<T>> list = Arrays.asList(Collections.singletonList(a), Collections.singletonList(b));
<caret>}
}
@@ -0,0 +1,6 @@
// "Add 'return' statement" "true"
import java.util.*;
class A<T> {
List<T>[] f() {
<caret>}
}
@@ -0,0 +1,7 @@
// "Add 'return' statement" "true"
import java.util.*;
class A<T> {
Object[] f() {
List<T> list = new ArrayList<>();
<caret>}
}