unify how java lookup elements determine their type

This commit is contained in:
peter
2015-08-27 15:53:00 +02:00
parent c483efa479
commit 4e5faa4c7b
10 changed files with 43 additions and 64 deletions
@@ -178,7 +178,7 @@ public class ConstructorInsertHandler implements InsertHandler<LookupElementDeco
if (newExpr != null) {
for (ExpectedTypeInfo info : ExpectedTypesProvider.getExpectedTypes(newExpr, true)) {
PsiType expected = info.getDefaultType();
if (expected.isAssignableFrom(delegate.getPsiType())) {
if (expected.isAssignableFrom(delegate.getType())) {
if (expected instanceof PsiClassType && ((PsiClassType)expected).isRaw()) {
return true;
}
@@ -293,7 +293,7 @@ public class JavaCompletionContributor extends CompletionContributor {
}
private static void registerClassFromTypeElement(LookupElement element, InheritorsHolder inheritors) {
PsiType type = assertNotNull(element.as(PsiTypeLookupItem.CLASS_CONDITION_KEY)).getPsiType();
PsiType type = assertNotNull(element.as(PsiTypeLookupItem.CLASS_CONDITION_KEY)).getType();
PsiClass aClass =
type instanceof PsiClassType && ((PsiClassType)type).getParameterCount() == 0 ? ((PsiClassType)type).resolve() : null;
if (aClass != null) {
@@ -245,48 +245,10 @@ public class JavaCompletionUtil {
return null;
}
@Nullable
private static PsiType getPsiType(final Object o) {
if (o instanceof ResolveResult) {
return getPsiType(((ResolveResult)o).getElement());
}
if (o instanceof PsiVariable) {
return ((PsiVariable)o).getType();
}
else if (o instanceof PsiMethod) {
return ((PsiMethod)o).getReturnType();
}
else if (o instanceof PsiClass) {
final PsiClass psiClass = (PsiClass)o;
return JavaPsiFacade.getInstance(psiClass.getProject()).getElementFactory().createType(psiClass);
}
else if (o instanceof PsiExpression) {
return ((PsiExpression)o).getType();
}
return null;
}
@Nullable
public static PsiType getLookupElementType(final LookupElement element) {
TypedLookupItem typed = element.as(TypedLookupItem.CLASS_CONDITION_KEY);
if (typed != null) {
return typed.getType();
}
final PsiType qualifierType = getPsiType(element.getObject());
final LookupItem lookupItem = element.as(LookupItem.CLASS_CONDITION_KEY);
if (lookupItem != null) {
final Object o = lookupItem.getAttribute(LookupItem.TYPE);
if (o instanceof PsiType) {
return (PsiType)o;
}
final PsiSubstitutor substitutor = (PsiSubstitutor)lookupItem.getAttribute(LookupItem.SUBSTITUTOR);
if (substitutor != null) {
return substitutor.substitute(qualifierType);
}
}
return qualifierType;
return typed != null ? typed.getType() : null;
}
@Nullable
@@ -424,7 +386,7 @@ public class JavaCompletionUtil {
if (plainQualifier != null) {
Object o = item.getObject();
if (o instanceof PsiMethod) {
PsiType castType = castTypeItem.getPsiType();
PsiType castType = castTypeItem.getType();
if (plainQualifier instanceof PsiClassType && castType instanceof PsiClassType) {
PsiMethod method = (PsiMethod)o;
PsiClassType.ClassResolveResult plainResult = ((PsiClassType)plainQualifier).resolveGenerics();
@@ -16,10 +16,7 @@
package com.intellij.codeInsight.completion;
import com.intellij.codeInsight.TailType;
import com.intellij.codeInsight.lookup.DefaultLookupItemRenderer;
import com.intellij.codeInsight.lookup.LookupElementPresentation;
import com.intellij.codeInsight.lookup.LookupItem;
import com.intellij.codeInsight.lookup.PsiTypeLookupItem;
import com.intellij.codeInsight.lookup.*;
import com.intellij.codeInsight.lookup.impl.JavaElementLookupRenderer;
import com.intellij.openapi.util.ClassConditionKey;
import com.intellij.openapi.util.Comparing;
@@ -41,7 +38,7 @@ import java.util.Set;
/**
* @author peter
*/
public class JavaPsiClassReferenceElement extends LookupItem<Object> {
public class JavaPsiClassReferenceElement extends LookupItem<Object> implements TypedLookupItem {
public static final Key<String> PACKAGE_NAME = Key.create("PACKAGE_NAME");
public static final ClassConditionKey<JavaPsiClassReferenceElement> CLASS_CONDITION_KEY = ClassConditionKey.create(JavaPsiClassReferenceElement.class);
private final Object myClass;
@@ -63,6 +60,14 @@ public class JavaPsiClassReferenceElement extends LookupItem<Object> {
return myForcedPresentableName;
}
@Nullable
@Override
public PsiType getType() {
PsiClass psiClass = getObject();
final PsiSubstitutor substitutor = (PsiSubstitutor)getAttribute(LookupItem.SUBSTITUTOR);
return JavaPsiFacade.getElementFactory(psiClass.getProject()).createType(psiClass, substitutor == null ? PsiSubstitutor.EMPTY : substitutor);
}
@NotNull
@Override
public String getLookupString() {
@@ -20,7 +20,6 @@ import com.intellij.codeInsight.lookup.LookupItem;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.PsiKeyword;
import com.intellij.psi.PsiPrimitiveType;
import com.intellij.psi.PsiType;
import java.util.Collection;
import java.util.LinkedHashSet;
@@ -53,7 +52,6 @@ public class NullSmartCompletionContributor extends CompletionContributor{
for (final ExpectedTypeInfo info : infos) {
if (!(info.getType() instanceof PsiPrimitiveType)) {
final LookupItem item = (LookupItem)BasicExpressionCompletionContributor.createKeywordLookupItem(parameters.getPosition(), PsiKeyword.NULL);
item.setAttribute(LookupItem.TYPE, PsiType.NULL);
result.addElement(JavaSmartCompletionContributor.decorate(item, infos));
return;
}
@@ -217,7 +217,7 @@ class TypeArgumentCompletionProvider extends CompletionProvider<CompletionParame
public void registerSingleClass(@Nullable InheritorsHolder inheritors) {
if (inheritors != null && myTypeItems.size() == 1) {
PsiType type = myTypeItems.get(0).getPsiType();
PsiType type = myTypeItems.get(0).getType();
PsiClass aClass = PsiUtil.resolveClassInClassTypeOnly(type);
if (aClass != null && !aClass.hasTypeParameters()) {
JavaCompletionUtil.setShowFQN(myTypeItems.get(0));
@@ -39,7 +39,7 @@ import java.util.Set;
/**
* @author peter
*/
public class PsiTypeLookupItem extends LookupItem {
public class PsiTypeLookupItem extends LookupItem implements TypedLookupItem {
private static final InsertHandler<PsiTypeLookupItem> DEFAULT_IMPORT_FIXER = new InsertHandler<PsiTypeLookupItem>() {
@Override
public void handleInsert(InsertionContext context, PsiTypeLookupItem item) {
@@ -65,13 +65,14 @@ public class PsiTypeLookupItem extends LookupItem {
}
@NotNull
public PsiType getPsiType() {
@Override
public PsiType getType() {
Object object = getObject();
PsiType type = object instanceof PsiType ? (PsiType)object : JavaPsiFacade.getElementFactory(((PsiClass) object).getProject()).createType((PsiClass)object);
for (int i = 0; i < getBracketsCount(); i++) {
type = new PsiArrayType(type);
}
return type;
return getSubstitutor().substitute(type);
}
@@ -191,18 +192,14 @@ public class PsiTypeLookupItem extends LookupItem {
}
public static PsiTypeLookupItem createLookupItem(@NotNull PsiType type, @Nullable PsiElement context, boolean isDiamond, InsertHandler<PsiTypeLookupItem> importFixer) {
final PsiType original = type;
public static PsiTypeLookupItem createLookupItem(@NotNull PsiType type, @Nullable PsiElement context, boolean isDiamond, InsertHandler<PsiTypeLookupItem> importFixer) {
int dim = 0;
while (type instanceof PsiArrayType) {
type = ((PsiArrayType)type).getComponentType();
dim++;
}
PsiTypeLookupItem item = doCreateItem(type, context, dim, isDiamond, importFixer);
item.setAttribute(TYPE, original);
return item;
return doCreateItem(type, context, dim, isDiamond, importFixer);
}
private static PsiTypeLookupItem doCreateItem(final PsiType type,
@@ -20,7 +20,6 @@ import com.intellij.codeInsight.lookup.LookupElement;
import com.intellij.codeInsight.lookup.PsiTypeLookupItem;
import com.intellij.codeInsight.template.*;
import com.intellij.psi.PsiArrayType;
import com.intellij.psi.PsiDocumentManager;
import com.intellij.psi.PsiExpression;
import com.intellij.psi.PsiType;
import com.intellij.util.containers.ContainerUtil;
@@ -49,7 +48,7 @@ public class ComponentTypeOfMacro extends Macro {
for (LookupElement element : lookupItems) {
PsiTypeLookupItem lookupItem = element.as(PsiTypeLookupItem.CLASS_CONDITION_KEY);
if (lookupItem != null) {
PsiType psiType = lookupItem.getPsiType();
PsiType psiType = lookupItem.getType();
if (psiType instanceof PsiArrayType) {
result.add(PsiTypeLookupItem.createLookupItem(((PsiArrayType)psiType).getComponentType(), null));
}
@@ -83,7 +82,7 @@ public class ComponentTypeOfMacro extends Macro {
for (LookupElement element : elements) {
PsiTypeLookupItem typeLookupItem = element.as(PsiTypeLookupItem.CLASS_CONDITION_KEY);
if (typeLookupItem != null) {
PsiType psiType = typeLookupItem.getPsiType();
PsiType psiType = typeLookupItem.getType();
if (psiType instanceof PsiArrayType) {
return new PsiTypeResult(((PsiArrayType)psiType).getComponentType(), context.getProject());
}
@@ -53,7 +53,6 @@ public class LookupItem<T> extends MutableLookupElement<T> implements Comparable
public static final Object FORCE_QUALIFY = Key.create("FORCE_QUALIFY");
public static final Object SUBSTITUTOR = Key.create("SUBSTITUTOR");
public static final Object TYPE = Key.create("TYPE");
public static final Object CASE_INSENSITIVE = Key.create("CASE_INSENSITIVE");
@@ -25,6 +25,7 @@ import com.intellij.psi.*;
import com.intellij.psi.search.PsiShortNamesCache;
import com.intellij.util.Consumer;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.plugins.groovy.lang.psi.GrReferenceElement;
import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElementFactory;
import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.modifiers.GrModifierList;
@@ -118,7 +119,7 @@ public class GroovyNoVariantsDelegator extends CompletionContributor {
final CompletionResultSet qualifiedCollector = result.withPrefixMatcher(fullPrefix);
InheritorsHolder inheritors = new InheritorsHolder(result);
for (final LookupElement base : suggestQualifierItems(parameters, (GrReferenceElement)qualifier, inheritors)) {
final PsiType type = JavaCompletionUtil.getLookupElementType(base);
final PsiType type = getPsiType(base.getObject());
if (type != null && !PsiType.VOID.equals(type)) {
GrReferenceElement ref = createMockReference(position, type, base);
PsiElement refName = ref.getReferenceNameElement();
@@ -139,6 +140,24 @@ public class GroovyNoVariantsDelegator extends CompletionContributor {
}
}
@Nullable
private static PsiType getPsiType(final Object o) {
if (o instanceof ResolveResult) {
return getPsiType(((ResolveResult)o).getElement());
}
if (o instanceof PsiVariable) {
return ((PsiVariable)o).getType();
}
else if (o instanceof PsiMethod) {
return ((PsiMethod)o).getReturnType();
}
else if (o instanceof PsiClass) {
final PsiClass psiClass = (PsiClass)o;
return JavaPsiFacade.getElementFactory(psiClass.getProject()).createType(psiClass);
}
return null;
}
private static GrReferenceElement createMockReference(final PsiElement place, @NotNull PsiType qualifierType, LookupElement qualifierItem) {
GroovyPsiElementFactory factory = GroovyPsiElementFactory.getInstance(place.getProject());
if (qualifierItem.getObject() instanceof PsiClass) {