mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
start template when anonymous class is completed with Object params (need better heuristic)
This commit is contained in:
+93
-35
@@ -3,16 +3,21 @@ package com.intellij.codeInsight.completion;
|
||||
import com.intellij.codeInsight.ExpectedTypeInfo;
|
||||
import com.intellij.codeInsight.ExpectedTypesProvider;
|
||||
import com.intellij.codeInsight.generation.GenerateMembersUtil;
|
||||
import com.intellij.codeInsight.generation.OverrideImplementExploreUtil;
|
||||
import com.intellij.codeInsight.generation.OverrideImplementUtil;
|
||||
import com.intellij.codeInsight.generation.PsiGenerationInfo;
|
||||
import com.intellij.codeInsight.intention.impl.TypeExpression;
|
||||
import com.intellij.codeInsight.lookup.Lookup;
|
||||
import com.intellij.codeInsight.lookup.LookupElementDecorator;
|
||||
import com.intellij.codeInsight.lookup.LookupItem;
|
||||
import com.intellij.codeInsight.lookup.PsiTypeLookupItem;
|
||||
import com.intellij.codeInsight.template.*;
|
||||
import com.intellij.featureStatistics.FeatureUsageTracker;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.application.Result;
|
||||
import com.intellij.openapi.command.CommandProcessor;
|
||||
import com.intellij.openapi.command.UndoConfirmationPolicy;
|
||||
import com.intellij.openapi.command.WriteCommandAction;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.editor.Document;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
@@ -25,6 +30,7 @@ import com.intellij.psi.infos.CandidateInfo;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.psi.util.PsiUtilCore;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import org.jetbrains.annotations.Contract;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@@ -243,46 +249,98 @@ public class ConstructorInsertHandler implements InsertHandler<LookupElementDeco
|
||||
|
||||
return new Runnable() {
|
||||
@Override
|
||||
public void run(){
|
||||
CommandProcessor.getInstance().executeCommand(project, new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
PsiDocumentManager.getInstance(project).commitDocument(editor.getDocument());
|
||||
final PsiAnonymousClass aClass = PsiTreeUtil.findElementOfClassAtOffset(file, editor.getCaretModel().getOffset(), PsiAnonymousClass.class, false);
|
||||
if (aClass == null) return;
|
||||
final Runnable runnable = new Runnable() {
|
||||
public void run() {
|
||||
PsiDocumentManager.getInstance(project).commitDocument(editor.getDocument());
|
||||
final PsiAnonymousClass aClass = PsiTreeUtil.findElementOfClassAtOffset(file, editor.getCaretModel().getOffset(), PsiAnonymousClass.class, false);
|
||||
if (aClass == null) return;
|
||||
|
||||
final Collection<CandidateInfo> candidatesToImplement = OverrideImplementUtil.getMethodsToOverrideImplement(aClass, true);
|
||||
for (Iterator<CandidateInfo> iterator = candidatesToImplement.iterator(); iterator.hasNext(); ) {
|
||||
final CandidateInfo candidate = iterator.next();
|
||||
final PsiElement element = candidate.getElement();
|
||||
if (element instanceof PsiMethod && ((PsiMethod)element).hasModifierProperty(PsiModifier.DEFAULT)) {
|
||||
iterator.remove();
|
||||
}
|
||||
}
|
||||
boolean invokeOverride = candidatesToImplement.isEmpty();
|
||||
if (invokeOverride){
|
||||
OverrideImplementUtil.chooseAndOverrideOrImplementMethods(project, editor, aClass, false);
|
||||
}
|
||||
else{
|
||||
ApplicationManager.getApplication().runWriteAction(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
try{
|
||||
List<PsiMethod> methods = OverrideImplementUtil.overrideOrImplementMethodCandidates(aClass, candidatesToImplement, false);
|
||||
List<PsiGenerationInfo<PsiMethod>> prototypes = OverrideImplementUtil.convert2GenerationInfos(methods);
|
||||
List<PsiGenerationInfo<PsiMethod>> resultMembers = GenerateMembersUtil.insertMembersBeforeAnchor(aClass, null, prototypes);
|
||||
resultMembers.get(0).positionCaret(editor, true);
|
||||
}
|
||||
catch(IncorrectOperationException ioe){
|
||||
LOG.error(ioe);
|
||||
CommandProcessor.getInstance().executeCommand(project, new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
final Collection<CandidateInfo> candidatesToImplement = OverrideImplementExploreUtil.getMethodsToOverrideImplement(aClass, true);
|
||||
for (Iterator<CandidateInfo> iterator = candidatesToImplement.iterator(); iterator.hasNext(); ) {
|
||||
final CandidateInfo candidate = iterator.next();
|
||||
final PsiElement element = candidate.getElement();
|
||||
if (element instanceof PsiMethod && ((PsiMethod)element).hasModifierProperty(PsiModifier.DEFAULT)) {
|
||||
iterator.remove();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
boolean invokeOverride = candidatesToImplement.isEmpty();
|
||||
if (invokeOverride) {
|
||||
OverrideImplementUtil.chooseAndOverrideOrImplementMethods(project, editor, aClass, false);
|
||||
}
|
||||
else {
|
||||
ApplicationManager.getApplication().runWriteAction(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
List<PsiMethod> methods = OverrideImplementUtil.overrideOrImplementMethodCandidates(aClass, candidatesToImplement, false);
|
||||
List<PsiGenerationInfo<PsiMethod>> prototypes = OverrideImplementUtil.convert2GenerationInfos(methods);
|
||||
List<PsiGenerationInfo<PsiMethod>> resultMembers =
|
||||
GenerateMembersUtil.insertMembersBeforeAnchor(aClass, null, prototypes);
|
||||
resultMembers.get(0).positionCaret(editor, true);
|
||||
}
|
||||
catch (IncorrectOperationException ioe) {
|
||||
LOG.error(ioe);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}, getCommandName(), getCommandName(), UndoConfirmationPolicy.DEFAULT, editor.getDocument());
|
||||
}
|
||||
}, CompletionBundle.message("completion.smart.type.generate.anonymous.body"), null, UndoConfirmationPolicy.DEFAULT, editor.getDocument());
|
||||
};
|
||||
|
||||
final PsiReferenceParameterList parameterList = aClass.getBaseClassReference().getParameterList();
|
||||
final PsiTypeElement[] parameters = parameterList != null ? parameterList.getTypeParameterElements() : null;
|
||||
if (startTypeTemplate(parameters)) {
|
||||
startTemplate(aClass, runnable, parameters);
|
||||
}
|
||||
else {
|
||||
runnable.run();
|
||||
}
|
||||
}
|
||||
|
||||
@Contract("null -> false")
|
||||
private boolean startTypeTemplate(PsiTypeElement[] parameters) {
|
||||
if (parameters != null && parameters.length > 0) {
|
||||
for (PsiTypeElement parameter : parameters) {
|
||||
if (!parameter.getType().equalsToText(CommonClassNames.JAVA_LANG_OBJECT)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private void startTemplate(final PsiAnonymousClass aClass, final Runnable runnable, @NotNull final PsiTypeElement[] parameters) {
|
||||
new WriteCommandAction(aClass.getProject(), getCommandName(), getCommandName()) {
|
||||
@Override
|
||||
protected void run(@NotNull Result result) throws Throwable {
|
||||
editor.getCaretModel().moveToOffset(aClass.getTextOffset());
|
||||
final TemplateBuilderImpl templateBuilder = (TemplateBuilderImpl)TemplateBuilderFactory.getInstance().createTemplateBuilder(aClass);
|
||||
for (int i = 0; i < parameters.length; i++) {
|
||||
PsiTypeElement parameter = parameters[i];
|
||||
templateBuilder.replaceElement(parameter, "param" + i, new TypeExpression(project, new PsiType[]{parameter.getType()}), true);
|
||||
}
|
||||
Template template = templateBuilder.buildInlineTemplate();
|
||||
TemplateManager.getInstance(project).startTemplate(editor, template, false, null, new TemplateEditingAdapter() {
|
||||
@Override
|
||||
public void templateFinished(Template template, boolean brokenOff) {
|
||||
if (!brokenOff) {
|
||||
runnable.run();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}.execute();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private static String getCommandName() {
|
||||
return CompletionBundle.message("completion.smart.type.generate.anonymous.body");
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user