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 org
.jetbrains
.plugins
.groovy
.lang
.psi
.impl
.auxiliary
.modifiers
;
19 import com
.intellij
.lang
.ASTNode
;
20 import com
.intellij
.psi
.*;
21 import com
.intellij
.psi
.impl
.source
.tree
.TreeUtil
;
22 import com
.intellij
.util
.IncorrectOperationException
;
23 import org
.jetbrains
.annotations
.NonNls
;
24 import org
.jetbrains
.annotations
.NotNull
;
25 import org
.jetbrains
.annotations
.Nullable
;
26 import org
.jetbrains
.plugins
.groovy
.annotator
.inspections
.GroovyImmutableAnnotationInspection
;
27 import org
.jetbrains
.plugins
.groovy
.lang
.lexer
.GroovyTokenTypes
;
28 import org
.jetbrains
.plugins
.groovy
.lang
.lexer
.TokenSets
;
29 import org
.jetbrains
.plugins
.groovy
.lang
.parser
.GroovyElementTypes
;
30 import org
.jetbrains
.plugins
.groovy
.lang
.psi
.GroovyElementVisitor
;
31 import org
.jetbrains
.plugins
.groovy
.lang
.psi
.GroovyPsiElementFactory
;
32 import org
.jetbrains
.plugins
.groovy
.lang
.psi
.api
.auxiliary
.modifiers
.GrModifierList
;
33 import org
.jetbrains
.plugins
.groovy
.lang
.psi
.api
.auxiliary
.modifiers
.annotation
.GrAnnotation
;
34 import org
.jetbrains
.plugins
.groovy
.lang
.psi
.api
.statements
.GrVariableDeclaration
;
35 import org
.jetbrains
.plugins
.groovy
.lang
.psi
.api
.statements
.typedef
.GrTypeDefinition
;
36 import org
.jetbrains
.plugins
.groovy
.lang
.psi
.api
.statements
.typedef
.GrTypeDefinitionBody
;
37 import org
.jetbrains
.plugins
.groovy
.lang
.psi
.impl
.GroovyPsiElementImpl
;
39 import java
.util
.ArrayList
;
40 import java
.util
.Arrays
;
41 import java
.util
.List
;
44 * @autor: Dmitry.Krasilschikov
47 public class GrModifierListImpl
extends GroovyPsiElementImpl
implements GrModifierList
{
48 public GrModifierListImpl(@NotNull ASTNode node
) {
52 public void accept(GroovyElementVisitor visitor
) {
53 visitor
.visitModifierList(this);
56 public String
toString() {
61 public PsiElement
[] getModifiers() {
62 List
<PsiElement
> modifiers
= new ArrayList
<PsiElement
>();
63 PsiElement
[] modifiersKeywords
= findChildrenByType(TokenSets
.MODIFIERS
, PsiElement
.class);
64 GrAnnotation
[] modifiersAnnotations
= findChildrenByClass(GrAnnotation
.class);
65 PsiElement defKeyword
= findChildByType(GroovyTokenTypes
.kDEF
);
67 if (modifiersKeywords
.length
!= 0) modifiers
.addAll(Arrays
.asList(modifiersKeywords
));
69 if (modifiersAnnotations
.length
!= 0) modifiers
.addAll(Arrays
.asList(modifiersAnnotations
));
71 if (defKeyword
!= null) modifiers
.add(defKeyword
);
73 return modifiers
.toArray(new PsiElement
[modifiers
.size()]);
76 public boolean hasExplicitVisibilityModifiers() {
77 return findChildByType(TokenSets
.VISIBILITY_MODIFIERS
) != null;
80 public boolean hasModifierProperty(@NotNull @NonNls String modifier
) {
81 final PsiElement parent
= getParent();
82 if (parent
instanceof GrVariableDeclaration
&&
83 parent
.getParent() instanceof GrTypeDefinitionBody
&&
84 !hasExplicitVisibilityModifiers()) { //properties are backed by private fields
85 PsiElement pParent
= parent
.getParent().getParent();
86 if (!(pParent
instanceof PsiClass
) || !((PsiClass
)pParent
).isInterface()) {
87 if (modifier
.equals(PsiModifier
.PUBLIC
)) return true;
88 if (modifier
.equals(PsiModifier
.PROTECTED
)) return false;
89 if (modifier
.equals(PsiModifier
.PRIVATE
)) return false;
92 if (modifier
.equals(PsiModifier
.STATIC
)) return true;
93 if (modifier
.equals(PsiModifier
.FINAL
)) return true;
97 if (modifier
.equals(PsiModifier
.PUBLIC
)) {
98 //groovy type definitions and methods are public by default
99 return findChildByType(GroovyElementTypes
.kPRIVATE
) == null && findChildByType(GroovyElementTypes
.kPROTECTED
) == null;
102 if (hasOtherModifiers(modifier
)) {
106 if (!(parent
instanceof GrVariableDeclaration
)) {
107 if (modifier
.equals(PsiModifier
.ABSTRACT
)) {
108 return (parent
instanceof GrTypeDefinition
&& ((GrTypeDefinition
)parent
).isInterface()) ||
109 findChildByType(GroovyElementTypes
.kABSTRACT
) != null;
111 if (modifier
.equals(PsiModifier
.NATIVE
)) return findChildByType(GroovyElementTypes
.kNATIVE
) != null;
114 if (!(parent
instanceof GrTypeDefinition
)) {
115 //check how type def annotations influent on members annotation
116 ASTNode classDefNode
= TreeUtil
.findParent(getNode(), GroovyElementTypes
.CLASS_DEFINITION
);
117 if (classDefNode
!= null) {
118 PsiElement psiClass
= classDefNode
.getPsi();
120 assert psiClass
instanceof GrTypeDefinition
;
121 GrTypeDefinition typeDefinition
= (GrTypeDefinition
)psiClass
;
123 PsiModifierList psiClassModifierList
= typeDefinition
.getModifierList();
125 if (psiClassModifierList
!= null) {
126 PsiAnnotation
[] psiClassAnnotations
= psiClassModifierList
.getAnnotations();
128 for (PsiAnnotation psiClassAnnotation
: psiClassAnnotations
) {
129 assert psiClassAnnotation
instanceof GrAnnotation
;
131 if (GroovyImmutableAnnotationInspection
.IMMUTABLE
.equals(psiClassAnnotation
.getQualifiedName())) {
132 if (modifier
.equals(PsiModifier
.FINAL
)) return true;
133 if (modifier
.equals(PsiModifier
.PRIVATE
)) return true;
143 public boolean hasExplicitModifier(@NotNull @NonNls String name
) {
145 if (name
.equals(PsiModifier
.PUBLIC
)) return findChildByType(GroovyElementTypes
.kPUBLIC
) != null;
146 if (name
.equals(PsiModifier
.ABSTRACT
)) return findChildByType(GroovyElementTypes
.kABSTRACT
) != null;
147 if (name
.equals(PsiModifier
.NATIVE
)) return findChildByType(GroovyElementTypes
.kNATIVE
) != null;
148 return hasOtherModifiers(name
);
151 private boolean hasOtherModifiers(String name
) {
152 if (name
.equals(PsiModifier
.PRIVATE
)) return findChildByType(GroovyElementTypes
.kPRIVATE
) != null;
153 if (name
.equals(PsiModifier
.PROTECTED
)) return findChildByType(GroovyElementTypes
.kPROTECTED
) != null;
154 if (name
.equals(PsiModifier
.SYNCHRONIZED
)) return findChildByType(GroovyElementTypes
.kSYNCHRONIZED
) != null;
155 if (name
.equals(PsiModifier
.STRICTFP
)) return findChildByType(GroovyElementTypes
.kSTRICTFP
) != null;
156 if (name
.equals(PsiModifier
.STATIC
)) return findChildByType(GroovyElementTypes
.kSTATIC
) != null;
157 if (name
.equals(PsiModifier
.FINAL
)) return findChildByType(GroovyElementTypes
.kFINAL
) != null;
158 if (name
.equals(PsiModifier
.TRANSIENT
)) return findChildByType(GroovyElementTypes
.kTRANSIENT
) != null;
159 return name
.equals(PsiModifier
.VOLATILE
) && findChildByType(GroovyElementTypes
.kVOLATILE
) != null;
162 public void setModifierProperty(@NotNull @NonNls String name
, boolean doSet
) throws IncorrectOperationException
{
163 if (PsiModifier
.PACKAGE_LOCAL
.equals(name
)) {
167 final ASTNode modifierNode
= GroovyPsiElementFactory
.getInstance(getProject()).createModifierFromText(name
).getNode();
168 if (!"def".equals(name
)) {
169 final PsiElement
[] modifiers
= getModifiers();
170 if (modifiers
.length
== 1 && modifiers
[0].getText().equals("def")) {
171 getNode().replaceChild(findChildByType(GroovyTokenTypes
.kDEF
).getNode(), modifierNode
);
175 addInternal(modifierNode
, modifierNode
, null, null);
178 final PsiElement
[] modifiers
= findChildrenByType(TokenSets
.MODIFIERS
, PsiElement
.class);
179 for (PsiElement modifier
: modifiers
) {
180 if (name
.equals(modifier
.getText())) {
181 getNode().removeChild(modifier
.getNode());
187 public void checkSetModifierProperty(@NotNull @NonNls String name
, boolean value
) throws IncorrectOperationException
{
191 public GrAnnotation
[] getAnnotations() {
192 return findChildrenByClass(GrAnnotation
.class);
195 public PsiAnnotation
[] getApplicableAnnotations() {
196 return getAnnotations();
200 public PsiAnnotation
findAnnotation(@NotNull @NonNls String qualifiedName
) {
201 PsiAnnotation
[] annotations
= getAnnotations();
202 for (PsiAnnotation annotation
: annotations
) {
203 if (qualifiedName
.equals(annotation
.getQualifiedName())) return annotation
;
210 public GrAnnotation
addAnnotation(@NotNull @NonNls String qualifiedName
) {
211 final PsiClass psiClass
= JavaPsiFacade
.getInstance(getProject()).findClass(qualifiedName
, getResolveScope());
212 final GroovyPsiElementFactory factory
= GroovyPsiElementFactory
.getInstance(getProject());
213 if (psiClass
!= null && psiClass
.isAnnotationType()) {
214 final GrAnnotation annotation
= (GrAnnotation
)addAfter(factory
.createModifierFromText("@xxx"), null);
215 annotation
.getClassReference().bindToElement(psiClass
);
219 return (GrAnnotation
)addAfter(factory
.createModifierFromText("@" + qualifiedName
), null);