mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-08-26 15:27:45 +07:00
local variables and recursion checks are more important for relevance than expected types in basic completion
This commit is contained in:
+7
-3
@@ -15,9 +15,9 @@ import com.intellij.psi.util.TypeConversionUtil;
|
||||
/**
|
||||
* @author peter
|
||||
*/
|
||||
public class SkipAbstractExpectedTypeWeigher extends CompletionPreselectSkipper {
|
||||
public class AbstractExpectedTypeSkipper extends CompletionPreselectSkipper {
|
||||
|
||||
enum Result {
|
||||
private enum Result {
|
||||
NON_DEFAULT,
|
||||
STRING,
|
||||
ABSTRACT,
|
||||
@@ -26,10 +26,14 @@ public class SkipAbstractExpectedTypeWeigher extends CompletionPreselectSkipper
|
||||
|
||||
@Override
|
||||
public boolean skipElement(LookupElement element, CompletionLocation location) {
|
||||
return skips(element, location);
|
||||
}
|
||||
|
||||
public static boolean skips(LookupElement element, CompletionLocation location) {
|
||||
return getSkippingStatus(element, location) != Result.ACCEPT;
|
||||
}
|
||||
|
||||
public static Result getSkippingStatus(final LookupElement item, final CompletionLocation location) {
|
||||
private static Result getSkippingStatus(final LookupElement item, final CompletionLocation location) {
|
||||
if (location.getCompletionType() != CompletionType.SMART) return Result.ACCEPT;
|
||||
|
||||
final PsiExpression expression = PsiTreeUtil.getParentOfType(location.getCompletionParameters().getPosition(), PsiExpression.class);
|
||||
@@ -680,7 +680,7 @@ public class JavaCompletionUtil {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static PsiType getPsiType(final Object o) {
|
||||
private static PsiType getPsiType(final Object o) {
|
||||
if (o instanceof PsiVariable) {
|
||||
return ((PsiVariable)o).getType();
|
||||
}
|
||||
@@ -768,28 +768,18 @@ public class JavaCompletionUtil {
|
||||
|
||||
@Nullable
|
||||
public static PsiType getLookupElementType(final LookupElement element) {
|
||||
PsiType qualifierType = null;
|
||||
final TypedLookupItem typed = element.as(TypedLookupItem.class);
|
||||
if (typed != null) {
|
||||
return typed.getType();
|
||||
}
|
||||
|
||||
final Object o = element.getObject();
|
||||
if (o instanceof PsiVariable) {
|
||||
qualifierType = ((PsiVariable)o).getType();
|
||||
}
|
||||
else if (o instanceof PsiMethod) {
|
||||
qualifierType = ((PsiMethod)o).getReturnType();
|
||||
}
|
||||
else if (o instanceof PsiExpression) {
|
||||
qualifierType = ((PsiExpression) o).getType();
|
||||
}
|
||||
|
||||
final PsiType qualifierType = getPsiType(element.getObject());
|
||||
final LookupItem lookupItem = element.as(LookupItem.class);
|
||||
if (lookupItem != null) {
|
||||
final PsiSubstitutor substitutor = (PsiSubstitutor)lookupItem.getAttribute(LookupItem.SUBSTITUTOR);
|
||||
if (substitutor != null) {
|
||||
qualifierType = substitutor.substitute(qualifierType);
|
||||
return substitutor.substitute(qualifierType);
|
||||
}
|
||||
}
|
||||
return qualifierType;
|
||||
|
||||
@@ -0,0 +1,91 @@
|
||||
/*
|
||||
* Copyright (c) 2000-2005 by JetBrains s.r.o. All Rights Reserved.
|
||||
* Use is subject to license terms.
|
||||
*/
|
||||
package com.intellij.codeInsight.completion;
|
||||
|
||||
import com.intellij.codeInsight.ExpectedTypeInfo;
|
||||
import com.intellij.codeInsight.lookup.LookupElement;
|
||||
import com.intellij.openapi.util.NullableLazyKey;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.psi.PsiClass;
|
||||
import com.intellij.psi.PsiType;
|
||||
import com.intellij.psi.PsiTypeParameter;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
import com.intellij.psi.util.TypeConversionUtil;
|
||||
import com.intellij.util.NullableFunction;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* @author peter
|
||||
*/
|
||||
public class PreferDefaultTypeWeigher extends CompletionWeigher {
|
||||
private static final NullableLazyKey<PsiTypeParameter, CompletionLocation> TYPE_PARAMETER = NullableLazyKey.create("expectedTypes", new NullableFunction<CompletionLocation, PsiTypeParameter>() {
|
||||
@Nullable
|
||||
public PsiTypeParameter fun(final CompletionLocation location) {
|
||||
final Pair<PsiClass,Integer> pair =
|
||||
JavaSmartCompletionContributor.getTypeParameterInfo(location.getCompletionParameters().getPosition());
|
||||
if (pair == null) return null;
|
||||
return pair.first.getTypeParameters()[pair.second.intValue()];
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
private enum MyResult {
|
||||
normal,
|
||||
exactlyExpected,
|
||||
ofDefaultType,
|
||||
exactlyDefault,
|
||||
expectedNoSelect
|
||||
}
|
||||
|
||||
public MyResult weigh(@NotNull final LookupElement item, final CompletionLocation location) {
|
||||
final Object object = item.getObject();
|
||||
if (location.getCompletionType() != CompletionType.SMART) return MyResult.normal;
|
||||
|
||||
if (object instanceof PsiClass) {
|
||||
final PsiTypeParameter parameter = TYPE_PARAMETER.getValue(location);
|
||||
if (parameter != null && object.equals(PsiUtil.resolveClassInType(TypeConversionUtil.typeParameterErasure(parameter)))) {
|
||||
return MyResult.exactlyExpected;
|
||||
}
|
||||
}
|
||||
|
||||
ExpectedTypeInfo[] expectedInfos = JavaCompletionUtil.EXPECTED_TYPES.getValue(location);
|
||||
if (expectedInfos == null) return MyResult.normal;
|
||||
|
||||
PsiType itemType = JavaCompletionUtil.getLookupElementType(item);
|
||||
if (itemType == null || !itemType.isValid()) return MyResult.normal;
|
||||
|
||||
if (object instanceof PsiClass) {
|
||||
for (final ExpectedTypeInfo info : expectedInfos) {
|
||||
if (TypeConversionUtil.erasure(info.getType().getDeepComponentType()).equals(TypeConversionUtil.erasure(itemType))) {
|
||||
return AbstractExpectedTypeSkipper.skips(item, location) ? MyResult.expectedNoSelect : MyResult.exactlyExpected;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (final ExpectedTypeInfo expectedInfo : expectedInfos) {
|
||||
final PsiType defaultType = expectedInfo.getDefaultType();
|
||||
final PsiType expectedType = expectedInfo.getType();
|
||||
if (!expectedType.isValid()) {
|
||||
return MyResult.normal;
|
||||
}
|
||||
|
||||
if (defaultType != expectedType) {
|
||||
if (defaultType.equals(itemType)) {
|
||||
return MyResult.exactlyDefault;
|
||||
}
|
||||
|
||||
if (defaultType.isAssignableFrom(itemType)) {
|
||||
return MyResult.ofDefaultType;
|
||||
}
|
||||
}
|
||||
if (PsiType.VOID.equals(itemType) && PsiType.VOID.equals(expectedType)) {
|
||||
return MyResult.exactlyExpected;
|
||||
}
|
||||
}
|
||||
|
||||
return MyResult.normal;
|
||||
}
|
||||
}
|
||||
+7
-63
@@ -6,75 +6,31 @@ package com.intellij.codeInsight.completion;
|
||||
|
||||
import com.intellij.codeInsight.ExpectedTypeInfo;
|
||||
import com.intellij.codeInsight.lookup.LookupElement;
|
||||
import com.intellij.codeInsight.lookup.LookupItem;
|
||||
import com.intellij.openapi.util.NullableLazyKey;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.psi.PsiClass;
|
||||
import com.intellij.psi.PsiType;
|
||||
import com.intellij.psi.PsiTypeParameter;
|
||||
import com.intellij.psi.PsiSubstitutor;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
import com.intellij.psi.util.TypeConversionUtil;
|
||||
import com.intellij.util.NullableFunction;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* @author peter
|
||||
*/
|
||||
public class PreferExpectedTypeWeigher extends CompletionWeigher {
|
||||
private static final NullableLazyKey<PsiTypeParameter, CompletionLocation> TYPE_PARAMETER = NullableLazyKey.create("expectedTypes", new NullableFunction<CompletionLocation, PsiTypeParameter>() {
|
||||
@Nullable
|
||||
public PsiTypeParameter fun(final CompletionLocation location) {
|
||||
final Pair<PsiClass,Integer> pair =
|
||||
JavaSmartCompletionContributor.getTypeParameterInfo(location.getCompletionParameters().getPosition());
|
||||
if (pair == null) return null;
|
||||
return pair.first.getTypeParameters()[pair.second.intValue()];
|
||||
}
|
||||
});
|
||||
|
||||
private enum MyResult {
|
||||
normal,
|
||||
expected,
|
||||
exactlyExpected,
|
||||
ofDefaultType,
|
||||
exactlyDefault,
|
||||
expectedNoSelect
|
||||
}
|
||||
|
||||
public MyResult weigh(@NotNull final LookupElement item, final CompletionLocation location) {
|
||||
final Object object = item.getObject();
|
||||
if (object instanceof PsiClass && location.getCompletionType() != CompletionType.SMART) return MyResult.normal;
|
||||
|
||||
if (object instanceof PsiClass) {
|
||||
final PsiTypeParameter parameter = TYPE_PARAMETER.getValue(location);
|
||||
if (parameter != null && object.equals(PsiUtil.resolveClassInType(TypeConversionUtil.typeParameterErasure(parameter)))) {
|
||||
return MyResult.expected;
|
||||
}
|
||||
}
|
||||
if (location.getCompletionType() != CompletionType.BASIC) return MyResult.normal;
|
||||
if (item.getObject() instanceof PsiClass) return MyResult.normal;
|
||||
|
||||
ExpectedTypeInfo[] expectedInfos = JavaCompletionUtil.EXPECTED_TYPES.getValue(location);
|
||||
if (expectedInfos == null) return MyResult.normal;
|
||||
|
||||
PsiType itemType = JavaCompletionUtil.getPsiType(object);
|
||||
PsiType itemType = JavaCompletionUtil.getLookupElementType(item);
|
||||
if (itemType == null || !itemType.isValid()) return MyResult.normal;
|
||||
|
||||
final LookupItem lookupItem = item.as(LookupItem.class);
|
||||
if (lookupItem != null) {
|
||||
final PsiSubstitutor substitutor = (PsiSubstitutor)lookupItem.getAttribute(LookupItem.SUBSTITUTOR);
|
||||
if (substitutor != null) {
|
||||
itemType = substitutor.substitute(itemType);
|
||||
}
|
||||
}
|
||||
|
||||
if (object instanceof PsiClass) {
|
||||
for (final ExpectedTypeInfo info : expectedInfos) {
|
||||
if (TypeConversionUtil.erasure(info.getType().getDeepComponentType()).equals(TypeConversionUtil.erasure(itemType))) {
|
||||
return SkipAbstractExpectedTypeWeigher.getSkippingStatus(item, location) != SkipAbstractExpectedTypeWeigher.Result.ACCEPT ? MyResult.expectedNoSelect : MyResult.expected;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (final ExpectedTypeInfo expectedInfo : expectedInfos) {
|
||||
final PsiType defaultType = expectedInfo.getDefaultType();
|
||||
final PsiType expectedType = expectedInfo.getType();
|
||||
@@ -82,23 +38,11 @@ public class PreferExpectedTypeWeigher extends CompletionWeigher {
|
||||
return MyResult.normal;
|
||||
}
|
||||
|
||||
if (defaultType != expectedType) {
|
||||
if (defaultType.equals(itemType)) {
|
||||
return MyResult.exactlyDefault;
|
||||
}
|
||||
|
||||
if (defaultType.isAssignableFrom(itemType)) {
|
||||
return MyResult.ofDefaultType;
|
||||
}
|
||||
if (defaultType != expectedType && defaultType.isAssignableFrom(itemType)) {
|
||||
return MyResult.ofDefaultType;
|
||||
}
|
||||
if ((location.getCompletionType() == CompletionType.BASIC || PsiType.VOID.equals(expectedType))) {
|
||||
if (expectedType.equals(itemType)) {
|
||||
return MyResult.exactlyExpected;
|
||||
}
|
||||
|
||||
if (expectedType.isAssignableFrom(itemType)) {
|
||||
return MyResult.expected;
|
||||
}
|
||||
if (expectedType.isAssignableFrom(itemType)) {
|
||||
return MyResult.expected;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -54,7 +54,7 @@ public class RecursionWeigher extends CompletionWeigher {
|
||||
if (expression != null) {
|
||||
final ExpectedTypeInfo[] expectedInfos = JavaCompletionUtil.EXPECTED_TYPES.getValue(location);
|
||||
if (expectedInfos != null) {
|
||||
final PsiType itemType = JavaCompletionUtil.getPsiType(object);
|
||||
final PsiType itemType = JavaCompletionUtil.getLookupElementType(element);
|
||||
if (itemType != null) {
|
||||
for (final ExpectedTypeInfo expectedInfo : expectedInfos) {
|
||||
if (positionMethod.equals(expectedInfo.getCalledMethod()) && expectedInfo.getType().isAssignableFrom(itemType)) {
|
||||
|
||||
Reference in New Issue
Block a user