IDEA-96661 Java completion: don't add {} tail after array completion variant

This commit is contained in:
peter
2013-02-01 17:40:55 +01:00
parent 2ae40f135f
commit 38faaa572a
7 changed files with 51 additions and 26 deletions
@@ -404,7 +404,7 @@ public class JavaCompletionSorting {
public Comparable weigh(@NotNull LookupElement element) {
final PsiTypeLookupItem lookupItem = element.as(PsiTypeLookupItem.CLASS_CONDITION_KEY);
if (lookupItem != null) {
return lookupItem.getBracketsCount();
return lookupItem.getBracketsCount() * 10 + (lookupItem.isAddArrayInitializer() ? 1 : 0);
}
if (element.as(CastingLookupElementDecorator.CLASS_CONDITION_KEY) != null) {
return 239;
@@ -50,6 +50,14 @@ public class JavaInheritorsGetter extends CompletionProvider<CompletionParameter
myConstructorInsertHandler = constructorInsertHandler;
}
private static boolean shouldAddArrayInitializer(PsiElement position) {
if (!JavaCompletionContributor.isInJavaContext(position) || !JavaSmartCompletionContributor.AFTER_NEW.accepts(position)) {
return false;
}
PsiNewExpression newExpression = PsiTreeUtil.getParentOfType(position, PsiNewExpression.class);
return newExpression != null && newExpression.getParent() instanceof PsiExpressionList;
}
@Override
public void addCompletions(@NotNull final CompletionParameters parameters, final ProcessingContext matchingContext, @NotNull final CompletionResultSet result) {
final ExpectedTypeInfo[] infos = JavaSmartCompletionContributor.getExpectedTypes(parameters);
@@ -88,16 +96,26 @@ public class JavaInheritorsGetter extends CompletionProvider<CompletionParameter
for (final PsiType type : ExpectedTypesGetter.extractTypes(infos, true)) {
if (type instanceof PsiArrayType) {
final LookupItem item = PsiTypeLookupItem.createLookupItem(TypeConversionUtil.erasure(type), identifierCopy);
if (item.getObject() instanceof PsiClass) {
JavaCompletionUtil.setShowFQN(item);
consumer.consume(createNewArrayItem(identifierCopy, type));
if (shouldAddArrayInitializer(identifierCopy)) {
PsiTypeLookupItem item = createNewArrayItem(identifierCopy, type);
item.setAddArrayInitializer();
consumer.consume(item);
}
item.setInsertHandler(new DefaultInsertHandler()); //braces & shortening
consumer.consume(item);
}
}
}
private static PsiTypeLookupItem createNewArrayItem(PsiElement identifierCopy, PsiType type) {
PsiTypeLookupItem item = PsiTypeLookupItem.createLookupItem(TypeConversionUtil.erasure(type), identifierCopy);
if (item.getObject() instanceof PsiClass) {
JavaCompletionUtil.setShowFQN(item);
}
item.setInsertHandler(new DefaultInsertHandler()); //braces & shortening
return item;
}
private static List<PsiClassType> extractClassTypes(ExpectedTypeInfo[] infos) {
final List<PsiClassType> expectedClassTypes = new SmartList<PsiClassType>();
for (PsiType type : ExpectedTypesGetter.extractTypes(infos, true)) {
@@ -155,9 +155,12 @@ public class JavaPsiClassReferenceElement extends LookupItem<Object> {
String tailText = StringUtil.notNullize((String) item.getAttribute(LookupItem.TAIL_TEXT_ATTR));
PsiSubstitutor substitutor = (PsiSubstitutor)item.getAttribute(LookupItem.SUBSTITUTOR);
if (item instanceof PsiTypeLookupItem && ((PsiTypeLookupItem)item).isIndicateAnonymous() &&
(psiClass.isInterface() || psiClass.hasModifierProperty(PsiModifier.ABSTRACT))) {
tailText = "{...}" + tailText;
if (item instanceof PsiTypeLookupItem) {
if (((PsiTypeLookupItem)item).isIndicateAnonymous() &&
(psiClass.isInterface() || psiClass.hasModifierProperty(PsiModifier.ABSTRACT)) ||
((PsiTypeLookupItem)item).isAddArrayInitializer()) {
tailText = "{...}" + tailText;
}
}
if (substitutor == null && !diamond && psiClass.getTypeParameters().length > 0) {
tailText = "<" + StringUtil.join(psiClass.getTypeParameters(), new Function<PsiTypeParameter, String>() {
@@ -27,7 +27,6 @@ import com.intellij.psi.*;
import com.intellij.psi.impl.DebugUtil;
import com.intellij.psi.impl.source.PostprocessReformattingAspect;
import com.intellij.psi.impl.source.PsiClassReferenceType;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.util.PsiUtil;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
@@ -55,6 +54,7 @@ public class PsiTypeLookupItem extends LookupItem {
private final int myBracketsCount;
private boolean myIndicateAnonymous;
private final InsertHandler<PsiTypeLookupItem> myImportFixer;
private boolean myAddArrayInitializer;
private PsiTypeLookupItem(Object o, @NotNull @NonNls String lookupString, boolean diamond, int bracketsCount, InsertHandler<PsiTypeLookupItem> fixer) {
super(o, lookupString);
@@ -84,7 +84,17 @@ public class PsiTypeLookupItem extends LookupItem {
@Override
public boolean equals(final Object o) {
return super.equals(o) && o instanceof PsiTypeLookupItem && getBracketsCount() == ((PsiTypeLookupItem) o).getBracketsCount();
return super.equals(o) && o instanceof PsiTypeLookupItem &&
getBracketsCount() == ((PsiTypeLookupItem) o).getBracketsCount() &&
myAddArrayInitializer == ((PsiTypeLookupItem) o).myAddArrayInitializer;
}
public boolean isAddArrayInitializer() {
return myAddArrayInitializer;
}
public void setAddArrayInitializer() {
myAddArrayInitializer = true;
}
@Override
@@ -93,7 +103,6 @@ public class PsiTypeLookupItem extends LookupItem {
PsiElement position = context.getFile().findElementAt(context.getStartOffset());
assert position != null;
boolean addBraces = shouldAddBraces(position);
int genericsStart = context.getTailOffset();
context.getDocument().insertString(genericsStart, JavaCompletionUtil.escapeXmlIfNeeded(context, calcGenerics(position, context)));
JavaCompletionUtil.shortenReference(context.getFile(), genericsStart - 1);
@@ -102,7 +111,7 @@ public class PsiTypeLookupItem extends LookupItem {
String braces = StringUtil.repeat("[]", getBracketsCount());
Editor editor = context.getEditor();
if (!braces.isEmpty()) {
if (LookupEvent.isSpecialCompletionChar(context.getCompletionChar()) && addBraces) {
if (myAddArrayInitializer) {
context.getDocument().insertString(tail, braces + "{}");
editor.getCaretModel().moveToOffset(tail + braces.length() + 1);
} else {
@@ -125,14 +134,6 @@ public class PsiTypeLookupItem extends LookupItem {
}
}
private static boolean shouldAddBraces(PsiElement position) {
if (!JavaCompletionContributor.isInJavaContext(position) || !JavaSmartCompletionContributor.AFTER_NEW.accepts(position)) {
return false;
}
PsiNewExpression newExpression = PsiTreeUtil.getParentOfType(position, PsiNewExpression.class);
return newExpression != null && newExpression.getParent() instanceof PsiExpressionList;
}
public String calcGenerics(@NotNull PsiElement context, InsertionContext insertionContext) {
if (insertionContext.getCompletionChar() == '<') {
return "";
@@ -1,5 +1,5 @@
class Super {
void foo(String[] params, int... indices) {
foo(new String[]{<caret>}, 0);
foo(new String[<caret>], 0);
}
}
@@ -4,6 +4,6 @@ class MyException extends RuntimeException {
class XXX {
{
throw new MyException(new String[]{<caret>});
throw new MyException(new String[<caret>]);
}
}
@@ -348,6 +348,7 @@ public class SmartTypeCompletionTest extends LightFixtureCompletionTestCase {
String path = "/generics";
configureByFile(path + "/before9.java");
selectItem(myItems[1]);
checkResultByFile(path + "/after9.java");
}
@@ -421,7 +422,7 @@ public class SmartTypeCompletionTest extends LightFixtureCompletionTestCase {
public void testArrayAccessIndex() throws Throwable { doTest(); }
public void testThrowExceptionConstructor() throws Throwable { doTest(); }
public void testThrowExceptionConstructor() throws Throwable { doTest('\n'); }
public void testJavadocThrows() throws Throwable { doTest(); }
@@ -594,16 +595,18 @@ public class SmartTypeCompletionTest extends LightFixtureCompletionTestCase {
public void testNewVararg() throws Throwable {
configureByTestName();
assertStringItems("Foo", "Foo");
assertStringItems("Foo", "Foo", "Foo");
assertEquals("{...} (default package)", LookupElementPresentation.renderElement(myItems[0]).getTailText());
assertEquals("[] (default package)", LookupElementPresentation.renderElement(myItems[1]).getTailText());
assertEquals("[]{...} (default package)", LookupElementPresentation.renderElement(myItems[2]).getTailText());
}
public void testNewVararg2() throws Throwable {
configureByTestName();
assertStringItems("String", "String");
assertStringItems("String", "String", "String");
assertEquals(" (java.lang)", LookupElementPresentation.renderElement(myItems[0]).getTailText());
assertEquals("[] (java.lang)", LookupElementPresentation.renderElement(myItems[1]).getTailText());
assertEquals("[]{...} (java.lang)", LookupElementPresentation.renderElement(myItems[2]).getTailText());
}
public void testNewByteArray() {