by default, JavaPsiClassReferenceElement insert handler doesn't know about Java language PSI

This commit is contained in:
peter
2010-10-30 15:23:55 +04:00
parent e5002bcf03
commit d2dd377775
4 changed files with 57 additions and 67 deletions
@@ -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<PsiElement> 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<JavaPsiClassReferenceElement> JAVA_CLASS_INSERT_HANDLER = new InsertHandler<JavaPsiClassReferenceElement>() {
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<CompletionParameters>(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<JavaPsiClassReferenceElement>() {
@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
@@ -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<Object> {
public static final InsertHandler<JavaPsiClassReferenceElement> JAVA_CLASS_INSERT_HANDLER = new InsertHandler<JavaPsiClassReferenceElement>() {
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<Object> {
private final Object myClass;
private final String myQualifiedName;
@@ -68,7 +34,8 @@ public class JavaPsiClassReferenceElement extends LookupItem<Object> {
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
@@ -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());
@@ -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);