IDEADEV-40041: the getter and setter method doesn't follow naming convention
[fedora-idea.git] / plugins / groovy / src / org / jetbrains / plugins / groovy / lang / psi / impl / statements / GrFieldImpl.java
blob4b5d6fb0875331ea323192f5f235f796e0f25530
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.
16 package org.jetbrains.plugins.groovy.lang.psi.impl.statements;
18 import com.intellij.lang.ASTNode;
19 import com.intellij.navigation.ItemPresentation;
20 import com.intellij.openapi.editor.colors.TextAttributesKey;
21 import com.intellij.psi.*;
22 import com.intellij.psi.impl.PsiImplUtil;
23 import com.intellij.psi.search.SearchScope;
24 import com.intellij.psi.stubs.IStubElementType;
25 import com.intellij.psi.util.CachedValue;
26 import com.intellij.psi.util.CachedValueProvider;
27 import com.intellij.psi.util.PsiModificationTracker;
28 import com.intellij.ui.LayeredIcon;
29 import com.intellij.util.IncorrectOperationException;
30 import org.jetbrains.annotations.NotNull;
31 import org.jetbrains.annotations.Nullable;
32 import org.jetbrains.plugins.groovy.GroovyIcons;
33 import org.jetbrains.plugins.groovy.lang.groovydoc.psi.api.GrDocComment;
34 import org.jetbrains.plugins.groovy.lang.groovydoc.psi.impl.GrDocCommentUtil;
35 import org.jetbrains.plugins.groovy.lang.parser.GroovyElementTypes;
36 import org.jetbrains.plugins.groovy.lang.psi.GroovyElementVisitor;
37 import org.jetbrains.plugins.groovy.lang.psi.GroovyFileBase;
38 import org.jetbrains.plugins.groovy.lang.psi.PropertyEnhancer;
39 import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.modifiers.GrModifierList;
40 import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrField;
41 import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrNamedArgumentSearchVisitor;
42 import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrClosableBlock;
43 import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression;
44 import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrTypeDefinition;
45 import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrTypeDefinitionBody;
46 import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrAccessorMethod;
47 import org.jetbrains.plugins.groovy.lang.psi.impl.synthetic.GrAccessorMethodImpl;
48 import org.jetbrains.plugins.groovy.lang.psi.stubs.GrFieldStub;
49 import org.jetbrains.plugins.groovy.lang.psi.util.GroovyPropertyUtils;
50 import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil;
52 import javax.swing.*;
53 import java.util.*;
55 /**
56 * User: Dmitry.Krasilschikov
57 * Date: 25.05.2007
59 public class GrFieldImpl extends GrVariableBaseImpl<GrFieldStub> implements GrField {
60 private GrAccessorMethod mySetter;
61 private GrAccessorMethod[] myGetters;
63 private boolean mySetterInitialized = false;
64 private boolean myGettersInitialized = false;
66 private volatile CachedValue<PsiType> myEnhancedType;
68 public GrFieldImpl(@NotNull ASTNode node) {
69 super(node);
72 public GrFieldImpl(GrFieldStub stub) {
73 this(stub, GroovyElementTypes.FIELD);
76 public GrFieldImpl(GrFieldStub stub, IStubElementType nodeType) {
77 super(stub, nodeType);
80 public void accept(GroovyElementVisitor visitor) {
81 visitor.visitField(this);
84 public String toString() {
85 return "Field";
88 public void setInitializer(@Nullable PsiExpression psiExpression) throws IncorrectOperationException {
91 public boolean isDeprecated() {
92 return false;
95 @Override
96 public PsiType getTypeGroovy() {
97 if (isProperty() && getDeclaredType() == null && getInitializer() == null) {
98 CachedValue<PsiType> enhancedType = myEnhancedType;
99 if (enhancedType == null) {
100 myEnhancedType = enhancedType = getManager().getCachedValuesManager().createCachedValue(new CachedValueProvider<PsiType>() {
101 public Result<PsiType> compute() {
102 for (PropertyEnhancer enhancer : PropertyEnhancer.EP_NAME.getExtensions()) {
103 final PsiType type = enhancer.getPropertyType(GrFieldImpl.this);
104 if (type != null) {
105 return Result.create(type, PsiModificationTracker.OUT_OF_CODE_BLOCK_MODIFICATION_COUNT);
109 return Result.create(null, PsiModificationTracker.OUT_OF_CODE_BLOCK_MODIFICATION_COUNT);
111 }, false);
113 final PsiType type = enhancedType.getValue();
114 if (type != null) {
115 return type;
118 return super.getTypeGroovy();
121 public PsiClass getContainingClass() {
122 PsiElement parent = getParent().getParent();
123 if (parent instanceof GrTypeDefinitionBody) {
124 final PsiElement pparent = parent.getParent();
125 if (pparent instanceof PsiClass) {
126 return (PsiClass)pparent;
130 final PsiFile file = getContainingFile();
131 if (file instanceof GroovyFileBase) {
132 return ((GroovyFileBase)file).getScriptClass();
135 assert false;
136 return null;
139 public boolean isProperty() {
140 // final String name = getName();
141 // if (!GroovyPropertyUtils.canBePropertyName(name)) return false;
142 final PsiClass clazz = getContainingClass();
143 if (clazz == null) return false;
144 if (clazz.isInterface()) return false;
145 final GrModifierList modifierList = getModifierList();
146 return modifierList == null || !modifierList.hasExplicitVisibilityModifiers();
149 public GrAccessorMethod getSetter() {
150 if (mySetterInitialized) return mySetter;
152 mySetter = null;
154 if (isProperty() && !hasModifierProperty(PsiModifier.FINAL)) {
155 String name = "set" + GroovyPropertyUtils.capitalize(getName());
156 final GrAccessorMethod setter = new GrAccessorMethodImpl(this, true, name);
157 final PsiClass clazz = getContainingClass();
158 if (!hasContradictingMethods(setter, clazz)) {
159 mySetter = setter;
164 mySetterInitialized = true;
165 return mySetter;
168 public void clearCaches() {
169 mySetterInitialized = myGettersInitialized = false;
170 mySetter = null;
171 myGetters = GrAccessorMethod.EMPTY_ARRAY;
172 myEnhancedType = null;
175 @NotNull
176 public GrAccessorMethod[] getGetters() {
177 if (myGettersInitialized) return myGetters;
179 myGetters = GrAccessorMethod.EMPTY_ARRAY;
181 if (isProperty()) {
182 String name = getName();
183 final PsiClass clazz = getContainingClass();
184 name = GroovyPropertyUtils.capitalize(name);
185 GrAccessorMethod getter1 = new GrAccessorMethodImpl(this, false, "get" + name);
186 if (hasContradictingMethods(getter1, clazz)) getter1 = null;
188 GrAccessorMethod getter2 = null;
189 if (PsiType.BOOLEAN.equals(getDeclaredType())) {
190 getter2 = new GrAccessorMethodImpl(this, false, "is" + name);
191 if (hasContradictingMethods(getter2, clazz)) getter2 = null;
194 if (getter1 != null || getter2 != null) {
195 if (getter1 != null && getter2 != null) {
196 myGetters = new GrAccessorMethod[]{getter1, getter2};
198 else if (getter1 != null) {
199 myGetters = new GrAccessorMethod[]{getter1};
201 else {
202 myGetters = new GrAccessorMethod[]{getter2};
208 myGettersInitialized = true;
209 return myGetters;
212 private boolean hasContradictingMethods(GrAccessorMethod proto, PsiClass clazz) {
213 PsiMethod[] methods = clazz instanceof GrTypeDefinition
214 ? ((GrTypeDefinition)clazz).findCodeMethodsBySignature(proto, true)
215 : clazz.findMethodsBySignature(proto, true);
216 for (PsiMethod method : methods) {
217 if (clazz.equals(method.getContainingClass())) return true;
219 if (PsiUtil.isAccessible(clazz, method) && method.hasModifierProperty(PsiModifier.FINAL)) return true;
222 //final property in supers
223 PsiClass aSuper = clazz.getSuperClass();
224 if (aSuper != null) {
225 PsiField field = aSuper.findFieldByName(getName(), true);
226 if (field instanceof GrField && ((GrField)field).isProperty() && field.hasModifierProperty(PsiModifier.FINAL)) return true;
229 return false;
232 @NotNull
233 public SearchScope getUseScope() {
234 if (isProperty()) {
235 return getManager().getFileManager().getUseScope(this); //maximal scope
237 return PsiImplUtil.getMemberUseScope(this);
240 @Override
241 public ItemPresentation getPresentation() {
242 return new ItemPresentation() {
243 public String getPresentableText() {
244 return getName();
247 @Nullable
248 public String getLocationString() {
249 PsiClass clazz = getContainingClass();
250 if (clazz == null) return "";
251 String name = clazz.getQualifiedName();
252 assert name != null;
253 return "(in " + name + ")";
256 @Nullable
257 public Icon getIcon(boolean open) {
258 return GrFieldImpl.this.getIcon(ICON_FLAG_VISIBILITY | ICON_FLAG_READ_STATUS);
261 @Nullable
262 public TextAttributesKey getTextAttributesKey() {
263 return null;
268 public PsiElement getOriginalElement() {
269 final PsiClass containingClass = getContainingClass();
270 if (containingClass == null) return this;
271 PsiClass originalClass = (PsiClass)containingClass.getOriginalElement();
272 PsiField originalField = originalClass.findFieldByName(getName(), false);
273 return originalField != null ? originalField : this;
276 @Nullable
277 public Icon getIcon(int flags) {
278 Icon superIcon = GroovyIcons.FIELD;
279 if (!isProperty()) return superIcon;
280 LayeredIcon rowIcon = new LayeredIcon(2);
281 rowIcon.setIcon(superIcon, 0);
282 rowIcon.setIcon(GroovyIcons.DEF, 1);
283 return rowIcon;
286 @NotNull
287 public Set<String>[] getNamedParametersArray() {
288 final GrExpression initializerGroovy = getInitializerGroovy();
290 List<Set<String>> namedParameters = new LinkedList<Set<String>>();
291 if (initializerGroovy instanceof GrClosableBlock) {
292 final GrClosableBlock closure = (GrClosableBlock)initializerGroovy;
294 final PsiParameter[] parameters = closure.getAllParameters();
295 final List<PsiParameter> parameterList = Arrays.asList(parameters);
297 for (int i = 0, parameterListSize = parameterList.size(); i < parameterListSize; i++) {
298 PsiParameter parameter = parameterList.get(i);
299 final String paramName = parameter.getName();
300 final HashSet<String> set = new HashSet<String>();
301 namedParameters.add(i, set);
303 closure.accept(new GrNamedArgumentSearchVisitor(paramName, set));
306 return namedParameters.toArray(new HashSet[namedParameters.size()]);
309 public GrDocComment getGrDocComment() {
310 return GrDocCommentUtil.findDocComment(this);