IDEA-113585 Cast to Type quick fix creates code that doesn't help

This commit is contained in:
Tagir Valeev
2017-09-19 16:10:34 +07:00
parent 6bb3451995
commit dede7b30f7
8 changed files with 95 additions and 12 deletions
@@ -298,7 +298,9 @@ public abstract class QuickFixFactory {
public abstract List<IntentionAction> createAddAnnotationAttributeNameFixes(@NotNull PsiNameValuePair pair);
@NotNull
public abstract IntentionAction createCollectionToArrayFix(@NotNull PsiExpression collectionExpression, @NotNull PsiArrayType arrayType);
public abstract IntentionAction createCollectionToArrayFix(@NotNull PsiExpression collectionExpression,
@NotNull PsiExpression expressionToReplace,
@NotNull PsiArrayType arrayType);
@NotNull
public abstract IntentionAction createInsertMethodCallFix(@NotNull PsiMethodCallExpression call, PsiMethod method);
@@ -30,6 +30,7 @@ import com.intellij.psi.*;
import com.intellij.psi.util.*;
import com.intellij.util.ArrayUtil;
import com.intellij.util.IncorrectOperationException;
import com.siyeh.ig.callMatcher.CallMatcher;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -42,6 +43,9 @@ public class HighlightFixUtil {
private static final QuickFixFactory QUICK_FIX_FACTORY = QuickFixFactory.getInstance();
private static final CallMatcher COLLECTION_TO_ARRAY =
CallMatcher.instanceCall(CommonClassNames.JAVA_UTIL_COLLECTION, "toArray").parameterCount(0);
static void registerCollectionToArrayFixAction(@Nullable HighlightInfo info,
@Nullable PsiType fromType,
@Nullable PsiType toType,
@@ -49,11 +53,25 @@ public class HighlightFixUtil {
if (toType instanceof PsiArrayType) {
PsiType arrayComponentType = ((PsiArrayType)toType).getComponentType();
if (!(arrayComponentType instanceof PsiPrimitiveType) &&
!(PsiUtil.resolveClassInType(arrayComponentType) instanceof PsiTypeParameter) &&
InheritanceUtil.isInheritor(fromType, CommonClassNames.JAVA_UTIL_COLLECTION)) {
PsiType collectionItemType = JavaGenericsUtil.getCollectionItemType(fromType, expression.getResolveScope());
if (collectionItemType != null && arrayComponentType.isAssignableFrom(collectionItemType)) {
QuickFixAction.registerQuickFixAction(info, QUICK_FIX_FACTORY.createCollectionToArrayFix(expression, (PsiArrayType)toType));
!(PsiUtil.resolveClassInType(arrayComponentType) instanceof PsiTypeParameter)) {
PsiExpression collection = expression;
if (expression instanceof PsiMethodCallExpression) {
PsiMethodCallExpression call = (PsiMethodCallExpression)expression;
if (COLLECTION_TO_ARRAY.test(call)) {
collection = call.getMethodExpression().getQualifierExpression();
if (collection == null) return;
fromType = collection.getType();
}
}
if (fromType instanceof PsiClassType &&
(CommonClassNames.JAVA_LANG_OBJECT.equals(arrayComponentType.getCanonicalText()) ||
!((PsiClassType)fromType).isRaw()) &&
InheritanceUtil.isInheritor(fromType, CommonClassNames.JAVA_UTIL_COLLECTION)) {
PsiType collectionItemType = JavaGenericsUtil.getCollectionItemType(fromType, expression.getResolveScope());
if (collectionItemType != null && arrayComponentType.isConvertibleFrom(collectionItemType)) {
QuickFixAction
.registerQuickFixAction(info, QUICK_FIX_FACTORY.createCollectionToArrayFix(collection, expression, (PsiArrayType)toType));
}
}
}
}
@@ -677,7 +677,9 @@ public class EmptyQuickFixFactory extends QuickFixFactory {
@NotNull
@Override
public IntentionAction createCollectionToArrayFix(@NotNull PsiExpression collectionExpression, @NotNull PsiArrayType arrayType) {
public IntentionAction createCollectionToArrayFix(@NotNull PsiExpression collectionExpression,
@NotNull PsiExpression expressionToReplace,
@NotNull PsiArrayType arrayType) {
return QuickFixes.EMPTY_FIX;
}
@@ -30,10 +30,14 @@ import org.jetbrains.annotations.NotNull;
*/
public class ConvertCollectionToArrayFix implements IntentionAction {
private final PsiExpression myCollectionExpression;
private final PsiExpression myExpressionToReplace;
private final String myNewArrayText;
public ConvertCollectionToArrayFix(@NotNull PsiExpression collectionExpression, @NotNull PsiArrayType arrayType) {
public ConvertCollectionToArrayFix(@NotNull PsiExpression collectionExpression,
@NotNull PsiExpression expressionToReplace,
@NotNull PsiArrayType arrayType) {
myCollectionExpression = collectionExpression;
myExpressionToReplace = expressionToReplace;
PsiType componentType = arrayType.getComponentType();
myNewArrayText = componentType.equalsToText(CommonClassNames.JAVA_LANG_OBJECT) ? "" : "new " + getArrayTypeText(componentType);
@@ -55,7 +59,8 @@ public class ConvertCollectionToArrayFix implements IntentionAction {
@Override
public boolean isAvailable(@NotNull Project project, Editor editor, PsiFile file) {
return myCollectionExpression.isValid() && PsiManager.getInstance(project).isInProject(myCollectionExpression);
return myCollectionExpression.isValid() && PsiManager.getInstance(project).isInProject(myCollectionExpression) &&
myExpressionToReplace.isValid() && PsiManager.getInstance(project).isInProject(myExpressionToReplace);
}
@Override
@@ -63,7 +68,7 @@ public class ConvertCollectionToArrayFix implements IntentionAction {
PsiElementFactory factory = JavaPsiFacade.getInstance(project).getElementFactory();
String replacement = ParenthesesUtils.getText(myCollectionExpression, ParenthesesUtils.POSTFIX_PRECEDENCE) +
".toArray(" + myNewArrayText + ")";
myCollectionExpression.replace(factory.createExpressionFromText(replacement, myCollectionExpression));
myExpressionToReplace.replace(factory.createExpressionFromText(replacement, myCollectionExpression));
}
@Override
@@ -867,8 +867,10 @@ public class QuickFixFactoryImpl extends QuickFixFactory {
@NotNull
@Override
public IntentionAction createCollectionToArrayFix(@NotNull PsiExpression collectionExpression, @NotNull PsiArrayType arrayType) {
return new ConvertCollectionToArrayFix(collectionExpression, arrayType);
public IntentionAction createCollectionToArrayFix(@NotNull PsiExpression collectionExpression,
@NotNull PsiExpression expressionToReplace,
@NotNull PsiArrayType arrayType) {
return new ConvertCollectionToArrayFix(collectionExpression, expressionToReplace, arrayType);
}
@NotNull
@@ -0,0 +1,22 @@
// "Apply conversion '.toArray(new Test.User[0])'" "true"
import java.util.List;
class Test {
interface User {
}
interface Query {
List<?> getResultList();
}
public User[] getAllUsers(Query readQuery) {
List<?> result = readQuery.getResultList();
return (result != null) ? result.toArray(new User[0]) : new User[0];
}
public static void main(String[] args) {
}
}
@@ -0,0 +1,10 @@
// "Apply conversion '.toArray(new java.lang.String[0])'" "false"
import java.util.*;
class Return {
String[] foo() {
List<Number> list = new ArrayList<>();
list.add(1);
return list<caret>;
}
}
@@ -0,0 +1,22 @@
// "Apply conversion '.toArray(new Test.User[0])'" "true"
import java.util.List;
class Test {
interface User {
}
interface Query {
List<?> getResultList();
}
public User[] getAllUsers(Query readQuery) {
List<?> result = readQuery.getResultList();
return (result != null) ? result.toAr<caret>ray() : new User[0];
}
public static void main(String[] args) {
}
}