Only update when current project is in focus
[fedora-idea.git] / java / java-impl / src / com / intellij / codeInsight / completion / PreferExpectedTypeWeigher.java
blobbfb30046cf192f40d91a3f0c00e1b68a74f1488b
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.codeInsight.lookup.LookupItem;
10 import com.intellij.openapi.util.NullableLazyKey;
11 import com.intellij.openapi.util.Pair;
12 import com.intellij.psi.PsiClass;
13 import com.intellij.psi.PsiType;
14 import com.intellij.psi.PsiTypeParameter;
15 import com.intellij.psi.PsiSubstitutor;
16 import com.intellij.psi.util.PsiUtil;
17 import com.intellij.psi.util.TypeConversionUtil;
18 import com.intellij.util.NullableFunction;
19 import org.jetbrains.annotations.NotNull;
20 import org.jetbrains.annotations.Nullable;
22 /**
23 * @author peter
25 public class PreferExpectedTypeWeigher extends CompletionWeigher {
26 private static final NullableLazyKey<PsiTypeParameter, CompletionLocation> TYPE_PARAMETER = NullableLazyKey.create("expectedTypes", new NullableFunction<CompletionLocation, PsiTypeParameter>() {
27 @Nullable
28 public PsiTypeParameter fun(final CompletionLocation location) {
29 final Pair<PsiClass,Integer> pair =
30 JavaSmartCompletionContributor.getTypeParameterInfo(location.getCompletionParameters().getPosition());
31 if (pair == null) return null;
32 return pair.first.getTypeParameters()[pair.second.intValue()];
34 });
36 private enum MyResult {
37 normal,
38 expected,
39 exactlyExpected,
40 ofDefaultType,
41 exactlyDefault,
42 expectedNoSelect
45 public MyResult weigh(@NotNull final LookupElement item, final CompletionLocation location) {
46 final Object object = item.getObject();
47 if (object instanceof PsiClass && location.getCompletionType() != CompletionType.SMART) return MyResult.normal;
49 if (object instanceof PsiClass) {
50 final PsiTypeParameter parameter = TYPE_PARAMETER.getValue(location);
51 if (parameter != null && object.equals(PsiUtil.resolveClassInType(TypeConversionUtil.typeParameterErasure(parameter)))) {
52 return MyResult.expected;
56 ExpectedTypeInfo[] expectedInfos = JavaCompletionUtil.EXPECTED_TYPES.getValue(location);
57 if (expectedInfos == null) return MyResult.normal;
59 PsiType itemType = JavaCompletionUtil.getPsiType(object);
60 if (itemType == null || !itemType.isValid()) return MyResult.normal;
62 final LookupItem lookupItem = item.as(LookupItem.class);
63 if (lookupItem != null) {
64 final PsiSubstitutor substitutor = (PsiSubstitutor)lookupItem.getAttribute(LookupItem.SUBSTITUTOR);
65 if (substitutor != null) {
66 itemType = substitutor.substitute(itemType);
70 if (object instanceof PsiClass) {
71 for (final ExpectedTypeInfo info : expectedInfos) {
72 if (TypeConversionUtil.erasure(info.getType().getDeepComponentType()).equals(TypeConversionUtil.erasure(itemType))) {
73 return SkipAbstractExpectedTypeWeigher.getSkippingStatus(item, location) != SkipAbstractExpectedTypeWeigher.Result.ACCEPT ? MyResult.expectedNoSelect : MyResult.expected;
78 for (final ExpectedTypeInfo expectedInfo : expectedInfos) {
79 final PsiType defaultType = expectedInfo.getDefaultType();
80 final PsiType expectedType = expectedInfo.getType();
81 if (!expectedType.isValid()) {
82 return MyResult.normal;
85 if (defaultType != expectedType) {
86 if (defaultType.equals(itemType)) {
87 return MyResult.exactlyDefault;
90 if (defaultType.isAssignableFrom(itemType)) {
91 return MyResult.ofDefaultType;
94 if ((location.getCompletionType() == CompletionType.BASIC || PsiType.VOID.equals(expectedType))) {
95 if (expectedType.equals(itemType)) {
96 return MyResult.exactlyExpected;
99 if (expectedType.isAssignableFrom(itemType)) {
100 return MyResult.expected;
105 return MyResult.normal;