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
.psi
.impl
.compiled
;
18 import com
.intellij
.navigation
.ItemPresentation
;
19 import com
.intellij
.openapi
.diagnostic
.Logger
;
20 import com
.intellij
.psi
.*;
21 import com
.intellij
.psi
.impl
.*;
22 import com
.intellij
.psi
.impl
.cache
.InitializerTooLongException
;
23 import com
.intellij
.psi
.impl
.cache
.TypeInfo
;
24 import com
.intellij
.psi
.impl
.java
.stubs
.JavaStubElementTypes
;
25 import com
.intellij
.psi
.impl
.java
.stubs
.PsiFieldStub
;
26 import com
.intellij
.psi
.impl
.source
.SourceTreeToPsiMap
;
27 import com
.intellij
.psi
.impl
.source
.tree
.TreeElement
;
28 import com
.intellij
.psi
.javadoc
.PsiDocComment
;
29 import com
.intellij
.psi
.presentation
.java
.JavaPresentationUtil
;
30 import com
.intellij
.psi
.search
.SearchScope
;
31 import com
.intellij
.ui
.RowIcon
;
32 import com
.intellij
.util
.Icons
;
33 import com
.intellij
.util
.IncorrectOperationException
;
34 import gnu
.trove
.THashSet
;
35 import org
.jetbrains
.annotations
.NonNls
;
36 import org
.jetbrains
.annotations
.NotNull
;
41 public class ClsFieldImpl
extends ClsRepositoryPsiElement
<PsiFieldStub
> implements PsiField
, PsiVariableEx
, ClsModifierListOwner
{
42 private static final Logger LOG
= Logger
.getInstance("#com.intellij.psi.impl.compiled.ClsFieldImpl");
44 private final PsiIdentifier myNameIdentifier
;
45 private final PsiDocComment myDocComment
;
46 private PsiTypeElement myType
= null; //guarded by PsiLock.LOCK
47 private PsiExpression myInitializer
= null; //guarded by PsiLock.LOCK
48 private boolean myInitializerInitialized
= false; //guarded by PsiLock.LOCK
50 public ClsFieldImpl(final PsiFieldStub stub
) {
52 myDocComment
= isDeprecated() ?
new ClsDocCommentImpl(this) : null;
53 myNameIdentifier
= new ClsIdentifierImpl(this, getName());
57 public PsiElement
[] getChildren() {
58 PsiDocComment docComment
= getDocComment();
59 PsiModifierList modifierList
= getModifierList();
60 PsiTypeElement type
= getTypeElement();
61 PsiIdentifier name
= getNameIdentifier();
64 (docComment
!= null ?
1 : 0)
65 + (modifierList
!= null ?
1 : 0)
66 + (type
!= null ?
1 : 0)
67 + (name
!= null ?
1 : 0);
68 PsiElement
[] children
= new PsiElement
[count
];
71 if (docComment
!= null) {
72 children
[offset
++] = docComment
;
74 if (modifierList
!= null) {
75 children
[offset
++] = modifierList
;
78 children
[offset
++] = type
;
81 children
[offset
++] = name
;
87 public PsiClass
getContainingClass() {
88 return (PsiClass
)getParent();
92 public PsiIdentifier
getNameIdentifier() {
93 return myNameIdentifier
;
98 public String
getName() {
99 return getStub().getName();
102 public PsiElement
setName(@NotNull String name
) throws IncorrectOperationException
{
103 PsiImplUtil
.setName(getNameIdentifier(), name
);
108 public PsiType
getType() {
109 return getTypeElement().getType();
112 public PsiTypeElement
getTypeElement() {
113 synchronized (LAZY_BUILT_LOCK
) {
114 if (myType
== null) {
115 String typeText
= TypeInfo
.createTypeText(getStub().getType(false));
116 myType
= new ClsTypeElementImpl(this, typeText
, ClsTypeElementImpl
.VARIANCE_NONE
);
122 public PsiModifierList
getModifierList() {
123 return getStub().findChildStubByType(JavaStubElementTypes
.MODIFIER_LIST
).getPsi();
126 public boolean hasModifierProperty(@NotNull String name
) {
127 return getModifierList().hasModifierProperty(name
);
130 public PsiExpression
getInitializer() {
131 synchronized (LAZY_BUILT_LOCK
) {
132 if (!myInitializerInitialized
) {
133 myInitializerInitialized
= true;
135 String initializerText
= getStub().getInitializerText();
136 if (initializerText
!= null) {
137 myInitializer
= ClsParsingUtil
.createExpressionFromText(initializerText
, getManager(), this);
140 catch (InitializerTooLongException e
) {
141 myInitializer
= null;
145 return myInitializer
;
149 public boolean hasInitializer() {
150 return getInitializer() != null;
153 public Object
computeConstantValue() {
154 return computeConstantValue(new THashSet
<PsiVariable
>());
157 public Object
computeConstantValue(Set
<PsiVariable
> visitedVars
) {
158 if (!hasModifierProperty(PsiModifier
.FINAL
)) return null;
159 PsiExpression initializer
= getInitializer();
160 if (initializer
== null) return null;
162 final String qName
= getContainingClass().getQualifiedName();
163 if ("java.lang.Float".equals(qName
)) {
164 @NonNls final String name
= getName();
165 if ("POSITIVE_INFINITY".equals(name
)) return new Float(Float
.POSITIVE_INFINITY
);
166 if ("NEGATIVE_INFINITY".equals(name
)) return new Float(Float
.NEGATIVE_INFINITY
);
167 if ("NaN".equals(name
)) return new Float(Float
.NaN
);
169 else if ("java.lang.Double".equals(qName
)) {
170 @NonNls final String name
= getName();
171 if ("POSITIVE_INFINITY".equals(name
)) return new Double(Double
.POSITIVE_INFINITY
);
172 if ("NEGATIVE_INFINITY".equals(name
)) return new Double(Double
.NEGATIVE_INFINITY
);
173 if ("NaN".equals(name
)) return new Double(Double
.NaN
);
176 return PsiConstantEvaluationHelperImpl
.computeCastTo(initializer
, getType(), visitedVars
);
179 public boolean isDeprecated() {
180 return getStub().isDeprecated();
183 public PsiDocComment
getDocComment() {
187 public void normalizeDeclaration() throws IncorrectOperationException
{
190 public void appendMirrorText(final int indentLevel
, final StringBuffer buffer
) {
191 ClsDocCommentImpl docComment
= (ClsDocCommentImpl
)getDocComment();
192 if (docComment
!= null) {
193 docComment
.appendMirrorText(indentLevel
, buffer
);
194 goNextLine(indentLevel
, buffer
);
196 ((ClsElementImpl
)getModifierList()).appendMirrorText(indentLevel
, buffer
);
197 ((ClsElementImpl
)getTypeElement()).appendMirrorText(indentLevel
, buffer
);
199 ((ClsElementImpl
)getNameIdentifier()).appendMirrorText(indentLevel
, buffer
);
200 if (getInitializer() != null) {
201 buffer
.append(" = ");
202 buffer
.append(getInitializer().getText());
207 public void setMirror(@NotNull TreeElement element
) {
208 setMirrorCheckingType(element
, null);
210 PsiField mirror
= (PsiField
)SourceTreeToPsiMap
.treeElementToPsi(element
);
211 if (getDocComment() != null) {
212 ((ClsElementImpl
)getDocComment()).setMirror((TreeElement
)SourceTreeToPsiMap
.psiElementToTree(mirror
.getDocComment()));
214 ((ClsElementImpl
)getModifierList()).setMirror((TreeElement
)SourceTreeToPsiMap
.psiElementToTree(mirror
.getModifierList()));
215 ((ClsElementImpl
)getTypeElement()).setMirror((TreeElement
)SourceTreeToPsiMap
.psiElementToTree(mirror
.getTypeElement()));
216 ((ClsElementImpl
)getNameIdentifier()).setMirror((TreeElement
)SourceTreeToPsiMap
.psiElementToTree(mirror
.getNameIdentifier()));
219 public void accept(@NotNull PsiElementVisitor visitor
) {
220 if (visitor
instanceof JavaElementVisitor
) {
221 ((JavaElementVisitor
)visitor
).visitField(this);
224 visitor
.visitElement(this);
228 public String
toString() {
229 return "PsiField:" + getName();
233 public PsiElement
getNavigationElement() {
234 PsiClass sourceClassMirror
= ((ClsClassImpl
)getParent()).getSourceMirrorClass();
235 PsiElement sourceFieldMirror
= sourceClassMirror
!= null ? sourceClassMirror
.findFieldByName(getName(), false) : null;
236 return sourceFieldMirror
!= null ? sourceFieldMirror
: this;
239 public ItemPresentation
getPresentation() {
240 return JavaPresentationUtil
.getFieldPresentation(this);
242 public void setInitializer(PsiExpression initializer
) throws IncorrectOperationException
{
243 throw new IncorrectOperationException();
246 public Icon
getElementIcon(final int flags
) {
247 final RowIcon baseIcon
= createLayeredIcon(Icons
.FIELD_ICON
, ElementPresentationUtil
.getFlags(this, false));
248 return ElementPresentationUtil
.addVisibilityIcon(this, flags
, baseIcon
);
252 public boolean isEquivalentTo(final PsiElement another
) {
253 return PsiClassImplUtil
.isFieldEquivalentTo(this, another
);
257 public SearchScope
getUseScope() {
258 return PsiImplUtil
.getMemberUseScope(this);
261 public PsiType
getTypeNoResolve() {
262 return getType(); //todo?