org.aspectj.apache.bcel.classfile.annotation.TypeAnnotationGen Maven / Gradle / Ivy
/* *******************************************************************
* Copyright (c) 2013 VMware
*
* 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:
* Andy Clement initial implementation
* ******************************************************************/
package org.aspectj.apache.bcel.classfile.annotation;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import org.aspectj.apache.bcel.classfile.ConstantPool;
public class TypeAnnotationGen {
public static final TypeAnnotationGen[] NO_TYPE_ANNOTATIONS = new TypeAnnotationGen[0];
public static final int[] NO_TYPE_PATH = new int[0];
private ConstantPool cpool;
private TypeAnnotationGen(ConstantPool cpool) {
this.cpool = cpool;
}
private int targetType;
private int[] typePath;
private AnnotationGen annotation;
private int info; // meaning varies depending on target type
private int info2; // meaning varies depending on target type
private int[] localVarTarget;
// target type constants
public final static int CLASS_TYPE_PARAMETER = 0x00;
public final static int METHOD_TYPE_PARAMETER = 0x01;
public final static int CLASS_EXTENDS = 0x10;
public final static int CLASS_TYPE_PARAMETER_BOUND = 0x11;
public final static int METHOD_TYPE_PARAMETER_BOUND = 0x12;
public final static int FIELD = 0x13;
public final static int METHOD_RETURN = 0x14;
public final static int METHOD_RECEIVER = 0x15;
public final static int METHOD_FORMAL_PARAMETER = 0x16;
public final static int THROWS = 0x17;
public final static int LOCAL_VARIABLE = 0x40;
public final static int RESOURCE_VARIABLE = 0x41;
public final static int EXCEPTION_PARAMETER = 0x42;
public final static int INSTANCEOF = 0x43;
public final static int NEW = 0x44;
public final static int CONSTRUCTOR_REFERENCE = 0x45;
public final static int METHOD_REFERENCE = 0x46;
public final static int CAST = 0x47;
public final static int CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT = 0x48;
public final static int METHOD_INVOCATION_TYPE_ARGUMENT = 0x49;
public final static int CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT = 0x4A;
public final static int METHOD_REFERENCE_TYPE_ARGUMENT = 0x4B;
// type path entry kinds
public final static int TYPE_PATH_ENTRY_KIND_ARRAY = 0;
public final static int TYPE_PATH_ENTRY_KIND_INNER_TYPE = 1;
public final static int TYPE_PATH_ENTRY_KIND_WILDCARD = 2;
public final static int TYPE_PATH_ENTRY_KIND_TYPE_ARGUMENT = 3;
public static TypeAnnotationGen read(DataInputStream dis, ConstantPool cpool, boolean isVisible) throws IOException {
TypeAnnotationGen typeAnno = new TypeAnnotationGen(cpool);
typeAnno.targetType = dis.readUnsignedByte();
// read target_info
switch (typeAnno.targetType) {
case CLASS_TYPE_PARAMETER:
typeAnno.info = dis.readUnsignedByte();// type_parameter_index
break;
case METHOD_TYPE_PARAMETER:
typeAnno.info = dis.readUnsignedByte(); // type_parameter_index
break;
case CLASS_EXTENDS:
int superTypeIndex = dis.readUnsignedShort();
if (superTypeIndex == 65535) {
typeAnno.info = -1;
} else {
typeAnno.info = superTypeIndex;
}
break;
case CLASS_TYPE_PARAMETER_BOUND:
case METHOD_TYPE_PARAMETER_BOUND:
typeAnno.info = dis.readUnsignedByte(); // type_parameter_index
typeAnno.info2 = dis.readUnsignedByte(); // bound_index;
break;
case FIELD:
case METHOD_RETURN:
case METHOD_RECEIVER:
break;
case METHOD_FORMAL_PARAMETER:
typeAnno.info = dis.readUnsignedByte(); // method_formal_parameter_index
break;
case THROWS:
typeAnno.info = dis.readUnsignedShort(); // throws_type_index
break;
case LOCAL_VARIABLE:
case RESOURCE_VARIABLE:
typeAnno.localVarTarget = readLocalVarTarget(dis);
break;
case EXCEPTION_PARAMETER:
// TODO should be a SHORT according to the spec but byte for now because of javac (b90)
typeAnno.info = dis.readUnsignedByte(); // exception_table_index
break;
case INSTANCEOF:
case NEW:
case CONSTRUCTOR_REFERENCE:
case METHOD_REFERENCE:
typeAnno.info = dis.readUnsignedShort(); // offset
break;
case CAST:
case CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT:
case METHOD_INVOCATION_TYPE_ARGUMENT:
case CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT:
case METHOD_REFERENCE_TYPE_ARGUMENT:
typeAnno.info = dis.readUnsignedShort(); // offset
typeAnno.info2 = dis.readUnsignedByte(); // type_argument_index
break;
default:
throw new IllegalStateException("nyi "+typeAnno.targetType);
}
int typepathlength = dis.readUnsignedByte();
if (typepathlength==0) {
typeAnno.typePath = NO_TYPE_PATH;
} else {
typeAnno.typePath = new int[typepathlength*2];
for (int i=0, max = typepathlength*2; i copyValues(List in, ConstantPool cpool, boolean copyPoolEntries) {
// List out = new ArrayList();
// for (NameValuePair nvp : in) {
// out.add(new NameValuePair(nvp, cpool, copyPoolEntries));
// }
// return out;
// }
//
//
// /**
// * Retrieve an immutable version of this AnnotationGen
// */
// public TypeAnnotationGen(ObjectType type, List pairs, boolean runtimeVisible, ConstantPool cpool) {
// this.cpool = cpool;
// if (type != null) {
// this.typeIndex = cpool.addUtf8(type.getSignature()); // Only null for funky *temporary* FakeAnnotation objects
// }
// this.pairs = pairs;
// isRuntimeVisible = runtimeVisible;
// }
//
public int[] getTypePath() {
return typePath;
}
public String getTypePathString() {
return toTypePathString(typePath);
}
public static String toTypePathString(int[] typepath) {
StringBuilder sb = new StringBuilder();
int count = 0;
sb.append("[");
while (count < typepath.length) {
if (count>0) sb.append(",");
switch (typepath[count++]) {
case TYPE_PATH_ENTRY_KIND_ARRAY:
sb.append("ARRAY");
count++;
break;
case TYPE_PATH_ENTRY_KIND_INNER_TYPE:
sb.append("INNER_TYPE");
count++;
break;
case TYPE_PATH_ENTRY_KIND_WILDCARD:
sb.append("WILDCARD");
count++;
break;
case TYPE_PATH_ENTRY_KIND_TYPE_ARGUMENT:
sb.append("TYPE_ARGUMENT(").append(typepath[count++]).append(")");
break;
}
}
sb.append("]");
return sb.toString();
}
}