下面列出了怎么用org.objectweb.asm.AnnotationVisitor的API类实例代码及写法,或者点击链接到github查看源代码。
private void visitAnnotationArrayElement(final Expression expr, final int arrayElementType, final AnnotationVisitor av) {
switch (arrayElementType) {
case 1:
AnnotationNode atAttr = (AnnotationNode) ((AnnotationConstantExpression) expr).getValue();
AnnotationVisitor av2 = av.visitAnnotation(null, BytecodeHelper.getTypeDescription(atAttr.getClassNode()));
visitAnnotationAttributes(atAttr, av2);
av2.visitEnd();
break;
case 2:
av.visit(null, ((ConstantExpression) expr).getValue());
break;
case 3:
av.visit(null, Type.getType(BytecodeHelper.getTypeDescription(expr.getType())));
break;
case 4:
PropertyExpression propExpr = (PropertyExpression) expr;
av.visitEnum(null,
BytecodeHelper.getTypeDescription(propExpr.getObjectExpression().getType()),
String.valueOf(((ConstantExpression) propExpr.getProperty()).getValue()));
break;
}
}
@Override
public AnnotationVisitor visitLocalVariableAnnotation(
final int typeRef,
final TypePath typePath,
final Label[] start,
final Label[] end,
final int[] index,
final String descriptor,
final boolean visible) {
Printer annotationPrinter =
p.visitLocalVariableAnnotation(typeRef, typePath, start, end, index, descriptor, visible);
return new TraceAnnotationVisitor(
super.visitLocalVariableAnnotation(
typeRef, typePath, start, end, index, descriptor, visible),
annotationPrinter);
}
@Override
public AnnotationVisitor visitInsnAnnotation(int typeRef, TypePath typePath, String desc, boolean visible) {
// Finds the last real instruction, i.e. the instruction targeted by
// this annotation.
AbstractInsnNode insn = instructions.getLast();
while (insn.getOpcode() == -1) {
insn = insn.getPrevious();
}
// Adds the annotation to this instruction.
TypeAnnotationNode an = new TypeAnnotationNode(typeRef, typePath, desc);
if (visible) {
if (insn.visibleTypeAnnotations == null) {
insn.visibleTypeAnnotations = new ArrayList<TypeAnnotationNode>(1);
}
insn.visibleTypeAnnotations.add(an);
} else {
if (insn.invisibleTypeAnnotations == null) {
insn.invisibleTypeAnnotations = new ArrayList<TypeAnnotationNode>(1);
}
insn.invisibleTypeAnnotations.add(an);
}
return an;
}
@Override
public AnnotationVisitor visitLocalVariableAnnotation(int typeRef, TypePath typePath, Label[] start, Label[] end, int[] index, String desc,
boolean visible) {
checkStartCode();
checkEndCode();
int sort = typeRef >>> 24;
if (sort != TypeReference.LOCAL_VARIABLE && sort != TypeReference.RESOURCE_VARIABLE) {
throw new IllegalArgumentException("Invalid type reference sort 0x" + Integer.toHexString(sort));
}
CheckClassAdapter.checkTypeRefAndPath(typeRef, typePath);
checkDesc(desc, false);
if (start == null || end == null || index == null || end.length != start.length || index.length != start.length) {
throw new IllegalArgumentException("Invalid start, end and index arrays (must be non null and of identical length");
}
for (int i = 0; i < start.length; ++i) {
checkLabel(start[i], true, "start label");
checkLabel(end[i], true, "end label");
checkUnsignedShort(index[i], "Invalid variable index");
int s = labels.get(start[i]).intValue();
int e = labels.get(end[i]).intValue();
if (e < s) {
throw new IllegalArgumentException("Invalid start and end labels (end must be greater than start)");
}
}
return super.visitLocalVariableAnnotation(typeRef, typePath, start, end, index, desc, visible);
}
@Override
public AnnotationVisitor visitTypeAnnotation(
final int typeRef, final TypePath typePath, final String descriptor, final boolean visible) {
checkVisitEndNotCalled();
int sort = new TypeReference(typeRef).getSort();
if (sort != TypeReference.METHOD_TYPE_PARAMETER
&& sort != TypeReference.METHOD_TYPE_PARAMETER_BOUND
&& sort != TypeReference.METHOD_RETURN
&& sort != TypeReference.METHOD_RECEIVER
&& sort != TypeReference.METHOD_FORMAL_PARAMETER
&& sort != TypeReference.THROWS) {
throw new IllegalArgumentException(INVALID_TYPE_REFERENCE + Integer.toHexString(sort));
}
CheckClassAdapter.checkTypeRef(typeRef);
CheckMethodAdapter.checkDescriptor(version, descriptor, false);
return new CheckAnnotationAdapter(
super.visitTypeAnnotation(typeRef, typePath, descriptor, visible));
}
@Override
public AnnotationVisitor visitLocalVariableAnnotation(
final int typeRef,
final TypePath typePath,
final Label[] start,
final Label[] end,
final int[] index,
final String descriptor,
final boolean visible) {
AnnotationVisitor annotationVisitor =
super.visitLocalVariableAnnotation(
typeRef, typePath, start, end, index, remapper.mapDesc(descriptor), visible);
return annotationVisitor == null
? annotationVisitor
: new AnnotationRemapper(api, annotationVisitor, remapper);
}
@Override
public AnnotationVisitor visitAnnotation(final String descriptor, final boolean visible) {
AnnotationNode annotation = new AnnotationNode(descriptor);
if (visible) {
if (visibleAnnotations == null) {
visibleAnnotations = new ArrayList<AnnotationNode>(1);
}
visibleAnnotations.add(annotation);
} else {
if (invisibleAnnotations == null) {
invisibleAnnotations = new ArrayList<AnnotationNode>(1);
}
invisibleAnnotations.add(annotation);
}
return annotation;
}
public AnnotationVisitor visitParameterAnnotation(
final int parameter,
final String desc,
final boolean visible)
{
cp.newUTF8(desc);
if (visible) {
cp.newUTF8("RuntimeVisibleParameterAnnotations");
} else {
cp.newUTF8("RuntimeInvisibleParameterAnnotations");
}
return new AnnotationConstantsCollector(mv.visitParameterAnnotation(parameter,
desc,
visible),
cp);
}
@Override
public AnnotationVisitor visitLocalVariableAnnotation(
final int typeRef,
final TypePath typePath,
final Label[] start,
final Label[] end,
final int[] index,
final String descriptor,
final boolean visible) {
AnnotationVisitor annotationVisitor =
super.visitLocalVariableAnnotation(
typeRef, typePath, start, end, index, remapper.mapDesc(descriptor), visible);
return annotationVisitor == null
? annotationVisitor
: new AnnotationRemapper(api, annotationVisitor, remapper);
}
@Override
public AnnotationVisitor visitTryCatchAnnotation(int typeRef, TypePath typePath, String desc, boolean visible) {
TryCatchBlockNode tcb = tryCatchBlocks.get((typeRef & 0x00FFFF00) >> 8);
TypeAnnotationNode an = new TypeAnnotationNode(typeRef, typePath, desc);
if (visible) {
if (tcb.visibleTypeAnnotations == null) {
tcb.visibleTypeAnnotations = new ArrayList<TypeAnnotationNode>(1);
}
tcb.visibleTypeAnnotations.add(an);
} else {
if (tcb.invisibleTypeAnnotations == null) {
tcb.invisibleTypeAnnotations = new ArrayList<TypeAnnotationNode>(1);
}
tcb.invisibleTypeAnnotations.add(an);
}
return an;
}
@Override
public AnnotationVisitor visitAnnotation(final String name, final String descriptor) {
AnnotationVisitor annotationVisitor = super.visitAnnotation(name, remapper.mapDesc(descriptor));
if (annotationVisitor == null) {
return null;
} else {
return annotationVisitor == av
? this
: new AnnotationRemapper(api, annotationVisitor, remapper);
}
}
public AnnotationVisitor visitAnnotation(final String desc,
final boolean visible) {
if (visible) {
final CacheonixAnnotation annRef = cacheonixAnnotations.get(desc);
if (annRef != null) {
currentState = annRef.stateForProcessing;
}
}
return super.visitAnnotation(desc, visible);
}
@Override
public AnnotationVisitor visitAnnotation(String name, String desc)
{
if (from == null)
{
return new CopyAnnotationVisitorAdapter(
null,
to.visitAnnotation(name, desc));
}
return new CopyAnnotationVisitorAdapter(
from.visitAnnotation(name, desc),
to.visitAnnotation(name, desc));
}
@Override
public AnnotationVisitor visitAnnotation(final String desc,
final boolean visible) {
AnnotationVisitor av = super.visitAnnotation(remapper.mapDesc(desc),
visible);
return av == null ? null
: new RemappingAnnotationAdapter(av, remapper) {
@Override
public void visitEnum(String name, String enumDesc,
String value) {
if (Type.getType(enumDesc).getClassName()
.equals(RedefinitionPolicy.class.getName())) {
RedefinitionPolicy valueAsEnum = RedefinitionPolicy
.valueOf(value);
if (Type.getType(desc).getClassName().equals(
FieldRedefinitionPolicy.class.getName())) {
cv.visitAttribute(new SingleByteAttribute(
FieldRedefinitionPolicy.class
.getSimpleName(),
(byte) valueAsEnum.ordinal()));
}
if (Type.getType(desc).getClassName().equals(
MethodRedefinitionPolicy.class.getName())) {
cv.visitAttribute(new SingleByteAttribute(
MethodRedefinitionPolicy.class
.getSimpleName(),
(byte) valueAsEnum.ordinal()));
}
}
super.visitEnum(name, desc, value);
}
};
}
@Override
public AnnotationVisitor visitInsnAnnotation(
final int typeRef, final TypePath typePath, final String descriptor, final boolean visible) {
Printer annotationPrinter = p.visitInsnAnnotation(typeRef, typePath, descriptor, visible);
return new TraceAnnotationVisitor(
super.visitInsnAnnotation(typeRef, typePath, descriptor, visible), annotationPrinter);
}
@Override
public AnnotationVisitor visitAnnotation(final String descriptor, final boolean visible) {
AnnotationVisitor annotationVisitor =
super.visitAnnotation(remapper.mapDesc(descriptor), visible);
return annotationVisitor == null
? annotationVisitor
: new AnnotationRemapper(api, annotationVisitor, remapper);
}
@Override
public AnnotationVisitor visitAnnotation(final String descriptor, final boolean visible) {
if (!isAnnotation && SKIP_ENCHANCING_ANNOTATION.equals(descriptor)) {
classContinuatedMarkerFound = true;
}
return null;
}
@Override
public void end(final String name) {
AnnotationVisitor av = (AnnotationVisitor) pop();
if (av != null) {
av.visitEnd();
}
}
@Override
public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
if (("L" + mApiUtilsClass + "$Api;").equals(desc)) {
hasAnnotation = true;
return new AnnotationVisitor(Opcodes.ASM5, super.visitAnnotation(desc, visible)) {
@Override
public void visit(String name, Object value) {// 可获取注解的值
isMock = (boolean) value;
super.visit(name, value);
}
};
}
return super.visitAnnotation(desc, visible);
}
@Test
public void shouldForwardVisitAnnotationDefaultCallsToChild() {
AnnotationVisitor av = getTesteeVisitor().visitAnnotationDefault();
if (av != null)
av.visit("foo", "bar");
getTesteeVisitor().visitInsn(NOP);
getTesteeVisitor().visitInsn(Opcodes.ATHROW);
getTesteeVisitor().visitEnd();
verify(this.mv).visitAnnotationDefault();
}
@Override
public AnnotationVisitor visitArray(final String name) {
if (values == null) {
values = new ArrayList<Object>(this.desc != null ? 2 : 1);
}
if (this.desc != null) {
values.add(name);
}
List<Object> array = new ArrayList<Object>();
values.add(array);
return new AnnotationNode(array);
}
@Override
public AnnotationVisitor visitInsnAnnotation(int typeRef,
TypePath typePath, String desc, boolean visible) {
AnnotationVisitor av = super.visitInsnAnnotation(typeRef, typePath,
remapper.mapDesc(desc), visible);
return av == null ? av : new RemappingAnnotationAdapter(av, remapper);
}
@Override
public AnnotationVisitor visitAnnotation(String description, boolean visible) {
if (isAnnotation && !classContinuableAnnotationFound) {
classContinuableAnnotationFound = cciResolver.isContinuableAnnotation(description);
}
return null;
}
/**
* Makes the given visitor visit this annotation.
*
* @param annotationVisitor
* an annotation visitor. Maybe {@literal null}.
*/
public void accept(final AnnotationVisitor annotationVisitor) {
if (annotationVisitor != null) {
if (values != null) {
for (int i = 0, n = values.size(); i < n; i += 2) {
String name = (String) values.get(i);
Object value = values.get(i + 1);
accept(annotationVisitor, name, value);
}
}
annotationVisitor.visitEnd();
}
}
@Override
public AnnotationVisitor visitParameterAnnotation(
final int parameter,
final String desc,
final boolean visible)
{
addDesc(desc);
return new AnnotationDependencyVisitor();
}
@Override
public AnnotationVisitor visitTryCatchAnnotation(
int typeRef, TypePath typePath, String descriptor, boolean visible) {
// An exception parameter annotation present in Javac-compiled bytecode has to be a type
// annotation. See the JLS link in visitLocalVariableAnnotation of this class.
return null;
}
static void visitAnnotationValue(AnnotationVisitor visitor, String key, Object value) {
if (value.getClass().isArray()) {
AnnotationVisitor arrayVisitor = visitor.visitArray(key);
for (Object arrayValue : (Object[]) value) {
// Default key is 'value'. It can be changed by using AnnotationValue type.
visitAnnotationValue(arrayVisitor, "value", arrayValue);
}
arrayVisitor.visitEnd();
} else if (value instanceof AnnotationValue) {
AnnotationValue annotationValue = (AnnotationValue) value;
visitor.visit(annotationValue.name(), annotationValue.value());
} else {
visitor.visit(key, value);
}
}
@Override
public AnnotationVisitor visitArray(String name)
{
if (from == null)
{
return new CopyAnnotationVisitorAdapter(
null,
to.visitArray(name));
}
return new CopyAnnotationVisitorAdapter(
from.visitArray(name),
to.visitArray(name));
}
@Override
public AnnotationVisitor visitAnnotation(final String descriptor, final boolean visible) {
AnnotationVisitor annotationVisitor =
super.visitAnnotation(remapper.mapDesc(descriptor), visible);
return annotationVisitor == null
? annotationVisitor
: new AnnotationRemapper(api, annotationVisitor, remapper);
}
private AnnotationVisitor paramAnnotationVisitor(final int index, final ParameterType parameterType) {
annotatedParameters.set(index);
final String type = parameterTypes.get(index);
MethodParameter methodParameter = methodParameters.get(index);
if (methodParameter == null) {
methodParameter = new MethodParameter(TypeIdentifier.ofType(type), parameterType);
methodParameters.put(index, methodParameter);
} else {
methodParameter.setParameterType(parameterType);
}
return new ParamAnnotationVisitor(methodParameter);
}