blob: 1a598744fc8fdc2ec0f1ec75a0e4b9e6dbc8a32c [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2005, 2016 BEA Systems, Inc.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* tyeung@bea.com - initial API and implementation
*******************************************************************************/
package org.eclipse.jdt.internal.compiler.classfmt;
import org.eclipse.jdt.core.compiler.CharOperation;
import org.eclipse.jdt.internal.compiler.codegen.AttributeNamesConstants;
public class AnnotationMethodInfo extends MethodInfo {
protected Object defaultValue = null;
public static MethodInfo createAnnotationMethod(byte classFileBytes[], int offsets[], int offset) {
MethodInfo methodInfo = new MethodInfo(classFileBytes, offsets, offset);
int attributesCount = methodInfo.u2At(6);
int readOffset = 8;
AnnotationInfo[] annotations = null;
Object defaultValue = null;
for (int i = 0; i < attributesCount; i++) {
// check the name of each attribute
int utf8Offset = methodInfo.constantPoolOffsets[methodInfo.u2At(readOffset)] - methodInfo.structOffset;
char[] attributeName = methodInfo.utf8At(utf8Offset + 3, methodInfo.u2At(utf8Offset + 1));
if (attributeName.length > 0) {
switch(attributeName[0]) {
case 'A':
if (CharOperation.equals(attributeName, AttributeNamesConstants.AnnotationDefaultName)) {
// readOffset + 6 so the offset is at the start of the 'member_value' entry
// u2 attribute_name_index + u4 attribute_length = + 6
AnnotationInfo info =
new AnnotationInfo(methodInfo.reference, methodInfo.constantPoolOffsets, readOffset + 6 + methodInfo.structOffset);
defaultValue = info.decodeDefaultValue();
}
break;
case 'S' :
if (CharOperation.equals(AttributeNamesConstants.SignatureName, attributeName))
methodInfo.signatureUtf8Offset = methodInfo.constantPoolOffsets[methodInfo.u2At(readOffset + 6)] - methodInfo.structOffset;
break;
case 'R' :
AnnotationInfo[] methodAnnotations = null;
if (CharOperation.equals(attributeName, AttributeNamesConstants.RuntimeVisibleAnnotationsName)) {
methodAnnotations = decodeMethodAnnotations(readOffset, true, methodInfo);
} else if (CharOperation.equals(attributeName, AttributeNamesConstants.RuntimeInvisibleAnnotationsName)) {
methodAnnotations = decodeMethodAnnotations(readOffset, false, methodInfo);
}
if (methodAnnotations != null) {
if (annotations == null) {
annotations = methodAnnotations;
} else {
int length = annotations.length;
AnnotationInfo[] newAnnotations = new AnnotationInfo[length + methodAnnotations.length];
System.arraycopy(annotations, 0, newAnnotations, 0, length);
System.arraycopy(methodAnnotations, 0, newAnnotations, length, methodAnnotations.length);
annotations = newAnnotations;
}
}
break;
}
}
readOffset += (6 + methodInfo.u4At(readOffset + 2));
}
methodInfo.attributeBytes = readOffset;
if (defaultValue != null) {
if (annotations != null) {
return new AnnotationMethodInfoWithAnnotations(methodInfo, defaultValue, annotations);
}
return new AnnotationMethodInfo(methodInfo, defaultValue);
}
if (annotations != null)
return new MethodInfoWithAnnotations(methodInfo, annotations);
return methodInfo;
}
AnnotationMethodInfo(MethodInfo methodInfo, Object defaultValue) {
super(methodInfo.reference, methodInfo.constantPoolOffsets, methodInfo.structOffset);
this.defaultValue = defaultValue;
this.accessFlags = methodInfo.accessFlags;
this.attributeBytes = methodInfo.attributeBytes;
this.descriptor = methodInfo.descriptor;
this.exceptionNames = methodInfo.exceptionNames;
this.name = methodInfo.name;
this.signature = methodInfo.signature;
this.signatureUtf8Offset = methodInfo.signatureUtf8Offset;
this.tagBits = methodInfo.tagBits;
}
public Object getDefaultValue() {
return this.defaultValue;
}
}