diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/AddVariableInitializerFix.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/AddVariableInitializerFix.java index 1c69fae07625..d33afa27c245 100644 --- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/AddVariableInitializerFix.java +++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/AddVariableInitializerFix.java @@ -17,19 +17,23 @@ package com.intellij.codeInsight.daemon.impl.quickfix; import com.intellij.codeInsight.CodeInsightBundle; import com.intellij.codeInsight.FileModificationService; -import com.intellij.codeInsight.completion.*; +import com.intellij.codeInsight.completion.JavaInheritorsGetter; +import com.intellij.codeInsight.completion.PrefixMatcher; +import com.intellij.codeInsight.completion.StatisticsWeigher; import com.intellij.codeInsight.intention.IntentionAction; -import com.intellij.codeInsight.lookup.*; +import com.intellij.codeInsight.lookup.ExpressionLookupItem; +import com.intellij.codeInsight.lookup.LookupElement; +import com.intellij.codeInsight.lookup.PsiTypeLookupItem; import com.intellij.codeInsight.template.*; import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.editor.CaretModel; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.project.Project; import com.intellij.psi.*; -import com.intellij.psi.util.InheritanceUtil; +import com.intellij.psi.filters.getters.JavaMembersGetter; import com.intellij.psi.util.PsiTreeUtil; import com.intellij.psi.util.PsiTypesUtil; import com.intellij.psi.util.PsiUtil; -import com.intellij.refactoring.util.RefactoringUtil; import com.intellij.util.Consumer; import com.intellij.util.Function; import com.intellij.util.IncorrectOperationException; @@ -38,11 +42,13 @@ import com.intellij.util.containers.ContainerUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.List; -import static com.intellij.util.containers.ContainerUtil.*; +import static com.intellij.util.containers.ContainerUtil.map; +import static com.intellij.util.containers.ContainerUtil.sorted; public class AddVariableInitializerFix implements IntentionAction { private static final Logger LOG = Logger.getInstance("#com.intellij.codeInsight.daemon.impl.quickfix.AddReturnFix"); @@ -76,11 +82,10 @@ public class AddVariableInitializerFix implements IntentionAction { @Override public void invoke(@NotNull Project project, Editor editor, PsiFile file) throws IncorrectOperationException { if (!FileModificationService.getInstance().prepareFileForWrite(myVariable.getContainingFile())) return; - final LookupElement[] suggestedInitializers = suggestInitializer(myVariable); LOG.assertTrue(suggestedInitializers.length > 0); LOG.assertTrue(suggestedInitializers[0] instanceof ExpressionLookupItem); - final PsiExpression initializer = (PsiExpression) suggestedInitializers[0].getObject(); + final PsiExpression initializer = (PsiExpression)suggestedInitializers[0].getObject(); if (myVariable instanceof PsiLocalVariable) { ((PsiLocalVariable)myVariable).setInitializer(initializer); } @@ -88,7 +93,7 @@ public class AddVariableInitializerFix implements IntentionAction { ((PsiField)myVariable).setInitializer(initializer); } else { - LOG.error("Unknown variable type: "+myVariable); + LOG.error("Unknown variable type: " + myVariable); } runAssignmentTemplate(Collections.singletonList(myVariable.getInitializer()), suggestedInitializers, editor); } @@ -130,80 +135,20 @@ public class AddVariableInitializerFix implements IntentionAction { public static LookupElement[] suggestInitializer(final PsiVariable variable) { PsiType type = variable.getType(); final PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(variable.getProject()); + + final List result = new SmartList(); + final String defaultValue = PsiTypesUtil.getDefaultValueOfType(type); + final ExpressionLookupItem defaultExpression = new ExpressionLookupItem(elementFactory.createExpressionFromText(defaultValue, variable)); + result.add(defaultExpression); if (type instanceof PsiClassType) { final PsiClass aClass = PsiTypesUtil.getPsiClass(type); - if (aClass != null) { - final LookupElement nullLookupItem = new ExpressionLookupItem(elementFactory.createExpressionFromText(PsiKeyword.NULL, variable)); - if (InheritanceUtil.isInheritor(aClass, CommonClassNames.JAVA_LANG_ITERABLE) || - InheritanceUtil.isInheritor(aClass, CommonClassNames.JAVA_UTIL_MAP)) { - final List suggestedTypes = new SmartList(); - JavaInheritorsGetter.processInheritors(variable.getContainingFile(), variable, Collections.singleton((PsiClassType) type), PrefixMatcher.ALWAYS_TRUE, new Consumer() { - @Override - public void consume(PsiType type) { - LOG.assertTrue(type instanceof PsiClassType); - final PsiClass psiClass = PsiTypesUtil.getPsiClass(type); - if (psiClass != null && - !psiClass.isInterface() && - !psiClass.hasModifierProperty(PsiModifier.ABSTRACT) && - psiClass.hasModifierProperty(PsiModifier.PUBLIC) && - PsiUtil.hasDefaultConstructor(psiClass)) { - suggestedTypes.add(type); - } - } - }); - - List sortedLookups = map(sorted(map(suggestedTypes, new Function() { - @Override - public LookupElement fun(PsiType type) { - return PsiTypeLookupItem.createLookupItem(type, variable); - } - }), new Comparator() { - @Override - public int compare(LookupElement o1, LookupElement o2) { - final int count1 = StatisticsWeigher.getBaseStatisticsInfo(o1, null).getUseCount(); - final int count2 = StatisticsWeigher.getBaseStatisticsInfo(o2, null).getUseCount(); - return count2 - count1; - } - }), new Function() { - @Override - public LookupElement fun(LookupElement element) { - final LookupElementDecorator constructorLookupElement = - LookupElementDecorator.withInsertHandler(element, ConstructorInsertHandler.BASIC_INSTANCE); - return new LookupElementDecorator(constructorLookupElement) { - @Override - public void renderElement(LookupElementPresentation presentation) { - super.renderElement(presentation); - presentation.setTailText(""); - presentation.setItemText(PsiKeyword.NEW + " " + presentation.getItemText() + "()"); - } - - @Override - public void handleInsert(InsertionContext context) { - super.handleInsert(context); - context.getDocument().insertString(context.getStartOffset(), PsiKeyword.NEW + " "); - } - }; - } - }); - LookupElement[] result = new LookupElement[sortedLookups.size() + 1]; - result[0] = nullLookupItem; - for (int i = 0; i < sortedLookups.size(); i++) { - LookupElement lookup = sortedLookups.get(i); - result[i + 1] = lookup; - } - return result; - } else { - if (PsiUtil.hasDefaultConstructor(aClass)) { - final PsiExpression newExpression = elementFactory - .createExpressionFromText(PsiKeyword.NEW + " " + type.getCanonicalText(false) + "()", variable); - return new LookupElement[]{nullLookupItem, new ExpressionLookupItem(newExpression)}; - } - } + if (aClass != null && PsiUtil.hasDefaultConstructor(aClass)) { + final String expressionText = PsiKeyword.NEW + " " + type.getCanonicalText(false) + "()"; + ExpressionLookupItem newExpression = new ExpressionLookupItem(elementFactory.createExpressionFromText(expressionText, variable)); + result.add(newExpression); } } - final String defaultValue = PsiTypesUtil.getDefaultValueOfType(type); - final PsiExpression expression = elementFactory.createExpressionFromText(defaultValue, variable); - return new LookupElement[] {new ExpressionLookupItem(expression)}; + return result.toArray(new LookupElement[result.size()]); } @Override