package org.eclipse.jdt.internal.compiler.classfmt;
import java.util.Arrays;
import org.eclipse.jdt.internal.compiler.codegen.AnnotationTargetTypeConstants;
import org.eclipse.jdt.internal.compiler.env.IBinaryAnnotation;
import org.eclipse.jdt.internal.compiler.env.IBinaryTypeAnnotation;
public class TypeAnnotationInfo extends ClassFileStruct implements IBinaryTypeAnnotation {
private AnnotationInfo annotation;
private int targetType = 0;
private int info;
private int info2;
private int[] typePath;
int readOffset = 0;
TypeAnnotationInfo(byte[] classFileBytes, int[] contantPoolOffsets, int offset) {
super(classFileBytes, contantPoolOffsets, offset);
}
TypeAnnotationInfo(byte[] classFileBytes, int[] contantPoolOffsets, int offset, boolean runtimeVisible, boolean populate) {
this(classFileBytes, contantPoolOffsets, offset);
this.readOffset = 0;
this.targetType = u1At(0);
switch (this.targetType) {
case AnnotationTargetTypeConstants.CLASS_TYPE_PARAMETER:
case AnnotationTargetTypeConstants.METHOD_TYPE_PARAMETER:
this.info = u1At(1);
this.readOffset += 2;
break;
case AnnotationTargetTypeConstants.CLASS_EXTENDS:
this.info = u2At(1);
this.readOffset += 3;
break;
case AnnotationTargetTypeConstants.CLASS_TYPE_PARAMETER_BOUND:
case AnnotationTargetTypeConstants.METHOD_TYPE_PARAMETER_BOUND:
this.info = u1At(1);
this.info2 = u1At(2);
this.readOffset += 3;
break;
case AnnotationTargetTypeConstants.FIELD:
case AnnotationTargetTypeConstants.METHOD_RETURN:
case AnnotationTargetTypeConstants.METHOD_RECEIVER:
this.readOffset ++;
break;
case AnnotationTargetTypeConstants.METHOD_FORMAL_PARAMETER :
this.info = u1At(1);
this.readOffset += 2;
break;
case AnnotationTargetTypeConstants.THROWS :
this.info = u2At(1);
this.readOffset += 3;
break;
default:
throw new IllegalStateException("Target type not handled "+this.targetType);
}
int typePathLength = u1At(this.readOffset);
this.readOffset ++;
if (typePathLength == 0) {
this.typePath = NO_TYPE_PATH;
} else {
this.typePath = new int[typePathLength*2];
int index = 0;
for (int i = 0; i < typePathLength; i++) {
this.typePath[index++] = u1At(this.readOffset++);
this.typePath[index++] = u1At(this.readOffset++);
}
}
this.annotation = new AnnotationInfo(classFileBytes, this.constantPoolOffsets, this.structOffset + this.readOffset, runtimeVisible, populate);
this.readOffset += this.annotation.readOffset;
}
@Override
public IBinaryAnnotation getAnnotation() {
return this.annotation;
}
protected void initialize() {
this.annotation.initialize();
}
@Override
protected void reset() {
this.annotation.reset();
super.reset();
}
@Override
public String toString() {
return BinaryTypeFormatter.annotationToString(this);
}
@Override
public int getTargetType() {
return this.targetType;
}
@Override
public int getSupertypeIndex() {
return this.info;
}
@Override
public int getTypeParameterIndex() {
return this.info;
}
@Override
public int getBoundIndex() {
return this.info2;
}
@Override
public int getMethodFormalParameterIndex() {
return this.info;
}
@Override
public int getThrowsTypeIndex() {
return this.info;
}
@Override
public int[] getTypePath() {
return this.typePath;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + this.targetType;
result = prime * result + this.info;
result = prime * result + this.info2;
if (this.typePath != null) {
for (int i = 0, max = this.typePath.length; i < max; i++) {
result = prime * result + this.typePath[i];
}
}
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
TypeAnnotationInfo other = (TypeAnnotationInfo) obj;
if (this.targetType != other.targetType) {
return false;
}
if (this.info != other.info) {
return false;
}
if (this.info2 != other.info2) {
return false;
}
if (!Arrays.equals(this.typePath, other.typePath)) {
return false;
}
return this.annotation.equals(other.annotation);
}
}