update copyright
[fedora-idea.git] / java / java-impl / src / com / intellij / psi / impl / source / tree / java / PsiNameValuePairImpl.java
blobef6b927611cdbf679b858ced007b1ad093ec5a3c
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 com.intellij.psi.impl.source.tree.java;
18 import com.intellij.lang.ASTNode;
19 import com.intellij.openapi.diagnostic.Logger;
20 import com.intellij.openapi.util.TextRange;
21 import com.intellij.psi.*;
22 import com.intellij.psi.impl.PsiImplUtil;
23 import com.intellij.psi.impl.source.Constants;
24 import com.intellij.psi.impl.source.SourceTreeToPsiMap;
25 import com.intellij.psi.impl.source.tree.*;
26 import com.intellij.psi.tree.ChildRoleBase;
27 import com.intellij.psi.util.MethodSignature;
28 import com.intellij.psi.util.MethodSignatureUtil;
29 import com.intellij.util.ArrayUtil;
30 import com.intellij.util.CharTable;
31 import com.intellij.util.IncorrectOperationException;
32 import org.jetbrains.annotations.NotNull;
34 /**
35 * @author ven
38 //Retrieves method reference from this pair, do NOT reuse!!!
39 public class PsiNameValuePairImpl extends CompositePsiElement implements PsiNameValuePair, Constants {
40 private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.tree.java.PsiNameValuePairImpl");
41 private volatile String myCachedName = null;
42 private volatile PsiIdentifier myCachedNameIdentifier = null;
43 private volatile PsiAnnotationMemberValue myCachedValue = null;
44 private volatile boolean myNameCached = false;
46 public void clearCaches() {
47 myNameCached = false;
48 myCachedName = null;
49 myCachedNameIdentifier = null;
50 myCachedValue = null;
51 super.clearCaches();
54 public PsiNameValuePairImpl() {
55 super(NAME_VALUE_PAIR);
58 public PsiIdentifier getNameIdentifier() {
59 PsiIdentifier cachedNameIdentifier = myCachedNameIdentifier;
60 if (!myNameCached) {
61 myCachedNameIdentifier = cachedNameIdentifier = (PsiIdentifier)findChildByRoleAsPsiElement(ChildRole.NAME);
62 myCachedName = cachedNameIdentifier == null ? null : cachedNameIdentifier.getText();
63 myNameCached = true;
65 return cachedNameIdentifier;
68 public String getName() {
69 String cachedName = myCachedName;
70 if (!myNameCached) {
71 PsiIdentifier identifier;
72 myCachedNameIdentifier = identifier = (PsiIdentifier)findChildByRoleAsPsiElement(ChildRole.NAME);
73 myCachedName = cachedName = identifier == null ? null : identifier.getText();
74 myNameCached = true;
76 return cachedName;
79 public PsiAnnotationMemberValue getValue() {
80 PsiAnnotationMemberValue cachedValue = myCachedValue;
81 if (cachedValue == null) {
82 myCachedValue = cachedValue = (PsiAnnotationMemberValue)findChildByRoleAsPsiElement(ChildRole.ANNOTATION_VALUE);
85 return cachedValue;
88 @NotNull
89 public PsiAnnotationMemberValue setValue(@NotNull PsiAnnotationMemberValue newValue) {
90 getValue().replace(newValue);
91 return getValue();
94 public int getChildRole(ASTNode child) {
95 if (ANNOTATION_MEMBER_VALUE_BIT_SET.contains(child.getElementType())) {
96 return ChildRole.ANNOTATION_VALUE;
98 else if (child.getElementType() == IDENTIFIER) {
99 return ChildRole.NAME;
101 else if (child.getElementType() == EQ) {
102 return ChildRole.OPERATION_SIGN;
105 return ChildRoleBase.NONE;
108 public ASTNode findChildByRole(int role) {
109 if (role == ChildRole.NAME) {
110 return findChildByType(IDENTIFIER);
112 else if (role == ChildRole.ANNOTATION_VALUE) {
113 return findChildByType(ANNOTATION_MEMBER_VALUE_BIT_SET);
115 else if (role == ChildRole.OPERATION_SIGN) {
116 return findChildByType(EQ);
119 return null;
122 public String toString() {
123 return "PsiNameValuePair";
126 public PsiReference getReference() {
127 return new PsiReference() {
128 private PsiClass getReferencedClass () {
129 LOG.assertTrue(getTreeParent().getElementType() == ANNOTATION_PARAMETER_LIST && getTreeParent().getTreeParent().getElementType() == ANNOTATION);
130 PsiAnnotationImpl annotation = (PsiAnnotationImpl)getTreeParent().getTreeParent().getPsi();
131 PsiJavaCodeReferenceElement nameRef = annotation.getNameReferenceElement();
132 return nameRef == null ? null : (PsiClass)nameRef.resolve();
135 public PsiElement getElement() {
136 PsiIdentifier nameIdentifier = getNameIdentifier();
137 if (nameIdentifier != null) {
138 return nameIdentifier;
139 } else {
140 return PsiNameValuePairImpl.this;
144 public TextRange getRangeInElement() {
145 PsiIdentifier id = getNameIdentifier();
146 if (id != null) {
147 return new TextRange(0, id.getTextLength());
149 return new TextRange(0, 0);
152 public PsiElement resolve() {
153 PsiClass refClass = getReferencedClass();
154 if (refClass == null) return null;
155 String name = getName();
156 if (name == null) name = PsiAnnotation.DEFAULT_REFERENCED_METHOD_NAME;
157 MethodSignature signature = MethodSignatureUtil.createMethodSignature(name, PsiType.EMPTY_ARRAY, PsiTypeParameter.EMPTY_ARRAY, PsiSubstitutor.EMPTY);
158 return MethodSignatureUtil.findMethodBySignature(refClass, signature, false);
161 public String getCanonicalText() {
162 String name = getName();
163 return name != null ? name : PsiAnnotation.DEFAULT_REFERENCED_METHOD_NAME;
166 public PsiElement handleElementRename(String newElementName) throws IncorrectOperationException {
167 PsiIdentifier nameIdentifier = getNameIdentifier();
168 if (nameIdentifier != null) {
169 PsiImplUtil.setName(nameIdentifier, newElementName);
171 else if (ANNOTATION_MEMBER_VALUE_BIT_SET.contains(getFirstChildNode().getElementType())) {
172 PsiElementFactory factory = JavaPsiFacade.getInstance(getProject()).getElementFactory();
173 nameIdentifier = factory.createIdentifier(newElementName);
174 addBefore(nameIdentifier, SourceTreeToPsiMap.treeElementToPsi(getFirstChildNode()));
177 return PsiNameValuePairImpl.this;
180 public PsiElement bindToElement(@NotNull PsiElement element) throws IncorrectOperationException {
181 throw new IncorrectOperationException("Not implemented");
184 public boolean isReferenceTo(PsiElement element) {
185 return element instanceof PsiMethod && element.equals(resolve());
188 public Object[] getVariants() {
189 return ArrayUtil.EMPTY_OBJECT_ARRAY;
192 public boolean isSoft() {
193 return false;
198 public final void accept(@NotNull PsiElementVisitor visitor) {
199 if (visitor instanceof JavaElementVisitor) {
200 ((JavaElementVisitor)visitor).visitNameValuePair(this);
202 else {
203 visitor.visitElement(this);
207 public TreeElement addInternal(TreeElement first, ASTNode last, ASTNode anchor, Boolean before) {
208 final CharTable treeCharTab = SharedImplUtil.findCharTableByTree(this);
209 final TreeElement treeElement = super.addInternal(first, last, anchor, before);
210 if (first == last && first.getElementType() == ElementType.IDENTIFIER) {
211 LeafElement eq = Factory.createSingleLeafElement(ElementType.EQ, "=", 0, 1, treeCharTab, getManager());
212 super.addInternal(eq, eq, first, Boolean.FALSE);
214 return treeElement;
217 public void deleteChildInternal(@NotNull ASTNode child) {
218 super.deleteChildInternal(child);
219 if (child.getElementType() == JavaTokenType.IDENTIFIER) {
220 super.deleteChildInternal(findChildByRole(ChildRole.OPERATION_SIGN));