1 /*******************************************************************************
2 * Copyright (c) 2005, 2008 BEA Systems, Inc.
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Eclipse Public License v1.0
5 * which accompanies this distribution, and is available at
6 * http://www.eclipse.org/legal/epl-v10.html
9 * tyeung@bea.com - initial API and implementation
10 * IBM Corporation - implemented methods from IBinding
11 * IBM Corporation - renamed from ResolvedAnnotation to AnnotationBinding
12 *******************************************************************************/
13 package net.sourceforge.phpdt.core.dom;
15 import net.sourceforge.phpdt.core.IAnnotatable;
16 import net.sourceforge.phpdt.core.ICompilationUnit;
17 import net.sourceforge.phpdt.core.IJavaElement;
18 import net.sourceforge.phpdt.internal.compiler.lookup.ElementValuePair;
19 import net.sourceforge.phpdt.internal.compiler.lookup.MethodBinding;
20 import net.sourceforge.phpdt.internal.compiler.lookup.ReferenceBinding;
21 import net.sourceforge.phpdt.internal.compiler.lookup.TagBits;
22 import net.sourceforge.phpdt.internal.compiler.util.*;
27 class AnnotationBinding implements IAnnotationBinding {
28 static final AnnotationBinding[] NoAnnotations = new AnnotationBinding[0];
29 private net.sourceforge.phpdt.internal.compiler.lookup.AnnotationBinding binding;
30 private BindingResolver bindingResolver;
33 AnnotationBinding(net.sourceforge.phpdt.internal.compiler.lookup.AnnotationBinding annotation, BindingResolver resolver) {
34 if (annotation == null)
35 throw new IllegalStateException();
37 bindingResolver = resolver;
40 public IAnnotationBinding[] getAnnotations() {
44 public ITypeBinding getAnnotationType() {
45 ITypeBinding typeBinding = this.bindingResolver.getTypeBinding(this.binding.getAnnotationType());
46 if (typeBinding == null)
51 public IMemberValuePairBinding[] getDeclaredMemberValuePairs() {
52 ReferenceBinding typeBinding = this.binding.getAnnotationType();
53 if (typeBinding == null || ((typeBinding.tagBits & TagBits.HasMissingType) != 0)) {
54 return MemberValuePairBinding.NoPair;
56 ElementValuePair[] internalPairs = this.binding.getElementValuePairs();
57 int length = internalPairs.length;
58 IMemberValuePairBinding[] pairs = length == 0 ? MemberValuePairBinding.NoPair : new MemberValuePairBinding[length];
60 for (int i = 0; i < length; i++) {
61 ElementValuePair valuePair = internalPairs[i];
62 if (valuePair.binding == null) continue;
63 pairs[counter++] = this.bindingResolver.getMemberValuePairBinding(valuePair);
65 if (counter == 0) return MemberValuePairBinding.NoPair;
66 if (counter != length) {
68 System.arraycopy(pairs, 0, (pairs = new MemberValuePairBinding[counter]), 0, counter);
73 public IMemberValuePairBinding[] getAllMemberValuePairs() {
74 IMemberValuePairBinding[] pairs = getDeclaredMemberValuePairs();
75 ReferenceBinding typeBinding = this.binding.getAnnotationType();
76 if (typeBinding == null || ((typeBinding.tagBits & TagBits.HasMissingType) != 0)) return pairs;
77 MethodBinding[] methods = typeBinding.availableMethods(); // resilience
78 int methodLength = methods == null ? 0 : methods.length;
79 if (methodLength == 0) return pairs;
81 int declaredLength = pairs.length;
82 if (declaredLength == methodLength)
85 HashtableOfObject table = new HashtableOfObject(declaredLength);
86 for (int i = 0; i < declaredLength; i++) {
87 char[] internalName = ((MemberValuePairBinding) pairs[i]).internalName();
88 if (internalName == null) continue;
89 table.put(internalName, pairs[i]);
92 // handle case of more methods than declared members
93 IMemberValuePairBinding[] allPairs = new IMemberValuePairBinding[methodLength];
94 for (int i = 0; i < methodLength; i++) {
95 Object pair = table.get(methods[i].selector);
96 allPairs[i] = pair == null ? new DefaultValuePairBinding(methods[i], this.bindingResolver) : (IMemberValuePairBinding) pair;
101 public IJavaElement getJavaElement() {
102 if (!(this.bindingResolver instanceof DefaultBindingResolver)) return null;
103 ASTNode node = (ASTNode) ((DefaultBindingResolver) this.bindingResolver).bindingsToAstNodes.get(this);
104 if (!(node instanceof Annotation)) return null;
105 ASTNode parent = node.getParent();
106 IJavaElement parentElement = null;
107 switch (parent.getNodeType()) {
108 case ASTNode.PACKAGE_DECLARATION:
109 IJavaElement cu = ((CompilationUnit) parent.getParent()).getJavaElement();
110 if (cu instanceof ICompilationUnit) {
111 String pkgName = ((PackageDeclaration) parent).getName().getFullyQualifiedName();
112 parentElement = ((ICompilationUnit) cu).getPackageDeclaration(pkgName);
115 case ASTNode.TYPE_DECLARATION:
116 parentElement = ((TypeDeclaration) parent).resolveBinding().getJavaElement();
118 case ASTNode.FIELD_DECLARATION:
119 VariableDeclarationFragment fragment = (VariableDeclarationFragment) ((FieldDeclaration) parent).fragments().get(0);
120 parentElement = fragment.resolveBinding().getJavaElement();
122 case ASTNode.METHOD_DECLARATION:
123 parentElement = ((MethodDeclaration) parent).resolveBinding().getJavaElement();
125 case ASTNode.VARIABLE_DECLARATION_STATEMENT:
126 fragment = (VariableDeclarationFragment) ((VariableDeclarationStatement) parent).fragments().get(0);
127 parentElement = fragment.resolveBinding().getJavaElement();
132 if (! (parentElement instanceof IAnnotatable)) return null;
133 return ((IAnnotatable) parentElement).getAnnotation(getName());
136 public String getKey() {
137 if (this.key == null) {
138 String recipientKey = getRecipientKey();
139 this.key = new String(this.binding.computeUniqueKey(recipientKey.toCharArray()));
144 private String getRecipientKey() {
145 if (!(this.bindingResolver instanceof DefaultBindingResolver)) return ""; //$NON-NLS-1$
146 DefaultBindingResolver resolver = (DefaultBindingResolver) this.bindingResolver;
147 ASTNode node = (ASTNode) resolver.bindingsToAstNodes.get(this);
149 // Can happen if annotation bindings have been resolved before having parsed the declaration
150 return ""; //$NON-NLS-1$
152 ASTNode recipient = node.getParent();
153 switch (recipient.getNodeType()) {
154 case ASTNode.PACKAGE_DECLARATION:
155 String pkgName = ((PackageDeclaration) recipient).getName().getFullyQualifiedName();
156 return pkgName.replace('.', '/');
157 case ASTNode.TYPE_DECLARATION:
158 return ((TypeDeclaration) recipient).resolveBinding().getKey();
159 case ASTNode.FIELD_DECLARATION:
160 VariableDeclarationFragment fragment = (VariableDeclarationFragment) ((FieldDeclaration) recipient).fragments().get(0);
161 return fragment.resolveBinding().getKey();
162 case ASTNode.METHOD_DECLARATION:
163 return ((MethodDeclaration) recipient).resolveBinding().getKey();
164 case ASTNode.VARIABLE_DECLARATION_STATEMENT:
165 fragment = (VariableDeclarationFragment) ((VariableDeclarationStatement) recipient).fragments().get(0);
166 return fragment.resolveBinding().getKey();
168 return ""; //$NON-NLS-1$
172 public int getKind() {
173 return IBinding.ANNOTATION;
176 public int getModifiers() {
177 return Modifier.NONE;
180 public String getName() {
181 ITypeBinding annotationType = getAnnotationType();
182 if (annotationType == null) {
183 return new String(this.binding.getAnnotationType().sourceName());
185 return annotationType.getName();
189 public boolean isDeprecated() {
190 ReferenceBinding typeBinding = this.binding.getAnnotationType();
191 if (typeBinding == null) return false;
192 return typeBinding.isDeprecated();
195 public boolean isEqualTo(IBinding otherBinding) {
196 if (this == otherBinding)
198 if (otherBinding.getKind() != IBinding.ANNOTATION)
200 IAnnotationBinding other = (IAnnotationBinding) otherBinding;
201 if (!getAnnotationType().isEqualTo(other.getAnnotationType()))
203 IMemberValuePairBinding[] memberValuePairs = getDeclaredMemberValuePairs();
204 IMemberValuePairBinding[] otherMemberValuePairs = other.getDeclaredMemberValuePairs();
205 if (memberValuePairs.length != otherMemberValuePairs.length)
207 for (int i = 0, length = memberValuePairs.length; i < length; i++) {
208 if (!memberValuePairs[i].isEqualTo(otherMemberValuePairs[i]))
216 * @see org.eclipse.jdt.core.dom.IBinding#isRecovered()
218 public boolean isRecovered() {
219 ReferenceBinding annotationType = binding.getAnnotationType();
220 return annotationType == null || (annotationType.tagBits & TagBits.HasMissingType) != 0; }
222 public boolean isSynthetic() {
226 public String toString() {
227 ITypeBinding type = getAnnotationType();
228 final StringBuffer buffer = new StringBuffer();
231 buffer.append(type.getName());
233 IMemberValuePairBinding[] pairs = getDeclaredMemberValuePairs();
234 for (int i = 0, len = pairs.length; i < len; i++) {
236 buffer.append(", "); //$NON-NLS-1$
237 buffer.append(pairs[i].toString());
240 return buffer.toString();