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
.psi
.*;
19 import com
.intellij
.psi
.filters
.*;
20 import com
.intellij
.psi
.filters
.classes
.InterfaceFilter
;
21 import com
.intellij
.psi
.impl
.source
.jsp
.jspJava
.JspClassLevelDeclarationStatement
;
22 import com
.intellij
.psi
.javadoc
.PsiDocComment
;
23 import com
.intellij
.psi
.util
.PsiTreeUtil
;
24 import com
.intellij
.util
.ArrayUtil
;
25 import com
.intellij
.util
.containers
.HashMap
;
27 import java
.util
.ArrayList
;
28 import java
.util
.Arrays
;
29 import java
.util
.List
;
33 * Created by IntelliJ IDEA.
37 * To change this template use Options | File Templates.
40 @SuppressWarnings({"HardCodedStringLiteral"})
41 public class ModifierChooser
42 implements KeywordChooser
{
43 private static final Map
<ElementFilter
, String
[][]> myMap
= new HashMap
<ElementFilter
, String
[][]>();
46 myMap
.put(new NotFilter(new InterfaceFilter()), new String
[][]{
47 new String
[]{"public", "protected", "private"},
48 new String
[]{"static"},
49 new String
[]{"final", "abstract"},
50 new String
[]{"native"},
51 new String
[]{"synchronized"},
52 new String
[]{"strictfp"},
53 new String
[]{"volatile"},
54 new String
[]{"transient"}
57 myMap
.put(new InterfaceFilter(), new String
[][]{
58 new String
[]{"public", "protected"},
59 new String
[]{"static"},
64 myMap
.put(new ClassFilter(PsiJavaFile
.class), new String
[][]{
65 new String
[]{"public"},
66 new String
[]{"final", "abstract"}
69 myMap
.put(new OrFilter(new ClassFilter(PsiStatement
.class), new ClassFilter(PsiCodeBlock
.class)), new String
[][]{
70 new String
[]{"final", "synchronized"}
73 myMap
.put(new ClassFilter(PsiParameterList
.class), new String
[][]{
78 public String
[] getKeywords(CompletionContext context
, PsiElement position
){
79 final List
<String
> ret
= new ArrayList
<String
>();
86 scope
= position
.getParent();
88 final PsiModifierList list
= getModifierList(position
);
91 while (scope
!= null) {
92 for (final Object o
: myMap
.keySet()) {
93 final ElementFilter filter
= (ElementFilter
)o
;
94 if (filter
.isClassAcceptable(scope
.getClass()) && filter
.isAcceptable(scope
, scope
.getParent())) {
95 final String
[][] keywordSets
= myMap
.get(filter
);
96 for (int i
= 0; i
< keywordSets
.length
; i
++) {
97 final String
[] keywords
= keywordSets
[keywordSets
.length
- i
- 1];
98 boolean containModifierFlag
= false;
100 for (@Modifier String keyword
: keywords
) {
101 if (list
.hasModifierProperty(keyword
)) {
102 containModifierFlag
= true;
107 if (!containModifierFlag
) {
108 ret
.addAll(Arrays
.asList(keywords
));
114 scope
= scope
.getParent();
115 if (scope
instanceof JspClassLevelDeclarationStatement
) {
116 scope
= scope
.getContext();
118 if (scope
instanceof PsiDirectory
) break;
122 return ArrayUtil
.toStringArray(ret
);
125 private static PsiModifierList
getModifierList(PsiElement element
)
130 if(element
.getParent() instanceof PsiModifierList
)
131 return (PsiModifierList
)element
.getParent();
133 final PsiElement prev
= FilterPositionUtil
.searchNonSpaceNonCommentBack(element
);
136 final PsiModifierList modifierList
= PsiTreeUtil
.getParentOfType(prev
, PsiModifierList
.class);
137 if(modifierList
!= null){
142 PsiElement parent
= element
.getParent();
143 while(parent
!= null && (parent
instanceof PsiJavaCodeReferenceElement
144 || parent
instanceof PsiErrorElement
|| parent
instanceof PsiTypeElement
145 || parent
instanceof PsiMethod
|| parent
instanceof PsiVariable
146 || parent
instanceof PsiDeclarationStatement
|| parent
instanceof PsiImportList
147 || parent
instanceof PsiDocComment
148 || element
.getText().equals(parent
.getText()))){
149 parent
= parent
.getParent();
150 if (parent
instanceof JspClassLevelDeclarationStatement
) {
151 parent
= parent
.getContext();
155 if(parent
== null) throw new Exception();
156 for (final Object o
: myMap
.keySet()) {
157 final ElementFilter filter
= (ElementFilter
)o
;
158 if (filter
.isClassAcceptable(parent
.getClass()) && filter
.isAcceptable(parent
, parent
.getParent())) {
159 if (parent
instanceof PsiParameterList
) {
160 if (prev
== null || Arrays
.asList(new String
[]{"(", ","}).contains(prev
.getText())
161 || Arrays
.asList(new String
[]{"(", ","}).contains(element
.getText())) {
165 else if (prev
== null || JavaCompletionData
.END_OF_BLOCK
.isAcceptable(element
, prev
.getParent())) {
171 throw new Exception("Can't find modifier list");
174 public String
toString(){
175 return "modifier-chooser";