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
;
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
);
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
);
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
);
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
);
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
));