1414import java .util .function .Consumer ;
1515
1616import org .jetbrains .annotations .Nullable ;
17- import org .objectweb .asm .Handle ;
18- import org .objectweb .asm .Opcodes ;
1917import org .objectweb .asm .Type ;
2018import org .objectweb .asm .commons .Remapper ;
2119
@@ -40,7 +38,32 @@ public EnhancedRemapper(ClassProvider classProvider, IMappingFile map, Consumer<
4038 }
4139
4240 @ Override public String mapModuleName (final String name ) { return name ; } // TODO? None of the mapping formats support this.
43- @ Override public String mapAnnotationAttributeName (final String descriptor , final String name ) { return name ; } // TODO: Is this just methods?
41+ @ Override
42+ public String mapAnnotationAttributeName (final String descriptor , final String name ) {
43+ Type type = Type .getType (descriptor );
44+ if (type .getSort () != Type .OBJECT )
45+ return name ;
46+
47+ MClass cls = getClass (type .getInternalName ()).orElse (null );
48+ if (cls == null )
49+ return name ;
50+
51+ List <MClass .MMethod > lst = cls .getMethods (name ).orElse (null );
52+ if (lst == null )
53+ return name ;
54+
55+ // You should not be able to specify conflicting annotation value names
56+ // As annotation attributes can't have parameters, and the bytecode doesn't store the descriptor
57+ // But renamers can be weird so log instead of doing weird things.
58+ if (lst .size () != 1 ) {
59+ for (MClass .MMethod mtd : lst )
60+ log .accept ("Duplicate Annotation name: " + cls .getName () + " " + mtd .getName () + mtd .getDescriptor () + " -> " + cls .getMapped () + " " + mtd .getName ());
61+ return name ;
62+ }
63+
64+ return lst .get (0 ).getMapped ();
65+ }
66+
4467 @ Override public String mapInvokeDynamicMethodName (final String name , final String descriptor ) { return name ; } // TODO: Lookup how the JVM resolves this and attempt to resolve it to get the owner?
4568
4669 @ Override
@@ -81,26 +104,6 @@ public String mapParameterName(final String owner, final String methodName, fina
81104 .orElse (paramName );
82105 }
83106
84- @ Override
85- public Object mapValue (final Object value ) {
86- if (value instanceof Handle ) {
87- // Backport of ASM!327 https://gitlab.ow2.org/asm/asm/-/merge_requests/327
88- final Handle handle = (Handle ) value ;
89- final boolean isFieldHandle = handle .getTag () <= Opcodes .H_PUTSTATIC ;
90-
91- return new Handle (
92- handle .getTag (),
93- this .mapType (handle .getOwner ()),
94- isFieldHandle
95- ? this .mapFieldName (handle .getOwner (), handle .getName (), handle .getDesc ())
96- : this .mapMethodName (handle .getOwner (), handle .getName (), handle .getDesc ()),
97- isFieldHandle ? this .mapDesc (handle .getDesc ()) : this .mapMethodDesc (handle .getDesc ()),
98- handle .isInterface ());
99- } else {
100- return super .mapValue (value );
101- }
102- }
103-
104107 private Optional <MClass > getClass (String cls ) {
105108 if (cls == null || cls .charAt (0 ) == '[' ) // Enums values() function invokes 'clone' on the array type.
106109 return Optional .empty (); // I'm pretty sure that i'd require stupid hacky JVM to allow native array methods to be remapped.
@@ -142,6 +145,7 @@ private class MClass {
142145 private final Collection <Optional <MField >> fieldsView = Collections .unmodifiableCollection (fields .values ());
143146 private final Map <String , Optional <MMethod >> methods = new ConcurrentHashMap <>();
144147 private final Collection <Optional <MMethod >> methodsView = Collections .unmodifiableCollection (methods .values ());
148+ private final Map <String , Optional <List <MMethod >>> methodsByName = new ConcurrentHashMap <>();
145149
146150 MClass (IClassInfo icls , IMappingFile .IClass mcls ) {
147151 if (icls == null && mcls == null )
@@ -329,6 +333,19 @@ public Optional<MMethod> getMethod(String name, String desc) {
329333 return this .methods .computeIfAbsent (name + desc , k -> Optional .empty ());
330334 }
331335
336+ Optional <List <MMethod >> getMethods (String name ) {
337+ return this .methodsByName .computeIfAbsent (name , k -> {
338+ List <MMethod > mtds = new ArrayList <>();
339+ for (Optional <MMethod > opt : this .getMethods ()) {
340+ MMethod mtd = opt .orElse (null );
341+ if (mtd == null || !k .equals (mtd .getName ()))
342+ continue ;
343+ mtds .add (mtd );
344+ }
345+ return mtds .isEmpty () ? Optional .<List <MMethod >>empty () : Optional .of (mtds );
346+ });
347+ }
348+
332349 @ Override
333350 public String toString () {
334351 return getName ();
0 commit comments