001: /*******************************************************************************
002: * Copyright (c) 2000, 2007 IBM Corporation and others.
003: * All rights reserved. This program and the accompanying materials
004: * are made available under the terms of the Eclipse Public License v1.0
005: * which accompanies this distribution, and is available at
006: * http://www.eclipse.org/legal/epl-v10.html
007: *
008: * Contributors:
009: * IBM Corporation - initial API and implementation
010: *******************************************************************************/package org.eclipse.jdt.internal.compiler.lookup;
011:
012: import org.eclipse.jdt.internal.compiler.ast.Annotation;
013:
014: /**
015: * Represents JSR 175 Annotation instances in the type-system.
016: */
017: public class AnnotationBinding {
018: // do not access directly - use getters instead (UnresolvedAnnotationBinding
019: // resolves types for type and pair contents just in time)
020: ReferenceBinding type;
021: ElementValuePair[] pairs;
022:
023: /**
024: * Add the standard annotations encoded in the tag bits to the recorded annotations.
025: *
026: * @param recordedAnnotations existing annotations already created
027: * @param annotationTagBits
028: * @param env
029: * @return the combined list of annotations
030: */
031: public static AnnotationBinding[] addStandardAnnotations(
032: AnnotationBinding[] recordedAnnotations,
033: long annotationTagBits, LookupEnvironment env) {
034: // NOTE: expect annotations to be requested just once so there is no need to store the standard annotations
035: // and all of the standard annotations created by this method are fully resolved since the sender is expected to use them immediately
036: int count = 0;
037: if ((annotationTagBits & TagBits.AnnotationTargetMASK) != 0)
038: count++;
039: if ((annotationTagBits & TagBits.AnnotationRetentionMASK) != 0)
040: count++;
041: if ((annotationTagBits & TagBits.AnnotationDeprecated) != 0)
042: count++;
043: if ((annotationTagBits & TagBits.AnnotationDocumented) != 0)
044: count++;
045: if ((annotationTagBits & TagBits.AnnotationInherited) != 0)
046: count++;
047: if ((annotationTagBits & TagBits.AnnotationOverride) != 0)
048: count++;
049: if ((annotationTagBits & TagBits.AnnotationSuppressWarnings) != 0)
050: count++;
051: if (count == 0)
052: return recordedAnnotations;
053:
054: int index = recordedAnnotations.length;
055: AnnotationBinding[] result = new AnnotationBinding[index
056: + count];
057: System.arraycopy(recordedAnnotations, 0, result, 0, index);
058: if ((annotationTagBits & TagBits.AnnotationTargetMASK) != 0)
059: result[index++] = buildTargetAnnotation(annotationTagBits,
060: env);
061: if ((annotationTagBits & TagBits.AnnotationRetentionMASK) != 0)
062: result[index++] = buildRetentionAnnotation(
063: annotationTagBits, env);
064: if ((annotationTagBits & TagBits.AnnotationDeprecated) != 0)
065: result[index++] = buildMarkerAnnotation(
066: TypeConstants.JAVA_LANG_DEPRECATED, env);
067: if ((annotationTagBits & TagBits.AnnotationDocumented) != 0)
068: result[index++] = buildMarkerAnnotation(
069: TypeConstants.JAVA_LANG_ANNOTATION_DOCUMENTED, env);
070: if ((annotationTagBits & TagBits.AnnotationInherited) != 0)
071: result[index++] = buildMarkerAnnotation(
072: TypeConstants.JAVA_LANG_ANNOTATION_INHERITED, env);
073: if ((annotationTagBits & TagBits.AnnotationOverride) != 0)
074: result[index++] = buildMarkerAnnotation(
075: TypeConstants.JAVA_LANG_OVERRIDE, env);
076: if ((annotationTagBits & TagBits.AnnotationSuppressWarnings) != 0)
077: result[index++] = buildMarkerAnnotation(
078: TypeConstants.JAVA_LANG_SUPPRESSWARNINGS, env);
079: return result;
080: }
081:
082: private static AnnotationBinding buildMarkerAnnotation(
083: char[][] compoundName, LookupEnvironment env) {
084: ReferenceBinding type = env.getResolvedType(compoundName, null);
085: return env.createAnnotation(type,
086: Binding.NO_ELEMENT_VALUE_PAIRS);
087: }
088:
089: private static AnnotationBinding buildRetentionAnnotation(
090: long bits, LookupEnvironment env) {
091: ReferenceBinding retentionPolicy = env.getResolvedType(
092: TypeConstants.JAVA_LANG_ANNOTATION_RETENTIONPOLICY,
093: null);
094: Object value = null;
095: if ((bits & TagBits.AnnotationRuntimeRetention) != 0)
096: value = retentionPolicy.getField(
097: TypeConstants.UPPER_RUNTIME, true);
098: else if ((bits & TagBits.AnnotationClassRetention) != 0)
099: value = retentionPolicy.getField(TypeConstants.UPPER_CLASS,
100: true);
101: else if ((bits & TagBits.AnnotationSourceRetention) != 0)
102: value = retentionPolicy.getField(
103: TypeConstants.UPPER_SOURCE, true);
104: return env.createAnnotation(env.getResolvedType(
105: TypeConstants.JAVA_LANG_ANNOTATION_RETENTION, null),
106: new ElementValuePair[] { new ElementValuePair(
107: TypeConstants.VALUE, value, null) });
108: }
109:
110: private static AnnotationBinding buildTargetAnnotation(long bits,
111: LookupEnvironment env) {
112: ReferenceBinding target = env.getResolvedType(
113: TypeConstants.JAVA_LANG_ANNOTATION_TARGET, null);
114: if ((bits & TagBits.AnnotationTarget) != 0)
115: return new AnnotationBinding(target,
116: Binding.NO_ELEMENT_VALUE_PAIRS);
117:
118: int arraysize = 0;
119: if ((bits & TagBits.AnnotationForAnnotationType) != 0)
120: arraysize++;
121: if ((bits & TagBits.AnnotationForConstructor) != 0)
122: arraysize++;
123: if ((bits & TagBits.AnnotationForField) != 0)
124: arraysize++;
125: if ((bits & TagBits.AnnotationForLocalVariable) != 0)
126: arraysize++;
127: if ((bits & TagBits.AnnotationForMethod) != 0)
128: arraysize++;
129: if ((bits & TagBits.AnnotationForPackage) != 0)
130: arraysize++;
131: if ((bits & TagBits.AnnotationForParameter) != 0)
132: arraysize++;
133: if ((bits & TagBits.AnnotationForType) != 0)
134: arraysize++;
135: Object[] value = new Object[arraysize];
136: if (arraysize > 0) {
137: ReferenceBinding elementType = env.getResolvedType(
138: TypeConstants.JAVA_LANG_ANNOTATION_ELEMENTTYPE,
139: null);
140: int index = 0;
141: if ((bits & TagBits.AnnotationForAnnotationType) != 0)
142: value[index++] = elementType.getField(
143: TypeConstants.UPPER_ANNOTATION_TYPE, true);
144: if ((bits & TagBits.AnnotationForConstructor) != 0)
145: value[index++] = elementType.getField(
146: TypeConstants.UPPER_CONSTRUCTOR, true);
147: if ((bits & TagBits.AnnotationForField) != 0)
148: value[index++] = elementType.getField(
149: TypeConstants.UPPER_FIELD, true);
150: if ((bits & TagBits.AnnotationForLocalVariable) != 0)
151: value[index++] = elementType.getField(
152: TypeConstants.UPPER_LOCAL_VARIABLE, true);
153: if ((bits & TagBits.AnnotationForMethod) != 0)
154: value[index++] = elementType.getField(
155: TypeConstants.UPPER_METHOD, true);
156: if ((bits & TagBits.AnnotationForPackage) != 0)
157: value[index++] = elementType.getField(
158: TypeConstants.UPPER_PACKAGE, true);
159: if ((bits & TagBits.AnnotationForParameter) != 0)
160: value[index++] = elementType.getField(
161: TypeConstants.UPPER_PARAMETER, true);
162: if ((bits & TagBits.AnnotationForType) != 0)
163: value[index++] = elementType.getField(
164: TypeConstants.TYPE, true);
165: }
166: return env.createAnnotation(target,
167: new ElementValuePair[] { new ElementValuePair(
168: TypeConstants.VALUE, value, null) });
169: }
170:
171: AnnotationBinding(ReferenceBinding type, ElementValuePair[] pairs) {
172: this .type = type;
173: this .pairs = pairs;
174: }
175:
176: AnnotationBinding(Annotation astAnnotation) {
177: this ((ReferenceBinding) astAnnotation.resolvedType,
178: astAnnotation.computeElementValuePairs());
179: }
180:
181: public ReferenceBinding getAnnotationType() {
182: return this .type;
183: }
184:
185: public ElementValuePair[] getElementValuePairs() {
186: return this .pairs;
187: }
188:
189: public static void setMethodBindings(ReferenceBinding type,
190: ElementValuePair[] pairs) {
191: // set the method bindings of each element value pair
192: for (int i = pairs.length; --i >= 0;) {
193: ElementValuePair pair = pairs[i];
194: MethodBinding[] methods = type.getMethods(pair.getName());
195: // there should be exactly one since the type is an annotation type.
196: if (methods != null && methods.length == 1)
197: pair.setMethodBinding(methods[0]);
198: }
199: }
200: }
|