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();