From d2dd3777756d760c6d86ed21caaa0bfa203af2a0 Mon Sep 17 00:00:00 2001 From: peter Date: Fri, 29 Oct 2010 23:55:58 +0400 Subject: [PATCH] by default, JavaPsiClassReferenceElement insert handler doesn't know about Java language PSI --- .../JavaClassNameCompletionContributor.java | 69 ++++++++++++------- .../JavaPsiClassReferenceElement.java | 45 ++---------- .../JavaSmartCompletionContributor.java | 6 +- .../codeInsight/lookup/LookupItemUtil.java | 4 +- 4 files changed, 57 insertions(+), 67 deletions(-) diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/JavaClassNameCompletionContributor.java b/java/java-impl/src/com/intellij/codeInsight/completion/JavaClassNameCompletionContributor.java index bbae78db3d13..26b51fa27baa 100644 --- a/java/java-impl/src/com/intellij/codeInsight/completion/JavaClassNameCompletionContributor.java +++ b/java/java-impl/src/com/intellij/codeInsight/completion/JavaClassNameCompletionContributor.java @@ -17,7 +17,6 @@ package com.intellij.codeInsight.completion; import com.intellij.codeInsight.ExpectedTypeInfo; import com.intellij.codeInsight.ExpectedTypesProvider; -import com.intellij.codeInsight.lookup.LookupElement; import com.intellij.lang.LangBundle; import com.intellij.lang.StdLanguages; import com.intellij.openapi.actionSystem.IdeActions; @@ -28,6 +27,7 @@ import com.intellij.patterns.PsiJavaPatterns; import com.intellij.psi.*; import com.intellij.psi.filters.ClassFilter; import com.intellij.psi.filters.ElementFilter; +import com.intellij.psi.filters.FilterPositionUtil; import com.intellij.psi.filters.TrueFilter; import com.intellij.psi.filters.classes.ThisOrAnyInnerFilter; import com.intellij.psi.filters.element.ExcludeDeclaredFilter; @@ -52,6 +52,49 @@ public class JavaClassNameCompletionContributor extends CompletionContributor { psiElement(PsiReferenceList.class).withParent(PsiTypeParameter.class)); private static final PsiJavaElementPattern.Capture INSIDE_METHOD_THROWS_CLAUSE = psiElement().afterLeaf(PsiKeyword.THROWS, ",").inside( PsiMethod.class).andNot(psiElement().inside(PsiCodeBlock.class)).andNot(psiElement().inside(PsiParameterList.class)); + private static final InsertHandler JAVA_CLASS_INSERT_HANDLER = new InsertHandler() { + public void handleInsert(final InsertionContext context, final JavaPsiClassReferenceElement item) { + context.setAddCompletionChar(false); + int offset = context.getTailOffset() - 1; + final PsiFile file = context.getFile(); + if (PsiTreeUtil.findElementOfClassAtOffset(file, offset, PsiImportStatementBase.class, false) != null) { + final PsiJavaCodeReferenceElement ref = PsiTreeUtil.findElementOfClassAtOffset(file, offset, PsiJavaCodeReferenceElement.class, false); + final String qname = item.getQualifiedName(); + if (qname != null && (ref == null || !qname.equals(ref.getCanonicalText()))) { + AllClassesGetter.INSERT_FQN.handleInsert(context, item); + } + return; + } + + if (completingRawConstructor(context, item)) { + ConstructorInsertHandler.insertParentheses(context, item, item.getObject()); + DefaultInsertHandler.addImportForItem(context.getFile(), context.getStartOffset(), item); + } else { + new DefaultInsertHandler().handleInsert(context, item); + } + } + + private boolean completingRawConstructor(InsertionContext context, JavaPsiClassReferenceElement item) { + final PsiJavaCodeReferenceElement ref = PsiTreeUtil.findElementOfClassAtOffset(context.getFile(), context.getStartOffset(), PsiJavaCodeReferenceElement.class, false); + final PsiElement prevElement = FilterPositionUtil.searchNonSpaceNonCommentBack(ref); + if (prevElement != null && prevElement.getParent() instanceof PsiNewExpression) { + PsiTypeParameter[] typeParameters = item.getObject().getTypeParameters(); + for (ExpectedTypeInfo info : ExpectedTypesProvider.getExpectedTypes((PsiExpression) prevElement.getParent(), true)) { + final PsiType type = info.getType(); + + if (info.isArrayTypeInfo()) { + return false; + } + if (typeParameters.length > 0 && type instanceof PsiClassType && !((PsiClassType)type).isRaw()) { + return false; + } + } + return true; + } + + return false; + } + }; public JavaClassNameCompletionContributor() { extend(CompletionType.CLASS_NAME, psiElement(), new CompletionProvider(false) { @@ -106,28 +149,8 @@ public class JavaClassNameCompletionContributor extends CompletionContributor { } - public static LookupElement createClassLookupItem(final PsiClass psiClass, final boolean inJavaContext) { - if (inJavaContext) { - return AllClassesGetter.createLookupItem(psiClass, new InsertHandler() { - @Override - public void handleInsert(InsertionContext context, JavaPsiClassReferenceElement item) { - context.setAddCompletionChar(false); - int offset = context.getTailOffset() - 1; - final PsiFile file = context.getFile(); - if (PsiTreeUtil.findElementOfClassAtOffset(file, offset, PsiImportStatementBase.class, false) != null) { - final PsiJavaCodeReferenceElement ref = PsiTreeUtil.findElementOfClassAtOffset(file, offset, PsiJavaCodeReferenceElement.class, false); - final String qname = item.getQualifiedName(); - if (qname != null && (ref == null || !qname.equals(ref.getCanonicalText()))) { - AllClassesGetter.INSERT_FQN.handleInsert(context, item); - } - return; - } - - JavaPsiClassReferenceElement.JAVA_CLASS_INSERT_HANDLER.handleInsert(context, item); - } - }); - } - return AllClassesGetter.createLookupItem(psiClass, AllClassesGetter.TRY_SHORTENING); + public static JavaPsiClassReferenceElement createClassLookupItem(final PsiClass psiClass, final boolean inJavaContext) { + return AllClassesGetter.createLookupItem(psiClass, inJavaContext ? JAVA_CLASS_INSERT_HANDLER : AllClassesGetter.TRY_SHORTENING); } @Override diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/JavaPsiClassReferenceElement.java b/java/java-impl/src/com/intellij/codeInsight/completion/JavaPsiClassReferenceElement.java index a3264b2697a7..826ce491a421 100644 --- a/java/java-impl/src/com/intellij/codeInsight/completion/JavaPsiClassReferenceElement.java +++ b/java/java-impl/src/com/intellij/codeInsight/completion/JavaPsiClassReferenceElement.java @@ -15,51 +15,17 @@ */ package com.intellij.codeInsight.completion; -import com.intellij.codeInsight.ExpectedTypeInfo; -import com.intellij.codeInsight.ExpectedTypesProvider; +import com.intellij.codeInsight.TailType; import com.intellij.codeInsight.lookup.LookupItem; import com.intellij.openapi.util.Comparing; -import com.intellij.psi.*; -import com.intellij.psi.filters.FilterPositionUtil; -import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.psi.PsiAnchor; +import com.intellij.psi.PsiClass; import org.jetbrains.annotations.NotNull; /** * @author peter */ -public class JavaPsiClassReferenceElement extends LookupItem { - public static final InsertHandler JAVA_CLASS_INSERT_HANDLER = new InsertHandler() { - public void handleInsert(final InsertionContext context, final JavaPsiClassReferenceElement item) { - if (completingRawConstructor(context, item)) { - ConstructorInsertHandler.insertParentheses(context, item, item.getObject()); - DefaultInsertHandler.addImportForItem(context.getFile(), context.getStartOffset(), item); - } else { - new DefaultInsertHandler().handleInsert(context, item); - } - } - - private boolean completingRawConstructor(InsertionContext context, JavaPsiClassReferenceElement item) { - final PsiJavaCodeReferenceElement ref = PsiTreeUtil.findElementOfClassAtOffset(context.getFile(), context.getStartOffset(), PsiJavaCodeReferenceElement.class, false); - final PsiElement prevElement = FilterPositionUtil.searchNonSpaceNonCommentBack(ref); - if (prevElement != null && prevElement.getParent() instanceof PsiNewExpression) { - PsiTypeParameter[] typeParameters = item.getObject().getTypeParameters(); - for (ExpectedTypeInfo info : ExpectedTypesProvider.getExpectedTypes((PsiExpression) prevElement.getParent(), true)) { - final PsiType type = info.getType(); - - if (info.isArrayTypeInfo()) { - return false; - } - if (typeParameters.length > 0 && type instanceof PsiClassType && !((PsiClassType)type).isRaw()) { - return false; - } - } - return true; - } - - return false; - } - }; - +public class JavaPsiClassReferenceElement extends LookupItem { private final Object myClass; private final String myQualifiedName; @@ -68,7 +34,8 @@ public class JavaPsiClassReferenceElement extends LookupItem { myClass = psiClass.getContainingFile().getVirtualFile() == null ? psiClass : PsiAnchor.create(psiClass); myQualifiedName = psiClass.getQualifiedName(); JavaCompletionUtil.setShowFQN(this); - setInsertHandler(JAVA_CLASS_INSERT_HANDLER); + setInsertHandler(AllClassesGetter.TRY_SHORTENING); + setTailType(TailType.NONE); } @NotNull diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/JavaSmartCompletionContributor.java b/java/java-impl/src/com/intellij/codeInsight/completion/JavaSmartCompletionContributor.java index 66a85a776f2a..1c11f833e605 100644 --- a/java/java-impl/src/com/intellij/codeInsight/completion/JavaSmartCompletionContributor.java +++ b/java/java-impl/src/com/intellij/codeInsight/completion/JavaSmartCompletionContributor.java @@ -234,7 +234,7 @@ public class JavaSmartCompletionContributor extends CompletionContributor { for (final PsiType type : ExpectedTypesGetter.getExpectedTypes(element, false)) { final PsiClass psiClass = PsiUtil.resolveClassInType(type); if (psiClass != null && psiClass.isAnnotationType()) { - final LookupItem item = new JavaPsiClassReferenceElement(psiClass).setTailType(TailType.NONE); + final LookupItem item = JavaClassNameCompletionContributor.createClassLookupItem(psiClass, true); if (needQualify) JavaCompletionUtil.qualify(item); result.addElement(item); } @@ -254,7 +254,7 @@ public class JavaSmartCompletionContributor extends CompletionContributor { for (PsiClassType ref : method.getThrowsList().getReferencedTypes()) { final PsiClass exception = ref.resolve(); if (exception != null && throwsSet.add(exception)) { - result.addElement(TailTypeDecorator.withTail(new JavaPsiClassReferenceElement(exception).setInsertHandler(new DefaultInsertHandler()), TailType.SPACE)); + result.addElement(TailTypeDecorator.withTail(new JavaPsiClassReferenceElement(exception), TailType.SPACE)); } } } @@ -326,7 +326,7 @@ public class JavaSmartCompletionContributor extends CompletionContributor { final PsiClass psiClass = PsiUtil.resolveClassInType(type); if (psiClass == null) return; - resultSet.addElement(TailTypeDecorator.withTail(new JavaPsiClassReferenceElement(psiClass).setInsertHandler(new DefaultInsertHandler()), tail)); + resultSet.addElement(TailTypeDecorator.withTail(new JavaPsiClassReferenceElement(psiClass), tail)); } }, resultSet.getPrefixMatcher()); diff --git a/java/java-impl/src/com/intellij/codeInsight/lookup/LookupItemUtil.java b/java/java-impl/src/com/intellij/codeInsight/lookup/LookupItemUtil.java index aca3dff1c9d9..da32200d7cb4 100644 --- a/java/java-impl/src/com/intellij/codeInsight/lookup/LookupItemUtil.java +++ b/java/java-impl/src/com/intellij/codeInsight/lookup/LookupItemUtil.java @@ -16,8 +16,8 @@ package com.intellij.codeInsight.lookup; import com.intellij.codeInsight.TailType; +import com.intellij.codeInsight.completion.JavaClassNameCompletionContributor; import com.intellij.codeInsight.completion.JavaMethodCallElement; -import com.intellij.codeInsight.completion.JavaPsiClassReferenceElement; import com.intellij.codeInsight.completion.PrefixMatcher; import com.intellij.codeInsight.completion.impl.CamelHumpMatcher; import com.intellij.codeInsight.template.Template; @@ -91,7 +91,7 @@ public class LookupItemUtil{ public static LookupElement objectToLookupItem(Object object) { if (object instanceof LookupElement) return (LookupElement)object; if (object instanceof PsiClass) { - return new JavaPsiClassReferenceElement((PsiClass)object).setTailType(TailType.NONE); + return JavaClassNameCompletionContributor.createClassLookupItem((PsiClass)object, true); } if (object instanceof PsiMethod) { return new JavaMethodCallElement((PsiMethod)object);