mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-18 09:34:34 +07:00
create from usage: extract used type params from deep levels (IDEA-87564)
This commit is contained in:
-16
@@ -249,22 +249,6 @@ public class CreateMethodFromUsageFix extends CreateFromUsageBaseFix {
|
||||
PsiDocumentManager.getInstance(project).commitDocument(newEditor.getDocument());
|
||||
final int offset = newEditor.getCaretModel().getOffset();
|
||||
PsiMethod method = PsiTreeUtil.findElementOfClassAtOffset(targetFile, offset - 1, PsiMethod.class, false);
|
||||
if (context instanceof PsiMethod) {
|
||||
final PsiTypeParameter[] typeParameters = ((PsiMethod)context).getTypeParameters();
|
||||
if (typeParameters.length > 0) {
|
||||
for (PsiTypeParameter typeParameter : typeParameters) {
|
||||
if (checkTypeParam( method, typeParameter)) {
|
||||
final JVMElementFactory factory = JVMElementFactories.getFactory(method.getLanguage(), method.getProject());
|
||||
PsiTypeParameterList list = method.getTypeParameterList();
|
||||
if (list == null) {
|
||||
PsiTypeParameterList newList = factory.createTypeParameterList();
|
||||
list = (PsiTypeParameterList)method.addAfter(newList, method.getModifierList());
|
||||
}
|
||||
list.add(factory.createTypeParameter(typeParameter.getName(),typeParameter.getExtendsList().getReferencedTypes()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (method != null) {
|
||||
try {
|
||||
CreateFromUsageUtils.setupMethodBody(method);
|
||||
|
||||
@@ -21,6 +21,7 @@ import com.intellij.codeInsight.template.Expression;
|
||||
import com.intellij.codeInsight.template.ExpressionContext;
|
||||
import com.intellij.codeInsight.template.PsiTypeResult;
|
||||
import com.intellij.codeInsight.template.Result;
|
||||
import com.intellij.codeInsight.template.impl.JavaTemplateUtil;
|
||||
import com.intellij.openapi.editor.Document;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.psi.*;
|
||||
@@ -50,7 +51,11 @@ public class TypeExpression extends Expression {
|
||||
return type == null? null : new PsiTypeResult(type, project) {
|
||||
@Override
|
||||
public void handleRecalc(PsiFile psiFile, Document document, int segmentStart, int segmentEnd) {
|
||||
if (myItems.size() <= 1) super.handleRecalc(psiFile, document, segmentStart, segmentEnd);
|
||||
if (myItems.size() <= 1) {
|
||||
super.handleRecalc(psiFile, document, segmentStart, segmentEnd);
|
||||
} else {
|
||||
JavaTemplateUtil.updateTypeBindings(getType(), psiFile, document, segmentStart, segmentEnd, true);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -29,6 +29,8 @@ import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
public class JavaTemplateUtil {
|
||||
@@ -38,42 +40,71 @@ public class JavaTemplateUtil {
|
||||
}
|
||||
|
||||
public static void updateTypeBindings(Object item, PsiFile file, final Document document, final int segmentStart, final int segmentEnd) {
|
||||
updateTypeBindings(item, file, document, segmentStart, segmentEnd, false);
|
||||
}
|
||||
|
||||
public static void updateTypeBindings(Object item,
|
||||
PsiFile file,
|
||||
final Document document,
|
||||
final int segmentStart,
|
||||
final int segmentEnd,
|
||||
boolean noImport) {
|
||||
final Project project = file.getProject();
|
||||
PsiClass aClass = null;
|
||||
List<PsiClass> classes = new ArrayList<PsiClass>();
|
||||
if (item instanceof PsiClass) {
|
||||
aClass = (PsiClass)item;
|
||||
classes.add((PsiClass)item);
|
||||
}
|
||||
else if (item instanceof PsiType) {
|
||||
aClass = PsiUtil.resolveClassInType((PsiType)item);
|
||||
else if (item instanceof PsiClassType) {
|
||||
PsiClass aClass = PsiUtil.resolveClassInType((PsiType)item);
|
||||
if (aClass != null) {
|
||||
classes.add(aClass);
|
||||
}
|
||||
collectClassParams((PsiType)item, classes);
|
||||
}
|
||||
|
||||
if (aClass != null) {
|
||||
if (aClass instanceof PsiTypeParameter) {
|
||||
if (((PsiTypeParameter)aClass).getOwner() instanceof PsiMethod) {
|
||||
PsiElement element = file.findElementAt(segmentStart);
|
||||
PsiMethod method = PsiTreeUtil.getParentOfType(element, PsiMethod.class);
|
||||
if (method != null) {
|
||||
PsiTypeParameterList paramList = method.getTypeParameterList();
|
||||
PsiTypeParameter[] params = paramList != null ? paramList.getTypeParameters() : PsiTypeParameter.EMPTY_ARRAY;
|
||||
for (PsiTypeParameter param : params) {
|
||||
if (param.getName().equals(aClass.getName())) return;
|
||||
}
|
||||
try {
|
||||
if (paramList == null) {
|
||||
final PsiTypeParameterList newList = JVMElementFactories.getFactory(method.getLanguage(), project).createTypeParameterList();
|
||||
paramList = (PsiTypeParameterList)method.addAfter(newList, method.getModifierList());
|
||||
if (!classes.isEmpty()) {
|
||||
for (PsiClass aClass : classes) {
|
||||
if (aClass instanceof PsiTypeParameter) {
|
||||
if (((PsiTypeParameter)aClass).getOwner() instanceof PsiMethod) {
|
||||
PsiElement element = file.findElementAt(segmentStart);
|
||||
PsiMethod method = PsiTreeUtil.getParentOfType(element, PsiMethod.class);
|
||||
if (method != null) {
|
||||
PsiTypeParameterList paramList = method.getTypeParameterList();
|
||||
PsiTypeParameter[] params = paramList != null ? paramList.getTypeParameters() : PsiTypeParameter.EMPTY_ARRAY;
|
||||
for (PsiTypeParameter param : params) {
|
||||
if (param.getName().equals(aClass.getName())) return;
|
||||
}
|
||||
try {
|
||||
if (paramList == null) {
|
||||
final PsiTypeParameterList newList = JVMElementFactories.getFactory(method.getLanguage(), project).createTypeParameterList();
|
||||
paramList = (PsiTypeParameterList)method.addAfter(newList, method.getModifierList());
|
||||
}
|
||||
paramList.add(aClass.copy());
|
||||
PsiDocumentManager.getInstance(project).doPostponedOperationsAndUnblockDocument(document);
|
||||
}
|
||||
catch (IncorrectOperationException e) {
|
||||
LOG.error(e);
|
||||
}
|
||||
paramList.add(aClass.copy());
|
||||
PsiDocumentManager.getInstance(project).doPostponedOperationsAndUnblockDocument(document);
|
||||
}
|
||||
catch (IncorrectOperationException e) {
|
||||
LOG.error(e);
|
||||
}
|
||||
}
|
||||
} else if (!noImport) {
|
||||
addImportForClass(document, aClass, segmentStart, segmentEnd);
|
||||
PsiDocumentManager.getInstance(project).doPostponedOperationsAndUnblockDocument(document);
|
||||
}
|
||||
} else {
|
||||
addImportForClass(document, aClass, segmentStart, segmentEnd);
|
||||
PsiDocumentManager.getInstance(project).doPostponedOperationsAndUnblockDocument(document);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void collectClassParams(PsiType item, List<PsiClass> classes) {
|
||||
PsiClass aClass = PsiUtil.resolveClassInType(item);
|
||||
if (aClass instanceof PsiTypeParameter) {
|
||||
classes.add(aClass);
|
||||
}
|
||||
|
||||
if (item instanceof PsiClassType) {
|
||||
PsiType[] parameters = ((PsiClassType)item).getParameters();
|
||||
for (PsiType parameter : parameters) {
|
||||
collectClassParams(parameter, classes);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user