mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
IDEA-106008 ('convert variable argument parameter to array' action generates uncompilable code in case of parametrized vararg)
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2003-2011 Dave Griffith, Bas Leijdekkers
|
||||
* Copyright 2003-2013 Dave Griffith, Bas Leijdekkers
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -15,13 +15,13 @@
|
||||
*/
|
||||
package com.siyeh.ig.jdk;
|
||||
|
||||
import com.intellij.codeInsight.AnnotationUtil;
|
||||
import com.intellij.codeInspection.ProblemDescriptor;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.codeStyle.CodeStyleManager;
|
||||
import com.intellij.psi.codeStyle.JavaCodeStyleManager;
|
||||
import com.intellij.psi.search.searches.ReferencesSearch;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import com.intellij.util.Query;
|
||||
import com.siyeh.InspectionGadgetsBundle;
|
||||
import com.siyeh.ig.BaseInspection;
|
||||
@@ -44,15 +44,13 @@ public class VarargParameterInspection extends BaseInspection {
|
||||
@Override
|
||||
@NotNull
|
||||
public String getDisplayName() {
|
||||
return InspectionGadgetsBundle.message(
|
||||
"variable.argument.method.display.name");
|
||||
return InspectionGadgetsBundle.message("variable.argument.method.display.name");
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public String buildErrorString(Object... infos) {
|
||||
return InspectionGadgetsBundle.message(
|
||||
"variable.argument.method.problem.descriptor");
|
||||
return InspectionGadgetsBundle.message("variable.argument.method.problem.descriptor");
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -65,27 +63,29 @@ public class VarargParameterInspection extends BaseInspection {
|
||||
|
||||
@NotNull
|
||||
public String getName() {
|
||||
return InspectionGadgetsBundle.message(
|
||||
"variable.argument.method.quickfix");
|
||||
return InspectionGadgetsBundle.message("variable.argument.method.quickfix");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doFix(Project project, ProblemDescriptor descriptor)
|
||||
throws IncorrectOperationException {
|
||||
protected void doFix(Project project, ProblemDescriptor descriptor) {
|
||||
final PsiElement element = descriptor.getPsiElement();
|
||||
final PsiMethod method = (PsiMethod)element.getParent();
|
||||
final PsiParameterList parameterList = method.getParameterList();
|
||||
final PsiParameter[] parameters = parameterList.getParameters();
|
||||
final PsiParameter lastParameter =
|
||||
parameters[parameters.length - 1];
|
||||
final PsiParameter lastParameter = parameters[parameters.length - 1];
|
||||
if (!lastParameter.isVarArgs()) {
|
||||
return;
|
||||
}
|
||||
final PsiEllipsisType type =
|
||||
(PsiEllipsisType)lastParameter.getType();
|
||||
final PsiEllipsisType type = (PsiEllipsisType)lastParameter.getType();
|
||||
final Query<PsiReference> query = ReferencesSearch.search(method);
|
||||
final PsiType componentType = type.getComponentType();
|
||||
final String typeText = componentType.getCanonicalText();
|
||||
final String typeText;
|
||||
if (componentType instanceof PsiClassType) {
|
||||
final PsiClassType classType = (PsiClassType)componentType;
|
||||
typeText = classType.rawType().getCanonicalText();
|
||||
} else {
|
||||
typeText = componentType.getCanonicalText();
|
||||
}
|
||||
final Collection<PsiReference> references = query.findAll();
|
||||
for (PsiReference reference : references) {
|
||||
modifyCalls(reference, typeText, parameters.length - 1);
|
||||
@@ -93,59 +93,48 @@ public class VarargParameterInspection extends BaseInspection {
|
||||
final PsiType arrayType = type.toArrayType();
|
||||
final PsiManager psiManager = lastParameter.getManager();
|
||||
final PsiElementFactory factory = JavaPsiFacade.getInstance(psiManager.getProject()).getElementFactory();
|
||||
final PsiTypeElement newTypeElement =
|
||||
factory.createTypeElement(arrayType);
|
||||
final PsiTypeElement typeElement =
|
||||
lastParameter.getTypeElement();
|
||||
final PsiTypeElement newTypeElement = factory.createTypeElement(arrayType);
|
||||
final PsiTypeElement typeElement = lastParameter.getTypeElement();
|
||||
if (typeElement == null) {
|
||||
return;
|
||||
}
|
||||
final PsiAnnotation annotation = AnnotationUtil.findAnnotation(method, "java.lang.SafeVarargs");
|
||||
if (annotation != null) {
|
||||
annotation.delete();
|
||||
}
|
||||
typeElement.replace(newTypeElement);
|
||||
}
|
||||
|
||||
public static void modifyCalls(PsiReference reference,
|
||||
String arrayTypeText,
|
||||
int indexOfFirstVarargArgument)
|
||||
throws IncorrectOperationException {
|
||||
final PsiReferenceExpression referenceExpression =
|
||||
(PsiReferenceExpression)reference.getElement();
|
||||
final PsiMethodCallExpression methodCallExpression =
|
||||
(PsiMethodCallExpression)referenceExpression.getParent();
|
||||
final PsiExpressionList argumentList =
|
||||
methodCallExpression.getArgumentList();
|
||||
public static void modifyCalls(PsiReference reference, String arrayTypeText, int indexOfFirstVarargArgument) {
|
||||
final PsiReferenceExpression referenceExpression = (PsiReferenceExpression)reference.getElement();
|
||||
final PsiMethodCallExpression methodCallExpression = (PsiMethodCallExpression)referenceExpression.getParent();
|
||||
final PsiExpressionList argumentList = methodCallExpression.getArgumentList();
|
||||
final PsiExpression[] arguments = argumentList.getExpressions();
|
||||
@NonNls final StringBuilder builder = new StringBuilder("new ");
|
||||
builder.append(arrayTypeText);
|
||||
builder.append("[]{");
|
||||
if (arguments.length > indexOfFirstVarargArgument) {
|
||||
final PsiExpression firstArgument =
|
||||
arguments[indexOfFirstVarargArgument];
|
||||
final PsiExpression firstArgument = arguments[indexOfFirstVarargArgument];
|
||||
final String firstArgumentText = firstArgument.getText();
|
||||
builder.append(firstArgumentText);
|
||||
for (int i = indexOfFirstVarargArgument + 1;
|
||||
i < arguments.length; i++) {
|
||||
builder.append(',');
|
||||
builder.append(arguments[i].getText());
|
||||
for (int i = indexOfFirstVarargArgument + 1; i < arguments.length; i++) {
|
||||
builder.append(',').append(arguments[i].getText());
|
||||
}
|
||||
}
|
||||
builder.append('}');
|
||||
final Project project = referenceExpression.getProject();
|
||||
final PsiElementFactory factory =
|
||||
JavaPsiFacade.getElementFactory(project);
|
||||
final PsiExpression arrayExpression =
|
||||
factory.createExpressionFromText(builder.toString(),
|
||||
referenceExpression);
|
||||
final PsiElementFactory factory = JavaPsiFacade.getElementFactory(project);
|
||||
final PsiExpression arrayExpression = factory.createExpressionFromText(builder.toString(), referenceExpression);
|
||||
if (arguments.length > indexOfFirstVarargArgument) {
|
||||
final PsiExpression firstArgument =
|
||||
arguments[indexOfFirstVarargArgument];
|
||||
argumentList.deleteChildRange(firstArgument,
|
||||
arguments[arguments.length - 1]);
|
||||
final PsiExpression firstArgument = arguments[indexOfFirstVarargArgument];
|
||||
argumentList.deleteChildRange(firstArgument, arguments[arguments.length - 1]);
|
||||
argumentList.add(arrayExpression);
|
||||
}
|
||||
else {
|
||||
argumentList.add(arrayExpression);
|
||||
}
|
||||
final CodeStyleManager codeStyleManager =
|
||||
CodeStyleManager.getInstance(project);
|
||||
final JavaCodeStyleManager javaCodeStyleManager =
|
||||
JavaCodeStyleManager.getInstance(project);
|
||||
final CodeStyleManager codeStyleManager = CodeStyleManager.getInstance(project);
|
||||
final JavaCodeStyleManager javaCodeStyleManager = JavaCodeStyleManager.getInstance(project);
|
||||
javaCodeStyleManager.shortenClassReferences(argumentList);
|
||||
codeStyleManager.reformat(argumentList);
|
||||
}
|
||||
@@ -165,8 +154,7 @@ public class VarargParameterInspection extends BaseInspection {
|
||||
return;
|
||||
}
|
||||
final PsiParameter[] parameters = parameterList.getParameters();
|
||||
final PsiParameter lastParameter =
|
||||
parameters[parameters.length - 1];
|
||||
final PsiParameter lastParameter = parameters[parameters.length - 1];
|
||||
if (lastParameter.isVarArgs()) {
|
||||
registerMethodError(method);
|
||||
}
|
||||
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
package com.siyeh.igfixes.jdk.vararg_parameter;
|
||||
|
||||
@SuppressWarnings("UnusedDeclaration")
|
||||
public class GenericType {
|
||||
final void addClasses(Class<? extends Number>[] classes) {
|
||||
}
|
||||
|
||||
void test() {
|
||||
addClasses(new Class[]{Number.class, Byte.class});
|
||||
}
|
||||
}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
package com.siyeh.igfixes.jdk.vararg_parameter;
|
||||
|
||||
@SuppressWarnings("UnusedDeclaration")
|
||||
public class GenericType {
|
||||
@java.lang.SafeVarargs
|
||||
final void addCl<caret>asses(Class<? extends Number>... classes) {
|
||||
}
|
||||
|
||||
void test() {
|
||||
addClasses(Number.class, Byte.class);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package com.siyeh.ig.fixes.jdk;
|
||||
|
||||
import com.siyeh.InspectionGadgetsBundle;
|
||||
import com.siyeh.ig.IGQuickFixesTestCase;
|
||||
import com.siyeh.ig.jdk.VarargParameterInspection;
|
||||
|
||||
public class VarargParameterFixTest extends IGQuickFixesTestCase {
|
||||
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
myFixture.enableInspections(new VarargParameterInspection());
|
||||
myRelativePath = "jdk/vararg_parameter";
|
||||
myDefaultHint = InspectionGadgetsBundle.message("variable.argument.method.quickfix");
|
||||
}
|
||||
|
||||
public void testGenericType() { doTest(); }
|
||||
}
|
||||
Reference in New Issue
Block a user