1eee7a17917550526b1803b81d40b4eae083f692
[fedora-idea.git] / platform / lang-impl / src / com / intellij / codeInsight / completion / LegacyCompletionContributor.java
blob1eee7a17917550526b1803b81d40b4eae083f692
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.
16 package com.intellij.codeInsight.completion;
18 import com.intellij.codeInsight.lookup.LookupElement;
19 import com.intellij.openapi.application.ApplicationManager;
20 import com.intellij.openapi.util.Computable;
21 import com.intellij.openapi.util.Ref;
22 import com.intellij.openapi.paths.PsiDynaReference;
23 import com.intellij.patterns.PlatformPatterns;
24 import com.intellij.patterns.PsiElementPattern;
25 import com.intellij.psi.PsiElement;
26 import com.intellij.psi.PsiFile;
27 import com.intellij.psi.PsiReference;
28 import com.intellij.psi.impl.source.resolve.reference.impl.PsiMultiReference;
29 import com.intellij.util.PairConsumer;
30 import com.intellij.util.ProcessingContext;
31 import org.jetbrains.annotations.NotNull;
33 import java.util.HashSet;
34 import java.util.LinkedHashSet;
35 import java.util.Set;
37 /**
38 * @author peter
40 public class LegacyCompletionContributor extends CompletionContributor {
41 public static boolean DEBUG = false;
43 public LegacyCompletionContributor() {
44 final PsiElementPattern.Capture<PsiElement> everywhere = PlatformPatterns.psiElement();
45 extend(CompletionType.BASIC, everywhere, new CompletionProvider<CompletionParameters>() {
46 public void addCompletions(@NotNull final CompletionParameters parameters, final ProcessingContext matchingContext, @NotNull final CompletionResultSet _result) {
47 final PsiFile file = parameters.getOriginalFile();
48 final int startOffset = parameters.getOffset();
49 final PsiElement insertedElement = parameters.getPosition();
50 CompletionData completionData = ApplicationManager.getApplication().runReadAction(new Computable<CompletionData>() {
51 public CompletionData compute() {
52 return CompletionUtil.getCompletionDataByElement(file);
54 });
55 final CompletionResultSet result = _result.withPrefixMatcher(completionData == null
56 ? CompletionData.findPrefixStatic(insertedElement, startOffset)
57 : completionData.findPrefix(insertedElement, startOffset));
58 if (completionData == null) {
59 // some completion data may depend on prefix
60 completionData = ApplicationManager.getApplication().runReadAction(new Computable<CompletionData>() {
61 public CompletionData compute() {
62 return CompletionUtil.getCompletionDataByElement(file);
64 });
67 if (completionData == null) return;
69 completeReference(parameters, result, completionData);
71 final Set<LookupElement> lookupSet = new LinkedHashSet<LookupElement>();
72 final Set<CompletionVariant> keywordVariants = new HashSet<CompletionVariant>();
73 completionData.addKeywordVariants(keywordVariants, insertedElement, parameters.getOriginalFile());
74 completionData.completeKeywordsBySet(lookupSet, keywordVariants, insertedElement, result.getPrefixMatcher(), parameters.getOriginalFile());
75 for (final LookupElement item : lookupSet) {
76 result.addElement(item);
79 });
84 public static boolean completeReference(final CompletionParameters parameters, final CompletionResultSet result, final CompletionData completionData) {
85 final Ref<Boolean> hasVariants = Ref.create(false);
86 processReferences(parameters, result, completionData, new PairConsumer<PsiReference, CompletionResultSet>() {
87 public void consume(final PsiReference reference, final CompletionResultSet resultSet) {
88 final Set<LookupElement> lookupSet = new LinkedHashSet<LookupElement>();
89 completionData.completeReference(reference, lookupSet, parameters.getPosition(), parameters.getOriginalFile(), parameters.getOffset());
90 for (final LookupElement item : lookupSet) {
91 if (resultSet.getPrefixMatcher().prefixMatches(item)) {
92 hasVariants.set(true);
93 resultSet.addElement(item);
97 });
98 return hasVariants.get().booleanValue();
101 public static void processReferences(final CompletionParameters parameters, final CompletionResultSet result, final CompletionData completionData,
102 final PairConsumer<PsiReference, CompletionResultSet> consumer) {
103 final int startOffset = parameters.getOffset();
104 final PsiReference ref = ApplicationManager.getApplication().runReadAction(new Computable<PsiReference>() {
105 public PsiReference compute() {
106 return parameters.getPosition().getContainingFile().findReferenceAt(startOffset);
109 if (ref instanceof PsiMultiReference) {
110 for (final PsiReference reference : completionData.getReferences((PsiMultiReference)ref)) {
111 processReference(result, startOffset, consumer, reference);
114 else if (ref instanceof PsiDynaReference) {
115 for (final PsiReference reference : ((PsiDynaReference<?>)ref).getReferences()) {
116 processReference(result, startOffset, consumer, reference);
119 else if (ref != null) {
120 processReference(result, startOffset, consumer, ref);
124 private static void processReference(final CompletionResultSet result, final int startOffset, final PairConsumer<PsiReference, CompletionResultSet> consumer,
125 final PsiReference reference) {
126 final int offsetInElement = startOffset - reference.getElement().getTextRange().getStartOffset();
127 final String prefix = ApplicationManager.getApplication().runReadAction(new Computable<String>() {
128 public String compute() {
129 return reference.getElement().getText().substring(reference.getRangeInElement().getStartOffset(), offsetInElement);
132 consumer.consume(reference, result.withPrefixMatcher(prefix));