1 package com
.intellij
.codeInsight
.completion
;
3 import com
.intellij
.codeInsight
.TailType
;
4 import com
.intellij
.codeInsight
.lookup
.LookupItem
;
5 import com
.intellij
.patterns
.ElementPattern
;
6 import com
.intellij
.psi
.PsiElement
;
7 import com
.intellij
.psi
.PsiFile
;
8 import com
.intellij
.psi
.PsiReference
;
9 import com
.intellij
.psi
.filters
.ContextGetter
;
10 import com
.intellij
.psi
.filters
.ElementFilter
;
11 import com
.intellij
.psi
.filters
.position
.PatternFilter
;
12 import com
.intellij
.util
.ReflectionCache
;
13 import com
.intellij
.util
.containers
.HashMap
;
14 import org
.jetbrains
.annotations
.NonNls
;
16 import java
.io
.Serializable
;
20 * Created by IntelliJ IDEA.
24 * To change this template use Options | File Templates.
27 public class CompletionVariant
{
28 protected static final TailType DEFAULT_TAIL_TYPE
= TailType
.SPACE
;
30 private final Set
<Scope
> myScopeClasses
= new HashSet
<Scope
>();
31 private ElementFilter myPosition
;
32 private final List
<CompletionVariantItem
> myCompletionsList
= new ArrayList
<CompletionVariantItem
>();
33 private final Set
<Class
> myScopeClassExceptions
= new HashSet
<Class
>();
34 private InsertHandler myInsertHandler
= null;
35 private final Map
<Object
, Serializable
> myItemProperties
= new HashMap
<Object
, Serializable
>();
37 public CompletionVariant() {
40 public CompletionVariant(Class scopeClass
, ElementPattern position
){
41 this(scopeClass
, new PatternFilter(position
));
43 public CompletionVariant(Class scopeClass
, ElementFilter position
){
44 includeScopeClass(scopeClass
);
45 myPosition
= position
;
48 public CompletionVariant(ElementPattern
<?
extends PsiElement
> position
){
49 this(new PatternFilter(position
));
51 public CompletionVariant(ElementFilter position
){
52 myPosition
= position
;
55 public boolean isScopeAcceptable(PsiElement scope
){
56 return isScopeClassAcceptable(scope
.getClass());
59 public boolean isScopeFinal(PsiElement scope
){
60 return isScopeClassFinal(scope
.getClass());
63 public InsertHandler
getInsertHandler(){
64 return myInsertHandler
;
67 public void setInsertHandler(InsertHandler handler
){
68 myInsertHandler
= handler
;
71 public void setItemProperty(Object id
, Serializable value
){
72 myItemProperties
.put(id
, value
);
75 public Map
<Object
, Serializable
> getItemProperties() {
76 return myItemProperties
;
79 public boolean isScopeClassFinal(Class scopeClass
){
80 for (final Object myScopeClass
: myScopeClasses
) {
81 Scope scope
= (Scope
)myScopeClass
;
82 if (ReflectionCache
.isAssignable(scope
.myClass
, scopeClass
) && scope
.myIsFinalScope
) {
89 public boolean isScopeClassAcceptable(Class scopeClass
){
92 for (final Object myScopeClass
: myScopeClasses
) {
93 final Class aClass
= ((Scope
)myScopeClass
).myClass
;
94 if (ReflectionCache
.isAssignable(aClass
, scopeClass
)) {
101 for (final Class aClass
: myScopeClassExceptions
) {
102 if (ReflectionCache
.isAssignable(aClass
, scopeClass
)) {
111 public void excludeScopeClass(Class
<?
> aClass
){
112 myScopeClassExceptions
.add(aClass
);
115 public void includeScopeClass(Class
<?
> aClass
){
116 myScopeClasses
.add(new Scope(aClass
, false));
119 public void includeScopeClass(Class
<?
> aClass
, boolean isFinalScope
){
120 myScopeClasses
.add(new Scope(aClass
, isFinalScope
));
123 public void addCompletionFilter(ElementFilter filter
, TailType tailType
){
124 addCompletion(filter
, tailType
);
127 public void addCompletionFilter(ElementFilter filter
){
128 addCompletionFilter(filter
, TailType
.NONE
);
131 public void addCompletion(@NonNls String keyword
){
132 addCompletion(keyword
, DEFAULT_TAIL_TYPE
);
135 public void addCompletion(@NonNls String keyword
, TailType tailType
){
136 addCompletion((Object
)keyword
, tailType
);
139 public void addCompletion(KeywordChooser chooser
){
140 addCompletion(chooser
, DEFAULT_TAIL_TYPE
);
143 public void addCompletion(KeywordChooser chooser
, TailType tailType
){
144 addCompletion((Object
)chooser
, tailType
);
147 public void addCompletion(ContextGetter chooser
){
148 addCompletion(chooser
, DEFAULT_TAIL_TYPE
);
151 public void addCompletion(ContextGetter chooser
, TailType tailType
){
152 addCompletion((Object
)chooser
, tailType
);
155 private void addCompletion(Object completion
, TailType tail
){
156 myCompletionsList
.add(new CompletionVariantItem(completion
, tail
));
159 public void addCompletion(@NonNls String
[] keywordList
){
160 addCompletion(keywordList
, DEFAULT_TAIL_TYPE
);
163 public void addCompletion(String
[] keywordList
, TailType tailType
){
164 for (String aKeywordList
: keywordList
) {
165 addCompletion(aKeywordList
, tailType
);
169 public boolean isVariantApplicable(PsiElement position
, PsiElement scope
){
170 return isScopeAcceptable(scope
) && myPosition
.isAcceptable(position
, scope
);
173 public void addReferenceCompletions(PsiReference reference
, PsiElement position
, Set
<LookupItem
> set
, final PrefixMatcher matcher
, final PsiFile file
,
174 final CompletionData completionData
){
175 for (final CompletionVariantItem ce
: myCompletionsList
) {
176 if(ce
.myCompletion
instanceof ElementFilter
){
177 final ElementFilter filter
= (ElementFilter
)ce
.myCompletion
;
178 if (LegacyCompletionContributor
.DEBUG
) {
179 System
.out
.println("CompletionVariant.addReferenceCompletions");
180 System
.out
.println("filter = " + filter
);
182 completionData
.completeReference(reference
, position
, set
, ce
.myTailType
, matcher
, file
, filter
, this);
187 public void addKeywords(Set
<LookupItem
> set
, PsiElement position
, final PrefixMatcher matcher
, final PsiFile file
,
188 final CompletionData completionData
){
190 for (final CompletionVariantItem ce
: myCompletionsList
) {
191 completionData
.addKeywords(set
, position
, matcher
, file
, this, ce
.myCompletion
, ce
.myTailType
);
195 public boolean hasReferenceFilter(){
196 for (final CompletionVariantItem item
: myCompletionsList
) {
197 if (item
.myCompletion
instanceof ElementFilter
) {
204 public boolean hasKeywordCompletions(){
205 for (final CompletionVariantItem item
: myCompletionsList
) {
206 if (!(item
.myCompletion
instanceof ElementFilter
)) {
214 private static class Scope
{
216 boolean myIsFinalScope
;
218 Scope(Class aClass
, boolean isFinalScope
){
220 myIsFinalScope
= isFinalScope
;
224 protected static class CompletionVariantItem
{
225 public Object myCompletion
;
226 public TailType myTailType
;
228 public CompletionVariantItem(Object completion
, TailType tailtype
){
229 myCompletion
= completion
;
230 myTailType
= tailtype
;
233 public String
toString(){
234 return myCompletion
.toString();
238 @SuppressWarnings({"HardCodedStringLiteral"})
239 public String
toString(){
240 return "completion variant at " + myPosition
.toString() + " completions: " + myCompletionsList
;
243 public void setCaseInsensitive(boolean caseInsensitive
) {
244 setItemProperty(LookupItem
.CASE_INSENSITIVE
, caseInsensitive
);