aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/ftbsc/lll/mapper/tools/MappingUtils.java
blob: fcc552595564c4806f5e28da3ef735ad1c073db5 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
package ftbsc.lll.mapper.tools;

import ftbsc.lll.exceptions.MappingNotFoundException;
import ftbsc.lll.mapper.IMapper;
import ftbsc.lll.tools.DescriptorBuilder;
import org.objectweb.asm.Type;

/**
 * A collection of static utility methods correlated to
 * mappers.
 */
public class MappingUtils {

   /**
    * Maps a method descriptor, replacing its class references with their mapped counterparts.
    * @param descriptor a {@link String} containing the descriptor
    * @param mapper the {@link IMapper} to use for the process
    * @param reverse if true it uses the inverted mapper rather than the normal one
    * @return the mapped descriptor
    */
   public static String mapMethodDescriptor(String descriptor, IMapper mapper, boolean reverse) {
      Type method = Type.getMethodType(descriptor);
      Type[] arguments = method.getArgumentTypes();
      Type returnType = method.getReturnType();

      Type[] mappedArguents = new Type[arguments.length];
      for(int i = 0; i < mappedArguents.length; i++)
         mappedArguents[i] = mapType(arguments[i], mapper, reverse);

      return Type.getMethodDescriptor(mapType(returnType, mapper, reverse), mappedArguents);
   }

   /**
    * Given a {@link Type} and a valid {@link IMapper} it returns its mapped counterpart.
    * @param type the type in question
    * @param mapper the {@link IMapper} to use for the process
    * @param reverse if true it uses the inverted mapper rather than the normal one
    * @return the mapped type
    */
   public static Type mapType(Type type, IMapper mapper, boolean reverse) {
      //unwrap arrays
      Type unwrapped = type;
      int arrayLevel = 0;
      while(unwrapped.getSort() == Type.ARRAY) {
         unwrapped = unwrapped.getElementType();
         arrayLevel++;
      }

      //if it's a primitive no operation is needed
      if(type.getSort() < Type.ARRAY)
         return type;

      String internalName = type.getInternalName();

      String internalNameMapped;
      try {
         internalNameMapped = reverse
            ? mapper.getInverted().getClassData(internalName).nameMapped
            : mapper.getClassData(internalName).nameMapped;
         return Type.getType(DescriptorBuilder.nameToDescriptor(internalNameMapped, arrayLevel));
      } catch(MappingNotFoundException e) {
         return type;
      }
   }
}