From 8969564893fc5d5e80be5fb96315922e210875ed Mon Sep 17 00:00:00 2001 From: Eric Bruneton Date: Mon, 4 Jan 2021 16:54:54 +0100 Subject: [PATCH 1/3] Add support for remapping annotation attribute names, while keeping backward compatibility. --- .../asm/commons/AnnotationRemapper.java | 123 ++++++++++++++++-- .../objectweb/asm/commons/ClassRemapper.java | 30 ++++- .../objectweb/asm/commons/FieldRemapper.java | 30 ++++- .../objectweb/asm/commons/MethodRemapper.java | 36 +++-- .../objectweb/asm/commons/ModuleRemapper.java | 4 +- .../asm/commons/RecordComponentRemapper.java | 26 +++- .../org/objectweb/asm/commons/Remapper.java | 12 ++ .../asm/commons/SignatureRemapper.java | 4 +- .../objectweb/asm/commons/SimpleRemapper.java | 11 +- .../asm/commons/ClassRemapperTest.java | 23 ++++ 10 files changed, 260 insertions(+), 39 deletions(-) diff --git a/asm-commons/src/main/java/org/objectweb/asm/commons/AnnotationRemapper.java b/asm-commons/src/main/java/org/objectweb/asm/commons/AnnotationRemapper.java index 7ef7ff7e..afd8c42f 100644 --- a/asm-commons/src/main/java/org/objectweb/asm/commons/AnnotationRemapper.java +++ b/asm-commons/src/main/java/org/objectweb/asm/commons/AnnotationRemapper.java @@ -38,6 +38,12 @@ import org.objectweb.asm.Opcodes; */ public class AnnotationRemapper extends AnnotationVisitor { + /** + * The descriptor of the visited annotation. May be {@literal null}, for instance for + * AnnotationDefault. + */ + protected final String descriptor; + /** The remapper used to remap the types in the visited annotation. */ protected final Remapper remapper; @@ -45,11 +51,27 @@ public class AnnotationRemapper extends AnnotationVisitor { * Constructs a new {@link AnnotationRemapper}. Subclasses must not use this constructor. * Instead, they must use the {@link #AnnotationRemapper(int,AnnotationVisitor,Remapper)} version. * - * @param annotationVisitor the annotation visitor this remapper must deleted to. + * @param annotationVisitor the annotation visitor this remapper must delegate to. * @param remapper the remapper to use to remap the types in the visited annotation. + * @deprecated use {@link #AnnotationRemapper(String, AnnotationVisitor, Remapper)} instead. */ + @Deprecated public AnnotationRemapper(final AnnotationVisitor annotationVisitor, final Remapper remapper) { - this(/* latest api = */ Opcodes.ASM9, annotationVisitor, remapper); + this(/* descriptor = */ null, annotationVisitor, remapper); + } + + /** + * Constructs a new {@link AnnotationRemapper}. Subclasses must not use this constructor. + * Instead, they must use the {@link #AnnotationRemapper(int,String,AnnotationVisitor,Remapper)} + * version. + * + * @param owner the internal name of the visited annotation. May be {@literal null}. + * @param annotationVisitor the annotation visitor this remapper must delegate to. + * @param remapper the remapper to use to remap the types in the visited annotation. + */ + public AnnotationRemapper( + final String owner, final AnnotationVisitor annotationVisitor, final Remapper remapper) { + this(/* latest api = */ Opcodes.ASM9, owner, annotationVisitor, remapper); } /** @@ -59,42 +81,69 @@ public class AnnotationRemapper extends AnnotationVisitor { * org.objectweb.asm.Opcodes#ASM4}, {@link org.objectweb.asm.Opcodes#ASM5}, {@link * org.objectweb.asm.Opcodes#ASM6}, {@link org.objectweb.asm.Opcodes#ASM7}, {@link * org.objectweb.asm.Opcodes#ASM8} or {@link org.objectweb.asm.Opcodes#ASM9}. - * @param annotationVisitor the annotation visitor this remapper must deleted to. + * @param annotationVisitor the annotation visitor this remapper must delegate to. * @param remapper the remapper to use to remap the types in the visited annotation. + * @deprecated use {@link #AnnotationRemapper(int, String, AnnotationVisitor, Remapper)} instead. */ + @Deprecated protected AnnotationRemapper( final int api, final AnnotationVisitor annotationVisitor, final Remapper remapper) { + this(api, /* descriptor = */ null, annotationVisitor, remapper); + } + + /** + * Constructs a new {@link AnnotationRemapper}. + * + * @param api the ASM API version supported by this remapper. Must be one of {@link + * org.objectweb.asm.Opcodes#ASM4}, {@link org.objectweb.asm.Opcodes#ASM5}, {@link + * org.objectweb.asm.Opcodes#ASM6}, {@link org.objectweb.asm.Opcodes#ASM7}, {@link + * org.objectweb.asm.Opcodes#ASM8} or {@link org.objectweb.asm.Opcodes#ASM9}. + * @param descriptor the descriptor of the visited annotation. May be {@literal null}. + * @param annotationVisitor the annotation visitor this remapper must delegate to. + * @param remapper the remapper to use to remap the types in the visited annotation. + */ + protected AnnotationRemapper( + final int api, + final String descriptor, + final AnnotationVisitor annotationVisitor, + final Remapper remapper) { super(api, annotationVisitor); + this.descriptor = descriptor; this.remapper = remapper; } @Override public void visit(final String name, final Object value) { - super.visit(name, remapper.mapValue(value)); + super.visit(mapAttributeName(name), remapper.mapValue(value)); } @Override public void visitEnum(final String name, final String descriptor, final String value) { - super.visitEnum(name, remapper.mapDesc(descriptor), value); + super.visitEnum(mapAttributeName(name), remapper.mapDesc(descriptor), value); } @Override public AnnotationVisitor visitAnnotation(final String name, final String descriptor) { - AnnotationVisitor annotationVisitor = super.visitAnnotation(name, remapper.mapDesc(descriptor)); + AnnotationVisitor annotationVisitor = + super.visitAnnotation(mapAttributeName(name), remapper.mapDesc(descriptor)); if (annotationVisitor == null) { return null; } else { - return annotationVisitor == av ? this : createAnnotationRemapper(annotationVisitor); + return annotationVisitor == av + ? this + : createAnnotationRemapper(descriptor, annotationVisitor); } } @Override public AnnotationVisitor visitArray(final String name) { - AnnotationVisitor annotationVisitor = super.visitArray(name); + AnnotationVisitor annotationVisitor = super.visitArray(mapAttributeName(name)); if (annotationVisitor == null) { return null; } else { - return annotationVisitor == av ? this : createAnnotationRemapper(annotationVisitor); + return annotationVisitor == av + ? this + : createAnnotationRemapper(/* descriptor = */ null, annotationVisitor); } } @@ -104,8 +153,62 @@ public class AnnotationRemapper extends AnnotationVisitor { * * @param annotationVisitor the AnnotationVisitor the remapper must delegate to. * @return the newly created remapper. + * @deprecated use {@link #createAnnotationRemapper(String, AnnotationVisitor)} instead. */ + @Deprecated protected AnnotationVisitor createAnnotationRemapper(final AnnotationVisitor annotationVisitor) { - return new AnnotationRemapper(api, annotationVisitor, remapper); + return new AnnotationRemapper(api, /* descriptor = */ null, annotationVisitor, remapper); + } + + /** + * Constructs a new remapper for annotations. The default implementation of this method returns a + * new {@link AnnotationRemapper}. + * + * @param descriptor the descriptor of the visited annotation. + * @param annotationVisitor the AnnotationVisitor the remapper must delegate to. + * @return the newly created remapper. + */ + protected AnnotationVisitor createAnnotationRemapper( + final String descriptor, final AnnotationVisitor annotationVisitor) { + return new AnnotationRemapper(api, descriptor, annotationVisitor, remapper) + .orDeprecatedValue(createAnnotationRemapper(annotationVisitor)); + } + + /** + * Returns either this object, or the given one. If the given object is equal to the object + * returned by the default implementation of the deprecated createAnnotationRemapper method, + * meaning that this method has not been overridden (or only in minor ways, for instance to add + * logging), then we can return this object instead, supposed to have been created by the new + * createAnnotationRemapper method. Otherwise we must return the given object. + * + * @param deprecatedAnnotationVisitor the result of a call to the deprecated + * createAnnotationRemapper method. + * @return either this object, or the given one. + */ + AnnotationVisitor orDeprecatedValue(final AnnotationVisitor deprecatedAnnotationVisitor) { + if (deprecatedAnnotationVisitor.getClass().equals(getClass())) { + AnnotationRemapper deprecatedAnnotationRemapper = + (AnnotationRemapper) deprecatedAnnotationVisitor; + if (deprecatedAnnotationRemapper.api == api + && deprecatedAnnotationRemapper.av == av + && deprecatedAnnotationRemapper.remapper == remapper) { + return this; + } + } + return deprecatedAnnotationVisitor; + } + + /** + * Maps an annotation attribute name with the remapper. Returns the original name unchanged if the + * internal name of the annotation is {@literal null}. + * + * @param name the name of the annotation attribute. + * @return the new name of the annotation attribute. + */ + private String mapAttributeName(final String name) { + if (descriptor == null) { + return name; + } + return remapper.mapAttributeName(descriptor, name); } } diff --git a/asm-commons/src/main/java/org/objectweb/asm/commons/ClassRemapper.java b/asm-commons/src/main/java/org/objectweb/asm/commons/ClassRemapper.java index f02a6cb7..09271967 100644 --- a/asm-commons/src/main/java/org/objectweb/asm/commons/ClassRemapper.java +++ b/asm-commons/src/main/java/org/objectweb/asm/commons/ClassRemapper.java @@ -70,7 +70,7 @@ public class ClassRemapper extends ClassVisitor { * Constructs a new {@link ClassRemapper}. Subclasses must not use this constructor. * Instead, they must use the {@link #ClassRemapper(int,ClassVisitor,Remapper)} version. * - * @param classVisitor the class visitor this remapper must deleted to. + * @param classVisitor the class visitor this remapper must delegate to. * @param remapper the remapper to use to remap the types in the visited class. */ public ClassRemapper(final ClassVisitor classVisitor, final Remapper remapper) { @@ -84,7 +84,7 @@ public class ClassRemapper extends ClassVisitor { * org.objectweb.asm.Opcodes#ASM4}, {@link org.objectweb.asm.Opcodes#ASM5}, {@link * org.objectweb.asm.Opcodes#ASM6}, {@link org.objectweb.asm.Opcodes#ASM7}, {@link * org.objectweb.asm.Opcodes#ASM8} or {@link org.objectweb.asm.Opcodes#ASM9}. - * @param classVisitor the class visitor this remapper must deleted to. + * @param classVisitor the class visitor this remapper must delegate to. * @param remapper the remapper to use to remap the types in the visited class. */ protected ClassRemapper(final int api, final ClassVisitor classVisitor, final Remapper remapper) { @@ -120,7 +120,9 @@ public class ClassRemapper extends ClassVisitor { public AnnotationVisitor visitAnnotation(final String descriptor, final boolean visible) { AnnotationVisitor annotationVisitor = super.visitAnnotation(remapper.mapDesc(descriptor), visible); - return annotationVisitor == null ? null : createAnnotationRemapper(annotationVisitor); + return annotationVisitor == null + ? null + : createAnnotationRemapper(descriptor, annotationVisitor); } @Override @@ -128,7 +130,9 @@ public class ClassRemapper extends ClassVisitor { final int typeRef, final TypePath typePath, final String descriptor, final boolean visible) { AnnotationVisitor annotationVisitor = super.visitTypeAnnotation(typeRef, typePath, remapper.mapDesc(descriptor), visible); - return annotationVisitor == null ? null : createAnnotationRemapper(annotationVisitor); + return annotationVisitor == null + ? null + : createAnnotationRemapper(descriptor, annotationVisitor); } @Override @@ -252,9 +256,25 @@ public class ClassRemapper extends ClassVisitor { * * @param annotationVisitor the AnnotationVisitor the remapper must delegate to. * @return the newly created remapper. + * @deprecated use {@link #createAnnotationRemapper(String, AnnotationVisitor)} instead. */ + @Deprecated protected AnnotationVisitor createAnnotationRemapper(final AnnotationVisitor annotationVisitor) { - return new AnnotationRemapper(api, annotationVisitor, remapper); + return new AnnotationRemapper(api, /* descriptor = */ null, annotationVisitor, remapper); + } + + /** + * Constructs a new remapper for annotations. The default implementation of this method returns a + * new {@link AnnotationRemapper}. + * + * @param descriptor the descriptor of the visited annotation. + * @param annotationVisitor the AnnotationVisitor the remapper must delegate to. + * @return the newly created remapper. + */ + protected AnnotationVisitor createAnnotationRemapper( + final String descriptor, final AnnotationVisitor annotationVisitor) { + return new AnnotationRemapper(api, descriptor, annotationVisitor, remapper) + .orDeprecatedValue(createAnnotationRemapper(annotationVisitor)); } /** diff --git a/asm-commons/src/main/java/org/objectweb/asm/commons/FieldRemapper.java b/asm-commons/src/main/java/org/objectweb/asm/commons/FieldRemapper.java index dd225dc3..979c137d 100644 --- a/asm-commons/src/main/java/org/objectweb/asm/commons/FieldRemapper.java +++ b/asm-commons/src/main/java/org/objectweb/asm/commons/FieldRemapper.java @@ -47,7 +47,7 @@ public class FieldRemapper extends FieldVisitor { * Constructs a new {@link FieldRemapper}. Subclasses must not use this constructor. * Instead, they must use the {@link #FieldRemapper(int,FieldVisitor,Remapper)} version. * - * @param fieldVisitor the field visitor this remapper must deleted to. + * @param fieldVisitor the field visitor this remapper must delegate to. * @param remapper the remapper to use to remap the types in the visited field. */ public FieldRemapper(final FieldVisitor fieldVisitor, final Remapper remapper) { @@ -60,7 +60,7 @@ public class FieldRemapper extends FieldVisitor { * @param api the ASM API version supported by this remapper. Must be one of {@link Opcodes#ASM4}, * {@link Opcodes#ASM5}, {@link Opcodes#ASM6}, {@link Opcodes#ASM7}, {@link Opcodes#ASM8}, or * {@link Opcodes#ASM9}. - * @param fieldVisitor the field visitor this remapper must deleted to. + * @param fieldVisitor the field visitor this remapper must delegate to. * @param remapper the remapper to use to remap the types in the visited field. */ protected FieldRemapper(final int api, final FieldVisitor fieldVisitor, final Remapper remapper) { @@ -72,7 +72,9 @@ public class FieldRemapper extends FieldVisitor { public AnnotationVisitor visitAnnotation(final String descriptor, final boolean visible) { AnnotationVisitor annotationVisitor = super.visitAnnotation(remapper.mapDesc(descriptor), visible); - return annotationVisitor == null ? null : createAnnotationRemapper(annotationVisitor); + return annotationVisitor == null + ? null + : createAnnotationRemapper(descriptor, annotationVisitor); } @Override @@ -80,7 +82,9 @@ public class FieldRemapper extends FieldVisitor { final int typeRef, final TypePath typePath, final String descriptor, final boolean visible) { AnnotationVisitor annotationVisitor = super.visitTypeAnnotation(typeRef, typePath, remapper.mapDesc(descriptor), visible); - return annotationVisitor == null ? null : createAnnotationRemapper(annotationVisitor); + return annotationVisitor == null + ? null + : createAnnotationRemapper(descriptor, annotationVisitor); } /** @@ -89,8 +93,24 @@ public class FieldRemapper extends FieldVisitor { * * @param annotationVisitor the AnnotationVisitor the remapper must delegate to. * @return the newly created remapper. + * @deprecated use {@link #createAnnotationRemapper(String, AnnotationVisitor)} instead. */ + @Deprecated protected AnnotationVisitor createAnnotationRemapper(final AnnotationVisitor annotationVisitor) { - return new AnnotationRemapper(api, annotationVisitor, remapper); + return new AnnotationRemapper(api, /* descriptor = */ null, annotationVisitor, remapper); + } + + /** + * Constructs a new remapper for annotations. The default implementation of this method returns a + * new {@link AnnotationRemapper}. + * + * @param descriptor the descriptor of the visited annotation. + * @param annotationVisitor the AnnotationVisitor the remapper must delegate to. + * @return the newly created remapper. + */ + protected AnnotationVisitor createAnnotationRemapper( + final String descriptor, final AnnotationVisitor annotationVisitor) { + return new AnnotationRemapper(api, descriptor, annotationVisitor, remapper) + .orDeprecatedValue(createAnnotationRemapper(annotationVisitor)); } } diff --git a/asm-commons/src/main/java/org/objectweb/asm/commons/MethodRemapper.java b/asm-commons/src/main/java/org/objectweb/asm/commons/MethodRemapper.java index 24bee00f..cb06e888 100644 --- a/asm-commons/src/main/java/org/objectweb/asm/commons/MethodRemapper.java +++ b/asm-commons/src/main/java/org/objectweb/asm/commons/MethodRemapper.java @@ -49,7 +49,7 @@ public class MethodRemapper extends MethodVisitor { * Constructs a new {@link MethodRemapper}. Subclasses must not use this constructor. * Instead, they must use the {@link #MethodRemapper(int,MethodVisitor,Remapper)} version. * - * @param methodVisitor the method visitor this remapper must deleted to. + * @param methodVisitor the method visitor this remapper must delegate to. * @param remapper the remapper to use to remap the types in the visited method. */ public MethodRemapper(final MethodVisitor methodVisitor, final Remapper remapper) { @@ -63,7 +63,7 @@ public class MethodRemapper extends MethodVisitor { * org.objectweb.asm.Opcodes#ASM4}, {@link org.objectweb.asm.Opcodes#ASM5}, {@link * org.objectweb.asm.Opcodes#ASM6}, {@link org.objectweb.asm.Opcodes#ASM7}, {@link * org.objectweb.asm.Opcodes#ASM8} or {@link org.objectweb.asm.Opcodes#ASM9}. - * @param methodVisitor the method visitor this remapper must deleted to. + * @param methodVisitor the method visitor this remapper must delegate to. * @param remapper the remapper to use to remap the types in the visited method. */ protected MethodRemapper( @@ -77,7 +77,7 @@ public class MethodRemapper extends MethodVisitor { AnnotationVisitor annotationVisitor = super.visitAnnotationDefault(); return annotationVisitor == null ? annotationVisitor - : createAnnotationRemapper(annotationVisitor); + : createAnnotationRemapper(/* descriptor = */ null, annotationVisitor); } @Override @@ -86,7 +86,7 @@ public class MethodRemapper extends MethodVisitor { super.visitAnnotation(remapper.mapDesc(descriptor), visible); return annotationVisitor == null ? annotationVisitor - : createAnnotationRemapper(annotationVisitor); + : createAnnotationRemapper(descriptor, annotationVisitor); } @Override @@ -96,7 +96,7 @@ public class MethodRemapper extends MethodVisitor { super.visitTypeAnnotation(typeRef, typePath, remapper.mapDesc(descriptor), visible); return annotationVisitor == null ? annotationVisitor - : createAnnotationRemapper(annotationVisitor); + : createAnnotationRemapper(descriptor, annotationVisitor); } @Override @@ -106,7 +106,7 @@ public class MethodRemapper extends MethodVisitor { super.visitParameterAnnotation(parameter, remapper.mapDesc(descriptor), visible); return annotationVisitor == null ? annotationVisitor - : createAnnotationRemapper(annotationVisitor); + : createAnnotationRemapper(descriptor, annotationVisitor); } @Override @@ -210,7 +210,7 @@ public class MethodRemapper extends MethodVisitor { super.visitInsnAnnotation(typeRef, typePath, remapper.mapDesc(descriptor), visible); return annotationVisitor == null ? annotationVisitor - : createAnnotationRemapper(annotationVisitor); + : createAnnotationRemapper(descriptor, annotationVisitor); } @Override @@ -226,7 +226,7 @@ public class MethodRemapper extends MethodVisitor { super.visitTryCatchAnnotation(typeRef, typePath, remapper.mapDesc(descriptor), visible); return annotationVisitor == null ? annotationVisitor - : createAnnotationRemapper(annotationVisitor); + : createAnnotationRemapper(descriptor, annotationVisitor); } @Override @@ -260,7 +260,7 @@ public class MethodRemapper extends MethodVisitor { typeRef, typePath, start, end, index, remapper.mapDesc(descriptor), visible); return annotationVisitor == null ? annotationVisitor - : createAnnotationRemapper(annotationVisitor); + : createAnnotationRemapper(descriptor, annotationVisitor); } /** @@ -269,8 +269,24 @@ public class MethodRemapper extends MethodVisitor { * * @param annotationVisitor the AnnotationVisitor the remapper must delegate to. * @return the newly created remapper. + * @deprecated use {@link #createAnnotationRemapper(String, AnnotationVisitor)} instead. */ + @Deprecated protected AnnotationVisitor createAnnotationRemapper(final AnnotationVisitor annotationVisitor) { - return new AnnotationRemapper(api, annotationVisitor, remapper); + return new AnnotationRemapper(api, /* descriptor = */ null, annotationVisitor, remapper); + } + + /** + * Constructs a new remapper for annotations. The default implementation of this method returns a + * new {@link AnnotationRemapper}. + * + * @param descriptor the descriptor of the visited annotation. + * @param annotationVisitor the AnnotationVisitor the remapper must delegate to. + * @return the newly created remapper. + */ + protected AnnotationVisitor createAnnotationRemapper( + final String descriptor, final AnnotationVisitor annotationVisitor) { + return new AnnotationRemapper(api, descriptor, annotationVisitor, remapper) + .orDeprecatedValue(createAnnotationRemapper(annotationVisitor)); } } diff --git a/asm-commons/src/main/java/org/objectweb/asm/commons/ModuleRemapper.java b/asm-commons/src/main/java/org/objectweb/asm/commons/ModuleRemapper.java index 4baf8035..ce359983 100644 --- a/asm-commons/src/main/java/org/objectweb/asm/commons/ModuleRemapper.java +++ b/asm-commons/src/main/java/org/objectweb/asm/commons/ModuleRemapper.java @@ -45,7 +45,7 @@ public class ModuleRemapper extends ModuleVisitor { * Constructs a new {@link ModuleRemapper}. Subclasses must not use this constructor. * Instead, they must use the {@link #ModuleRemapper(int,ModuleVisitor,Remapper)} version. * - * @param moduleVisitor the module visitor this remapper must deleted to. + * @param moduleVisitor the module visitor this remapper must delegate to. * @param remapper the remapper to use to remap the types in the visited module. */ public ModuleRemapper(final ModuleVisitor moduleVisitor, final Remapper remapper) { @@ -59,7 +59,7 @@ public class ModuleRemapper extends ModuleVisitor { * org.objectweb.asm.Opcodes#ASM4}, {@link org.objectweb.asm.Opcodes#ASM5}, {@link * org.objectweb.asm.Opcodes#ASM6}, {@link org.objectweb.asm.Opcodes#ASM7}, {@link * org.objectweb.asm.Opcodes#ASM8} or {@link org.objectweb.asm.Opcodes#ASM9}. - * @param moduleVisitor the module visitor this remapper must deleted to. + * @param moduleVisitor the module visitor this remapper must delegate to. * @param remapper the remapper to use to remap the types in the visited module. */ protected ModuleRemapper( diff --git a/asm-commons/src/main/java/org/objectweb/asm/commons/RecordComponentRemapper.java b/asm-commons/src/main/java/org/objectweb/asm/commons/RecordComponentRemapper.java index c11f41ee..2f1e5ae2 100644 --- a/asm-commons/src/main/java/org/objectweb/asm/commons/RecordComponentRemapper.java +++ b/asm-commons/src/main/java/org/objectweb/asm/commons/RecordComponentRemapper.java @@ -74,7 +74,9 @@ public class RecordComponentRemapper extends RecordComponentVisitor { public AnnotationVisitor visitAnnotation(final String descriptor, final boolean visible) { AnnotationVisitor annotationVisitor = super.visitAnnotation(remapper.mapDesc(descriptor), visible); - return annotationVisitor == null ? null : createAnnotationRemapper(annotationVisitor); + return annotationVisitor == null + ? null + : createAnnotationRemapper(descriptor, annotationVisitor); } @Override @@ -82,7 +84,9 @@ public class RecordComponentRemapper extends RecordComponentVisitor { final int typeRef, final TypePath typePath, final String descriptor, final boolean visible) { AnnotationVisitor annotationVisitor = super.visitTypeAnnotation(typeRef, typePath, remapper.mapDesc(descriptor), visible); - return annotationVisitor == null ? null : createAnnotationRemapper(annotationVisitor); + return annotationVisitor == null + ? null + : createAnnotationRemapper(descriptor, annotationVisitor); } /** @@ -91,8 +95,24 @@ public class RecordComponentRemapper extends RecordComponentVisitor { * * @param annotationVisitor the AnnotationVisitor the remapper must delegate to. * @return the newly created remapper. + * @deprecated use {@link #createAnnotationRemapper(String, AnnotationVisitor)} instead. */ + @Deprecated protected AnnotationVisitor createAnnotationRemapper(final AnnotationVisitor annotationVisitor) { - return new AnnotationRemapper(api, annotationVisitor, remapper); + return new AnnotationRemapper(api, /* descriptor = */ null, annotationVisitor, remapper); + } + + /** + * Constructs a new remapper for annotations. The default implementation of this method returns a + * new {@link AnnotationRemapper}. + * + * @param descriptor the descriptor sof the visited annotation. + * @param annotationVisitor the AnnotationVisitor the remapper must delegate to. + * @return the newly created remapper. + */ + protected AnnotationVisitor createAnnotationRemapper( + final String descriptor, final AnnotationVisitor annotationVisitor) { + return new AnnotationRemapper(api, descriptor, annotationVisitor, remapper) + .orDeprecatedValue(createAnnotationRemapper(annotationVisitor)); } } diff --git a/asm-commons/src/main/java/org/objectweb/asm/commons/Remapper.java b/asm-commons/src/main/java/org/objectweb/asm/commons/Remapper.java index e70e67af..345280b3 100644 --- a/asm-commons/src/main/java/org/objectweb/asm/commons/Remapper.java +++ b/asm-commons/src/main/java/org/objectweb/asm/commons/Remapper.java @@ -236,6 +236,18 @@ public abstract class Remapper { return new SignatureRemapper(signatureVisitor, this); } + /** + * Maps an annotation attribute name. The default implementation of this method returns the given + * name, unchanged. Subclasses can override. + * + * @param descriptor the descriptor of the annotation class. + * @param name the name of the annotation attribute. + * @return the new name of the annotation attribute. + */ + public String mapAttributeName(final String descriptor, final String name) { + return name; + } + /** * Maps an inner class name to its new name. The default implementation of this method provides a * strategy that will work for inner classes produced by Java, but not necessarily other diff --git a/asm-commons/src/main/java/org/objectweb/asm/commons/SignatureRemapper.java b/asm-commons/src/main/java/org/objectweb/asm/commons/SignatureRemapper.java index 20501144..356d1802 100644 --- a/asm-commons/src/main/java/org/objectweb/asm/commons/SignatureRemapper.java +++ b/asm-commons/src/main/java/org/objectweb/asm/commons/SignatureRemapper.java @@ -49,7 +49,7 @@ public class SignatureRemapper extends SignatureVisitor { * Constructs a new {@link SignatureRemapper}. Subclasses must not use this constructor. * Instead, they must use the {@link #SignatureRemapper(int,SignatureVisitor,Remapper)} version. * - * @param signatureVisitor the signature visitor this remapper must deleted to. + * @param signatureVisitor the signature visitor this remapper must delegate to. * @param remapper the remapper to use to remap the types in the visited signature. */ public SignatureRemapper(final SignatureVisitor signatureVisitor, final Remapper remapper) { @@ -63,7 +63,7 @@ public class SignatureRemapper extends SignatureVisitor { * org.objectweb.asm.Opcodes#ASM4}, {@link org.objectweb.asm.Opcodes#ASM5},{@link * org.objectweb.asm.Opcodes#ASM6}, {@link org.objectweb.asm.Opcodes#ASM7}, {@link * org.objectweb.asm.Opcodes#ASM8} or {@link org.objectweb.asm.Opcodes#ASM9}. - * @param signatureVisitor the signature visitor this remapper must deleted to. + * @param signatureVisitor the signature visitor this remapper must delegate to. * @param remapper the remapper to use to remap the types in the visited signature. */ protected SignatureRemapper( diff --git a/asm-commons/src/main/java/org/objectweb/asm/commons/SimpleRemapper.java b/asm-commons/src/main/java/org/objectweb/asm/commons/SimpleRemapper.java index c48a911b..3c4a9429 100644 --- a/asm-commons/src/main/java/org/objectweb/asm/commons/SimpleRemapper.java +++ b/asm-commons/src/main/java/org/objectweb/asm/commons/SimpleRemapper.java @@ -50,8 +50,9 @@ public class SimpleRemapper extends Remapper { * name. *
  • for invokedynamic method names, the key is the name and descriptor of the method (in * the form .<name><descriptor>), and the value is the new method name. - *
  • for field names, the key is the owner and name of the field (in the form - * <owner>.<name>), and the value is the new field name. + *
  • for field and attribute names, the key is the owner and name of the field or + * attribute (in the form <owner>.<name>), and the value is the new field + * name. *
  • for internal names, the key is the old internal name, and the value is the new * internal name. * @@ -83,6 +84,12 @@ public class SimpleRemapper extends Remapper { return remappedName == null ? name : remappedName; } + @Override + public String mapAttributeName(final String descriptor, final String name) { + String remappedName = map(descriptor + '.' + name); + return remappedName == null ? name : remappedName; + } + @Override public String mapFieldName(final String owner, final String name, final String descriptor) { String remappedName = map(owner + '.' + name); diff --git a/asm-commons/src/test/java/org/objectweb/asm/commons/ClassRemapperTest.java b/asm-commons/src/test/java/org/objectweb/asm/commons/ClassRemapperTest.java index ee86f73f..cfe16495 100644 --- a/asm-commons/src/test/java/org/objectweb/asm/commons/ClassRemapperTest.java +++ b/asm-commons/src/test/java/org/objectweb/asm/commons/ClassRemapperTest.java @@ -38,6 +38,7 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.api.function.Executable; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.MethodSource; +import org.objectweb.asm.AnnotationVisitor; import org.objectweb.asm.ClassReader; import org.objectweb.asm.ClassVisitor; import org.objectweb.asm.ClassWriter; @@ -70,6 +71,28 @@ public class ClassRemapperTest extends AsmTest { assertEquals("new/pkg/C", classNode.name); } + @Test + public void testVisitAnnotation() { + ClassNode classNode = new ClassNode(); + ClassRemapper remapper = + new ClassRemapper( + classNode, + new Remapper() { + @Override + public String mapAttributeName(final String descriptor, final String name) { + if ("Lpkg/A;".equals(descriptor)) { + return "new." + name; + } + return name; + } + }); + remapper.visit(Opcodes.V1_5, Opcodes.ACC_PUBLIC, "pkg/C", null, "java/lang/Object", null); + AnnotationVisitor annotationVisitor = remapper.visitAnnotation("Lpkg/A;", true); + annotationVisitor.visit("attribute", "value"); + + assertEquals("new.attribute", classNode.visibleAnnotations.get(0).values.get(0)); + } + @Test public void testVisitInnerClass() { ClassNode classNode = new ClassNode(); -- GitLab From 2efb6e08f26744516e170fc1d7360680b18b7c09 Mon Sep 17 00:00:00 2001 From: Eric Bruneton Date: Mon, 4 Jan 2021 17:14:38 +0100 Subject: [PATCH 2/3] Fix parameter name. --- .../java/org/objectweb/asm/commons/AnnotationRemapper.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/asm-commons/src/main/java/org/objectweb/asm/commons/AnnotationRemapper.java b/asm-commons/src/main/java/org/objectweb/asm/commons/AnnotationRemapper.java index afd8c42f..91d1cd51 100644 --- a/asm-commons/src/main/java/org/objectweb/asm/commons/AnnotationRemapper.java +++ b/asm-commons/src/main/java/org/objectweb/asm/commons/AnnotationRemapper.java @@ -65,13 +65,13 @@ public class AnnotationRemapper extends AnnotationVisitor { * Instead, they must use the {@link #AnnotationRemapper(int,String,AnnotationVisitor,Remapper)} * version. * - * @param owner the internal name of the visited annotation. May be {@literal null}. + * @param descriptor the descriptor of the visited annotation. May be {@literal null}. * @param annotationVisitor the annotation visitor this remapper must delegate to. * @param remapper the remapper to use to remap the types in the visited annotation. */ public AnnotationRemapper( - final String owner, final AnnotationVisitor annotationVisitor, final Remapper remapper) { - this(/* latest api = */ Opcodes.ASM9, owner, annotationVisitor, remapper); + final String descriptor, final AnnotationVisitor annotationVisitor, final Remapper remapper) { + this(/* latest api = */ Opcodes.ASM9, descriptor, annotationVisitor, remapper); } /** -- GitLab From 9d0bbe7f4a95afaa41c10d85b64da3f1a528792e Mon Sep 17 00:00:00 2001 From: Eric Bruneton Date: Wed, 27 Jan 2021 19:39:27 +0100 Subject: [PATCH 3/3] Address code review comments. --- .../asm/commons/AnnotationRemapper.java | 16 ++++++++-------- .../java/org/objectweb/asm/commons/Remapper.java | 2 +- .../objectweb/asm/commons/SimpleRemapper.java | 2 +- .../objectweb/asm/commons/ClassRemapperTest.java | 2 +- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/asm-commons/src/main/java/org/objectweb/asm/commons/AnnotationRemapper.java b/asm-commons/src/main/java/org/objectweb/asm/commons/AnnotationRemapper.java index 91d1cd51..4e61831b 100644 --- a/asm-commons/src/main/java/org/objectweb/asm/commons/AnnotationRemapper.java +++ b/asm-commons/src/main/java/org/objectweb/asm/commons/AnnotationRemapper.java @@ -114,18 +114,18 @@ public class AnnotationRemapper extends AnnotationVisitor { @Override public void visit(final String name, final Object value) { - super.visit(mapAttributeName(name), remapper.mapValue(value)); + super.visit(mapAnnotationAttributeName(name), remapper.mapValue(value)); } @Override public void visitEnum(final String name, final String descriptor, final String value) { - super.visitEnum(mapAttributeName(name), remapper.mapDesc(descriptor), value); + super.visitEnum(mapAnnotationAttributeName(name), remapper.mapDesc(descriptor), value); } @Override public AnnotationVisitor visitAnnotation(final String name, final String descriptor) { AnnotationVisitor annotationVisitor = - super.visitAnnotation(mapAttributeName(name), remapper.mapDesc(descriptor)); + super.visitAnnotation(mapAnnotationAttributeName(name), remapper.mapDesc(descriptor)); if (annotationVisitor == null) { return null; } else { @@ -137,7 +137,7 @@ public class AnnotationRemapper extends AnnotationVisitor { @Override public AnnotationVisitor visitArray(final String name) { - AnnotationVisitor annotationVisitor = super.visitArray(mapAttributeName(name)); + AnnotationVisitor annotationVisitor = super.visitArray(mapAnnotationAttributeName(name)); if (annotationVisitor == null) { return null; } else { @@ -185,8 +185,8 @@ public class AnnotationRemapper extends AnnotationVisitor { * createAnnotationRemapper method. * @return either this object, or the given one. */ - AnnotationVisitor orDeprecatedValue(final AnnotationVisitor deprecatedAnnotationVisitor) { - if (deprecatedAnnotationVisitor.getClass().equals(getClass())) { + final AnnotationVisitor orDeprecatedValue(final AnnotationVisitor deprecatedAnnotationVisitor) { + if (deprecatedAnnotationVisitor.getClass() == getClass()) { AnnotationRemapper deprecatedAnnotationRemapper = (AnnotationRemapper) deprecatedAnnotationVisitor; if (deprecatedAnnotationRemapper.api == api @@ -205,10 +205,10 @@ public class AnnotationRemapper extends AnnotationVisitor { * @param name the name of the annotation attribute. * @return the new name of the annotation attribute. */ - private String mapAttributeName(final String name) { + private String mapAnnotationAttributeName(final String name) { if (descriptor == null) { return name; } - return remapper.mapAttributeName(descriptor, name); + return remapper.mapAnnotationAttributeName(descriptor, name); } } diff --git a/asm-commons/src/main/java/org/objectweb/asm/commons/Remapper.java b/asm-commons/src/main/java/org/objectweb/asm/commons/Remapper.java index 345280b3..8186376c 100644 --- a/asm-commons/src/main/java/org/objectweb/asm/commons/Remapper.java +++ b/asm-commons/src/main/java/org/objectweb/asm/commons/Remapper.java @@ -244,7 +244,7 @@ public abstract class Remapper { * @param name the name of the annotation attribute. * @return the new name of the annotation attribute. */ - public String mapAttributeName(final String descriptor, final String name) { + public String mapAnnotationAttributeName(final String descriptor, final String name) { return name; } diff --git a/asm-commons/src/main/java/org/objectweb/asm/commons/SimpleRemapper.java b/asm-commons/src/main/java/org/objectweb/asm/commons/SimpleRemapper.java index 3c4a9429..9986f10d 100644 --- a/asm-commons/src/main/java/org/objectweb/asm/commons/SimpleRemapper.java +++ b/asm-commons/src/main/java/org/objectweb/asm/commons/SimpleRemapper.java @@ -85,7 +85,7 @@ public class SimpleRemapper extends Remapper { } @Override - public String mapAttributeName(final String descriptor, final String name) { + public String mapAnnotationAttributeName(final String descriptor, final String name) { String remappedName = map(descriptor + '.' + name); return remappedName == null ? name : remappedName; } diff --git a/asm-commons/src/test/java/org/objectweb/asm/commons/ClassRemapperTest.java b/asm-commons/src/test/java/org/objectweb/asm/commons/ClassRemapperTest.java index cfe16495..cba05f47 100644 --- a/asm-commons/src/test/java/org/objectweb/asm/commons/ClassRemapperTest.java +++ b/asm-commons/src/test/java/org/objectweb/asm/commons/ClassRemapperTest.java @@ -79,7 +79,7 @@ public class ClassRemapperTest extends AsmTest { classNode, new Remapper() { @Override - public String mapAttributeName(final String descriptor, final String name) { + public String mapAnnotationAttributeName(final String descriptor, final String name) { if ("Lpkg/A;".equals(descriptor)) { return "new." + name; } -- GitLab