1 /*******************************************************************************
2 * Copyright (c) 2000, 2008 IBM Corporation and others.
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 * IBM Corporation - initial API and implementation
10 *******************************************************************************/
11 package net.sourceforge.phpdt.internal.compiler.lookup;
13 import net.sourceforge.phpdt.internal.compiler.ast.Annotation;
16 * Represents JSR 175 Annotation instances in the type-system.
18 public class AnnotationBinding {
19 // do not access directly - use getters instead (UnresolvedAnnotationBinding
20 // resolves types for type and pair contents just in time)
21 ReferenceBinding type;
22 ElementValuePair[] pairs;
25 * Add the standard annotations encoded in the tag bits to the recorded annotations.
27 * @param recordedAnnotations existing annotations already created
28 * @param annotationTagBits
30 * @return the combined list of annotations
32 public static AnnotationBinding[] addStandardAnnotations(AnnotationBinding[] recordedAnnotations, long annotationTagBits, LookupEnvironment env) {
33 // NOTE: expect annotations to be requested just once so there is no need to store the standard annotations
34 // and all of the standard annotations created by this method are fully resolved since the sender is expected to use them immediately
36 if ((annotationTagBits & TagBits.AnnotationTargetMASK) != 0)
38 if ((annotationTagBits & TagBits.AnnotationRetentionMASK) != 0)
40 if ((annotationTagBits & TagBits.AnnotationDeprecated) != 0)
42 if ((annotationTagBits & TagBits.AnnotationDocumented) != 0)
44 if ((annotationTagBits & TagBits.AnnotationInherited) != 0)
46 if ((annotationTagBits & TagBits.AnnotationOverride) != 0)
48 if ((annotationTagBits & TagBits.AnnotationSuppressWarnings) != 0)
51 return recordedAnnotations;
53 int index = recordedAnnotations.length;
54 AnnotationBinding[] result = new AnnotationBinding[index + count];
55 System.arraycopy(recordedAnnotations, 0, result, 0, index);
56 if ((annotationTagBits & TagBits.AnnotationTargetMASK) != 0)
57 result[index++] = buildTargetAnnotation(annotationTagBits, env);
58 if ((annotationTagBits & TagBits.AnnotationRetentionMASK) != 0)
59 result[index++] = buildRetentionAnnotation(annotationTagBits, env);
60 if ((annotationTagBits & TagBits.AnnotationDeprecated) != 0)
61 result[index++] = buildMarkerAnnotation(TypeConstants.JAVA_LANG_DEPRECATED, env);
62 if ((annotationTagBits & TagBits.AnnotationDocumented) != 0)
63 result[index++] = buildMarkerAnnotation(TypeConstants.JAVA_LANG_ANNOTATION_DOCUMENTED, env);
64 if ((annotationTagBits & TagBits.AnnotationInherited) != 0)
65 result[index++] = buildMarkerAnnotation(TypeConstants.JAVA_LANG_ANNOTATION_INHERITED, env);
66 if ((annotationTagBits & TagBits.AnnotationOverride) != 0)
67 result[index++] = buildMarkerAnnotation(TypeConstants.JAVA_LANG_OVERRIDE, env);
68 if ((annotationTagBits & TagBits.AnnotationSuppressWarnings) != 0)
69 result[index++] = buildMarkerAnnotation(TypeConstants.JAVA_LANG_SUPPRESSWARNINGS, env);
73 private static AnnotationBinding buildMarkerAnnotation(char[][] compoundName, LookupEnvironment env) {
74 ReferenceBinding type = env.getResolvedType(compoundName, null);
75 return env.createAnnotation(type, Binding.NO_ELEMENT_VALUE_PAIRS);
78 private static AnnotationBinding buildRetentionAnnotation(long bits, LookupEnvironment env) {
79 ReferenceBinding retentionPolicy =
80 env.getResolvedType(TypeConstants.JAVA_LANG_ANNOTATION_RETENTIONPOLICY,
83 if ((bits & TagBits.AnnotationRuntimeRetention) != 0)
84 value = retentionPolicy.getField(TypeConstants.UPPER_RUNTIME, true);
85 else if ((bits & TagBits.AnnotationClassRetention) != 0)
86 value = retentionPolicy.getField(TypeConstants.UPPER_CLASS, true);
87 else if ((bits & TagBits.AnnotationSourceRetention) != 0)
88 value = retentionPolicy.getField(TypeConstants.UPPER_SOURCE, true);
89 return env.createAnnotation(
90 env.getResolvedType(TypeConstants.JAVA_LANG_ANNOTATION_RETENTION, null),
91 new ElementValuePair[] {
92 new ElementValuePair(TypeConstants.VALUE, value, null)
96 private static AnnotationBinding buildTargetAnnotation(long bits, LookupEnvironment env) {
97 ReferenceBinding target = env.getResolvedType(TypeConstants.JAVA_LANG_ANNOTATION_TARGET, null);
98 if ((bits & TagBits.AnnotationTarget) != 0)
99 return new AnnotationBinding(target, Binding.NO_ELEMENT_VALUE_PAIRS);
102 if ((bits & TagBits.AnnotationForAnnotationType) != 0)
104 if ((bits & TagBits.AnnotationForConstructor) != 0)
106 if ((bits & TagBits.AnnotationForField) != 0)
108 if ((bits & TagBits.AnnotationForLocalVariable) != 0)
110 if ((bits & TagBits.AnnotationForMethod) != 0)
112 if ((bits & TagBits.AnnotationForPackage) != 0)
114 if ((bits & TagBits.AnnotationForParameter) != 0)
116 if ((bits & TagBits.AnnotationForType) != 0)
118 Object[] value = new Object[arraysize];
120 ReferenceBinding elementType = env.getResolvedType(TypeConstants.JAVA_LANG_ANNOTATION_ELEMENTTYPE, null);
122 if ((bits & TagBits.AnnotationForAnnotationType) != 0)
123 value[index++] = elementType.getField(TypeConstants.UPPER_ANNOTATION_TYPE, true);
124 if ((bits & TagBits.AnnotationForConstructor) != 0)
125 value[index++] = elementType.getField(TypeConstants.UPPER_CONSTRUCTOR, true);
126 if ((bits & TagBits.AnnotationForField) != 0)
127 value[index++] = elementType.getField(TypeConstants.UPPER_FIELD, true);
128 if ((bits & TagBits.AnnotationForLocalVariable) != 0)
129 value[index++] = elementType.getField(TypeConstants.UPPER_LOCAL_VARIABLE, true);
130 if ((bits & TagBits.AnnotationForMethod) != 0)
131 value[index++] = elementType.getField(TypeConstants.UPPER_METHOD, true);
132 if ((bits & TagBits.AnnotationForPackage) != 0)
133 value[index++] = elementType.getField(TypeConstants.UPPER_PACKAGE, true);
134 if ((bits & TagBits.AnnotationForParameter) != 0)
135 value[index++] = elementType.getField(TypeConstants.UPPER_PARAMETER, true);
136 if ((bits & TagBits.AnnotationForType) != 0)
137 value[index++] = elementType.getField(TypeConstants.TYPE, true);
139 return env.createAnnotation(
141 new ElementValuePair[] {
142 new ElementValuePair(TypeConstants.VALUE, value, null)
146 AnnotationBinding(ReferenceBinding type, ElementValuePair[] pairs) {
151 AnnotationBinding(Annotation astAnnotation) {
152 this((ReferenceBinding) astAnnotation.resolvedType, astAnnotation.computeElementValuePairs());
156 * Computes a key that uniquely identifies this binding, using the given recipient's unique key.
157 * recipientKey @ typeKey
158 * @MyAnnot void bar() --> Lp/X;.bar()V@Lp/MyAnnot;
160 public char[] computeUniqueKey(char[] recipientKey) {
161 char[] typeKey = this.type.computeUniqueKey(false);
162 int recipientKeyLength = recipientKey.length;
163 char[] uniqueKey = new char[recipientKeyLength+1+typeKey.length];
164 System.arraycopy(recipientKey, 0, uniqueKey, 0, recipientKeyLength);
165 uniqueKey[recipientKeyLength] = '@';
166 System.arraycopy(typeKey, 0, uniqueKey, recipientKeyLength+1, typeKey.length);
170 public ReferenceBinding getAnnotationType() {
174 public ElementValuePair[] getElementValuePairs() {
178 public static void setMethodBindings(ReferenceBinding type, ElementValuePair[] pairs) {
179 // set the method bindings of each element value pair
180 for (int i = pairs.length; --i >= 0;) {
181 ElementValuePair pair = pairs[i];
182 MethodBinding[] methods = type.getMethods(pair.getName());
183 // there should be exactly one since the type is an annotation type.
184 if (methods != null && methods.length == 1)
185 pair.setMethodBinding(methods[0]);
189 public String toString() {
190 StringBuffer buffer = new StringBuffer(5);
191 buffer.append('@').append(this.type.sourceName);
192 if (this.pairs != null && this.pairs.length > 0) {
193 buffer.append("{ "); //$NON-NLS-1$
194 for (int i = 0, max = this.pairs.length; i < max; i++) {
195 if (i > 0) buffer.append(", "); //$NON-NLS-1$
196 buffer.append(this.pairs[i]);
200 return buffer.toString();