local variables and recursion checks are more important for relevance than expected...
[fedora-idea.git] / java / java-impl / src / com / intellij / codeInsight / completion / PreferDefaultTypeWeigher.java
blob86dc2de5a4194c35d113cef931260910013a3bfb
1 /*
2 * Copyright (c) 2000-2005 by JetBrains s.r.o. All Rights Reserved.
3 * Use is subject to license terms.
4 */
5 package com.intellij.codeInsight.completion;
7 import com.intellij.codeInsight.ExpectedTypeInfo;
8 import com.intellij.codeInsight.lookup.LookupElement;
9 import com.intellij.openapi.util.NullableLazyKey;
10 import com.intellij.openapi.util.Pair;
11 import com.intellij.psi.PsiClass;
12 import com.intellij.psi.PsiType;
13 import com.intellij.psi.PsiTypeParameter;
14 import com.intellij.psi.util.PsiUtil;
15 import com.intellij.psi.util.TypeConversionUtil;
16 import com.intellij.util.NullableFunction;
17 import org.jetbrains.annotations.NotNull;
18 import org.jetbrains.annotations.Nullable;
20 /**
21 * @author peter
23 public class PreferDefaultTypeWeigher extends CompletionWeigher {
24 private static final NullableLazyKey<PsiTypeParameter, CompletionLocation> TYPE_PARAMETER = NullableLazyKey.create("expectedTypes", new NullableFunction<CompletionLocation, PsiTypeParameter>() {
25 @Nullable
26 public PsiTypeParameter fun(final CompletionLocation location) {
27 final Pair<PsiClass,Integer> pair =
28 JavaSmartCompletionContributor.getTypeParameterInfo(location.getCompletionParameters().getPosition());
29 if (pair == null) return null;
30 return pair.first.getTypeParameters()[pair.second.intValue()];
32 });
35 private enum MyResult {
36 normal,
37 exactlyExpected,
38 ofDefaultType,
39 exactlyDefault,
40 expectedNoSelect
43 public MyResult weigh(@NotNull final LookupElement item, final CompletionLocation location) {
44 final Object object = item.getObject();
45 if (location.getCompletionType() != CompletionType.SMART) return MyResult.normal;
47 if (object instanceof PsiClass) {
48 final PsiTypeParameter parameter = TYPE_PARAMETER.getValue(location);
49 if (parameter != null && object.equals(PsiUtil.resolveClassInType(TypeConversionUtil.typeParameterErasure(parameter)))) {
50 return MyResult.exactlyExpected;
54 ExpectedTypeInfo[] expectedInfos = JavaCompletionUtil.EXPECTED_TYPES.getValue(location);
55 if (expectedInfos == null) return MyResult.normal;
57 PsiType itemType = JavaCompletionUtil.getLookupElementType(item);
58 if (itemType == null || !itemType.isValid()) return MyResult.normal;
60 if (object instanceof PsiClass) {
61 for (final ExpectedTypeInfo info : expectedInfos) {
62 if (TypeConversionUtil.erasure(info.getType().getDeepComponentType()).equals(TypeConversionUtil.erasure(itemType))) {
63 return AbstractExpectedTypeSkipper.skips(item, location) ? MyResult.expectedNoSelect : MyResult.exactlyExpected;
68 for (final ExpectedTypeInfo expectedInfo : expectedInfos) {
69 final PsiType defaultType = expectedInfo.getDefaultType();
70 final PsiType expectedType = expectedInfo.getType();
71 if (!expectedType.isValid()) {
72 return MyResult.normal;
75 if (defaultType != expectedType) {
76 if (defaultType.equals(itemType)) {
77 return MyResult.exactlyDefault;
80 if (defaultType.isAssignableFrom(itemType)) {
81 return MyResult.ofDefaultType;
84 if (PsiType.VOID.equals(itemType) && PsiType.VOID.equals(expectedType)) {
85 return MyResult.exactlyExpected;
89 return MyResult.normal;