diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/ConstructorInsertHandler.java b/java/java-impl/src/com/intellij/codeInsight/completion/ConstructorInsertHandler.java index 80df0986a2f3..b68572f1c4af 100644 --- a/java/java-impl/src/com/intellij/codeInsight/completion/ConstructorInsertHandler.java +++ b/java/java-impl/src/com/intellij/codeInsight/completion/ConstructorInsertHandler.java @@ -26,6 +26,7 @@ import com.intellij.psi.infos.CandidateInfo; import com.intellij.psi.util.PsiTreeUtil; import com.intellij.psi.util.PsiUtil; import com.intellij.util.IncorrectOperationException; +import org.jetbrains.annotations.NotNull; import java.util.ArrayList; import java.util.Collection; @@ -147,8 +148,16 @@ class ConstructorInsertHandler implements InsertHandler completeReference(final PsiElement element, diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/TypeArgumentCompletionProvider.java b/java/java-impl/src/com/intellij/codeInsight/completion/TypeArgumentCompletionProvider.java index 0a1990795a09..f074a9b140c4 100644 --- a/java/java-impl/src/com/intellij/codeInsight/completion/TypeArgumentCompletionProvider.java +++ b/java/java-impl/src/com/intellij/codeInsight/completion/TypeArgumentCompletionProvider.java @@ -16,12 +16,16 @@ package com.intellij.codeInsight.completion; import com.intellij.codeInsight.CharTailType; +import com.intellij.codeInsight.ExpectedTypeInfo; import com.intellij.codeInsight.TailType; -import com.intellij.codeInsight.lookup.*; +import com.intellij.codeInsight.completion.util.ParenthesesInsertHandler; +import com.intellij.codeInsight.lookup.LookupElement; +import com.intellij.codeInsight.lookup.LookupElementPresentation; +import com.intellij.codeInsight.lookup.PsiTypeLookupItem; +import com.intellij.codeInsight.lookup.TailTypeDecorator; import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.*; -import com.intellij.psi.filters.getters.ExpectedTypesGetter; import com.intellij.psi.util.InheritanceUtil; import com.intellij.psi.util.PsiTreeUtil; import com.intellij.psi.util.PsiUtil; @@ -36,6 +40,8 @@ import java.util.ArrayList; import java.util.Collections; import java.util.List; +import static com.intellij.patterns.PsiJavaPatterns.psiElement; + /** * @author peter */ @@ -47,11 +53,12 @@ class TypeArgumentCompletionProvider extends CompletionProvider pair = getTypeParameterInfo(context); if (pair == null) return; - final PsiType[] psiTypes = ExpectedTypesGetter.getExpectedTypes(context, false); - if (psiTypes.length > 0) { - for (PsiType type : psiTypes) { + ExpectedTypeInfo[] types = JavaSmartCompletionContributor.getExpectedTypes(parameters, false); + if (types.length > 0) { + for (ExpectedTypeInfo info : types) { + PsiType type = info.getType(); if (type instanceof PsiClassType) { - fillExpectedTypeArgs(resultSet, context, pair.first, pair.second, ((PsiClassType)type).resolveGenerics()); + fillExpectedTypeArgs(resultSet, context, pair.first, pair.second, ((PsiClassType)type).resolveGenerics(), info.getTailType()); } } } else { @@ -63,7 +70,7 @@ class TypeArgumentCompletionProvider extends CompletionProvider() { - @Override - public void renderElement(LookupElement element, LookupElementPresentation presentation) { - typeItems.get(0).renderElement(presentation); - presentation.setItemText(StringUtil.join(typeItems, new Function() { - @Override - public String fun(PsiTypeLookupItem item) { - return item.getLookupString(); - } - }, ", ")); - presentation.setTailText(null); - presentation.setTypeText(null); - } - }).setInsertHandler(new InsertHandler() { - @Override - public void handleInsert(InsertionContext context, LookupElement item) { - context.getDocument().deleteString(context.getStartOffset(), context.getTailOffset()); - for (int i = 0; i < typeItems.size(); i++) { - CompletionUtil.emulateInsertion(context, context.getTailOffset(), typeItems.get(i)); - getTail(i == typeItems.size() - 1).processTail(context.getEditor(), context.getTailOffset()); - } - context.setAddCompletionChar(false); - } - })); + resultSet.addElement(new TypeArgsLookupElement(typeItems, globalTail, ConstructorInsertHandler.hasConstructorParameters(actualClass, context))); } @Nullable @@ -184,4 +168,79 @@ class TypeArgumentCompletionProvider extends CompletionProvider myTypeItems; + private final TailType myGlobalTail; + private final boolean myHasParameters; + + public TypeArgsLookupElement(List typeItems, TailType globalTail, boolean hasParameters) { + myTypeItems = typeItems; + myGlobalTail = globalTail; + myHasParameters = hasParameters; + myLookupString = StringUtil.join(myTypeItems, new Function() { + @Override + public String fun(PsiTypeLookupItem item) { + return item.getLookupString(); + } + }, ", "); + } + + @NotNull + @Override + public Object getObject() { + return myTypeItems.get(0).getObject(); + } + + @NotNull + @Override + public String getLookupString() { + return myLookupString; + } + + @Override + public void renderElement(LookupElementPresentation presentation) { + myTypeItems.get(0).renderElement(presentation); + presentation.setItemText(getLookupString()); + presentation.setTailText(null); + presentation.setTypeText(null); + } + + @Override + public void handleInsert(InsertionContext context) { + context.getDocument().deleteString(context.getStartOffset(), context.getTailOffset()); + for (int i = 0; i < myTypeItems.size(); i++) { + CompletionUtil.emulateInsertion(context, context.getTailOffset(), myTypeItems.get(i)); + context.setTailOffset(getTail(i == myTypeItems.size() - 1).processTail(context.getEditor(), context.getTailOffset())); + } + context.setAddCompletionChar(false); + + context.commitDocument(); + + PsiElement leaf = context.getFile().findElementAt(context.getTailOffset() - 1); + if (psiElement().withParents(PsiReferenceParameterList.class, PsiJavaCodeReferenceElement.class, PsiNewExpression.class) + .accepts(leaf)) { + ParenthesesInsertHandler.getInstance(myHasParameters).handleInsert(context, this); + myGlobalTail.processTail(context.getEditor(), context.getTailOffset()); + } + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + TypeArgsLookupElement element = (TypeArgsLookupElement)o; + + if (!myTypeItems.equals(element.myTypeItems)) return false; + + return true; + } + + @Override + public int hashCode() { + return myTypeItems.hashCode(); + } + } } diff --git a/java/java-tests/testData/codeInsight/completion/smartType/SeveralTypeArguments-out.java b/java/java-tests/testData/codeInsight/completion/smartType/SeveralTypeArguments-out.java index 2c3c66313e77..d2c7713aa4d4 100644 --- a/java/java-tests/testData/codeInsight/completion/smartType/SeveralTypeArguments-out.java +++ b/java/java-tests/testData/codeInsight/completion/smartType/SeveralTypeArguments-out.java @@ -1,5 +1,5 @@ -class HashMap {} +import java.util.HashMap; public class A { - private HashMap m = new HashMap(); + private HashMap m = new HashMap(); } diff --git a/java/java-tests/testData/codeInsight/completion/smartType/SeveralTypeArguments.java b/java/java-tests/testData/codeInsight/completion/smartType/SeveralTypeArguments.java index 5e62309ae3d4..31ec5002ce6b 100644 --- a/java/java-tests/testData/codeInsight/completion/smartType/SeveralTypeArguments.java +++ b/java/java-tests/testData/codeInsight/completion/smartType/SeveralTypeArguments.java @@ -1,4 +1,4 @@ -class HashMap {} +import java.util.HashMap; public class A { private HashMap m = new HashMap<>(); diff --git a/java/java-tests/testData/codeInsight/completion/smartType/afterNew/after12.java b/java/java-tests/testData/codeInsight/completion/smartType/afterNew/after12.java index 052d2656908d..9a81b52d85c8 100644 --- a/java/java-tests/testData/codeInsight/completion/smartType/afterNew/after12.java +++ b/java/java-tests/testData/codeInsight/completion/smartType/afterNew/after12.java @@ -1,4 +1,4 @@ class Test { - Test test = new Test + Test test = new Test(); } \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/completion/smartType/afterNew/after13.java b/java/java-tests/testData/codeInsight/completion/smartType/afterNew/after13.java index aa55d681d903..5d8f893473e0 100644 --- a/java/java-tests/testData/codeInsight/completion/smartType/afterNew/after13.java +++ b/java/java-tests/testData/codeInsight/completion/smartType/afterNew/after13.java @@ -1,3 +1,3 @@ class AAAAA{ - AAAAA asd = new AAAAA + AAAAA asd = new AAAAA(); } \ No newline at end of file