groovy string select word2
[fedora-idea.git] / plugins / groovy / src / org / jetbrains / plugins / groovy / lang / psi / impl / auxiliary / modifiers / GrModifierListImpl.java
blob3fed2f69db3e021d7adb09b34f9d2b1597735506
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.
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;
43 /**
44 * @autor: Dmitry.Krasilschikov
45 * @date: 18.03.2007
47 public class GrModifierListImpl extends GroovyPsiElementImpl implements GrModifierList {
48 public GrModifierListImpl(@NotNull ASTNode node) {
49 super(node);
52 public void accept(GroovyElementVisitor visitor) {
53 visitor.visitModifierList(this);
56 public String toString() {
57 return "Modifiers";
60 @NotNull
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;
91 else {
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)) {
103 return true;
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;
140 return false;
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)) {
164 return;
166 if (doSet) {
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);
172 return;
175 addInternal(modifierNode, modifierNode, null, null);
177 else {
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 {
190 @NotNull
191 public GrAnnotation[] getAnnotations() {
192 return findChildrenByClass(GrAnnotation.class);
194 @NotNull
195 public PsiAnnotation[] getApplicableAnnotations() {
196 return getAnnotations();
199 @Nullable
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;
206 return null;
209 @NotNull
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);
216 return annotation;
219 return (GrAnnotation)addAfter(factory.createModifierFromText("@" + qualifiedName), null);