update copyrights
[fedora-idea.git] / platform / lang-impl / src / com / intellij / codeInsight / completion / CompletionLookupArranger.java
blobebd9f17e2837231ca0a0d9a57b5b87c83d34d2fd
1 /*
2 * Copyright 2000-2009 JetBrains s.r.o.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 package com.intellij.codeInsight.completion;
19 import com.intellij.codeInsight.lookup.*;
20 import com.intellij.codeInsight.lookup.impl.LookupImpl;
21 import com.intellij.codeInsight.lookup.impl.LookupItemWeightComparable;
22 import com.intellij.openapi.util.Key;
23 import com.intellij.psi.PsiElement;
24 import com.intellij.psi.WeighingService;
25 import com.intellij.psi.statistics.StatisticsInfo;
26 import com.intellij.psi.statistics.StatisticsManager;
28 import java.util.Collections;
29 import java.util.Comparator;
30 import java.util.List;
32 public class CompletionLookupArranger extends LookupArranger {
33 public static final Key<LookupItemWeightComparable> RELEVANCE_KEY = Key.create("RELEVANCE_KEY");
34 private static final Key<Comparable> SORTING_KEY = Key.create("SORTING_KEY");
35 private static final String SELECTED = "selected";
36 static final String IGNORED = "ignored";
37 private final CompletionLocation myLocation;
38 public static final Key<Comparable[]> WEIGHT = Key.create("WEIGHT");
40 public CompletionLookupArranger(final CompletionParameters parameters) {
41 myLocation = new CompletionLocation(parameters);
44 @Override
45 public void sortItems(List<LookupElement> items) {
46 Collections.sort(items, new Comparator<LookupElement>() {
47 public int compare(LookupElement o1, LookupElement o2) {
48 //noinspection unchecked
49 return getSortingWeight(o1).compareTo(getSortingWeight(o2));
51 });
54 public void itemSelected(LookupElement item, final Lookup lookup) {
55 final StatisticsManager manager = StatisticsManager.getInstance();
56 manager.incUseCount(CompletionService.STATISTICS_KEY, item, myLocation);
57 final List<LookupElement> items = lookup.getItems();
58 final LookupImpl lookupImpl = (LookupImpl)lookup;
59 final int count = Math.min(lookupImpl.getPreferredItemsCount(), lookupImpl.getList().getSelectedIndex());
60 for (int i = 0; i < count; i++) {
61 final LookupElement element = items.get(i);
62 StatisticsInfo info = StatisticsManager.serialize(CompletionService.STATISTICS_KEY, element, myLocation);
63 if (info != null && info != StatisticsInfo.EMPTY && manager.getUseCount(info) == 0) {
64 manager.incUseCount(new StatisticsInfo(composeContextWithValue(info), item == element ? SELECTED : IGNORED));
70 public int suggestPreselectedItem(List<LookupElement> sorted) {
71 final CompletionPreselectSkipper[] skippers = CompletionPreselectSkipper.EP_NAME.getExtensions();
73 nextItem: for (int i = 0; i < sorted.size(); i++){
74 LookupElement item = sorted.get(i);
75 final Object obj = item.getObject();
76 if (obj instanceof PsiElement && !((PsiElement)obj).isValid()) continue;
78 for (final CompletionPreselectSkipper skipper : skippers) {
79 if (skipper.skipElement(item, myLocation)) {
80 continue nextItem;
84 return i;
86 return sorted.size() - 1;
89 public static String composeContextWithValue(final StatisticsInfo info) {
90 return info.getContext() + "###" + info.getValue();
93 public Comparable[] getRelevanceWeight(final LookupElement item) {
94 if (item.getUserData(WEIGHT) != null) return item.getUserData(WEIGHT);
96 final Comparable[] result = new Comparable[]{WeighingService.weigh(CompletionService.RELEVANCE_KEY, item, myLocation)};
98 item.putUserData(WEIGHT, result);
100 return result;
103 public Comparable getSortingWeight(final LookupElement item) {
104 if (item.getUserData(SORTING_KEY) != null) return item.getUserData(SORTING_KEY);
106 final Comparable result = WeighingService.weigh(CompletionService.SORTING_KEY, item, myLocation);
108 item.putUserData(SORTING_KEY, result);
110 return result;
114 public static int doCompare(final double priority1, final double priority2, final Comparable[] weight1, final Comparable[] weight2) {
115 if (priority1 != priority2) {
116 final double v = priority1 - priority2;
117 if (v > 0) return -1;
118 if (v < 0) return 1;
121 for (int i = 0; i < weight1.length; i++) {
122 final Comparable w1 = weight1[i];
123 final Comparable w2 = weight2[i];
124 if (w1 != null || w2 != null) {
125 if (w1 == null) return 1;
126 if (w2 == null) return -1;
127 //noinspection unchecked
128 final int res = w1.compareTo(w2);
129 if (res != 0) return -res;
133 return 0;
136 @Override
137 public LookupItemWeightComparable getRelevance(LookupElement item) {
138 if (item.getUserData(RELEVANCE_KEY) != null) return item.getUserData(RELEVANCE_KEY);
140 final double priority = item instanceof LookupItem ? ((LookupItem)item).getPriority() : 0;
141 final LookupItemWeightComparable result = new LookupItemWeightComparable(priority, getRelevanceWeight(item));
143 item.putUserData(RELEVANCE_KEY, result);
145 return result;