122 lines
5.1 KiB
Java
122 lines
5.1 KiB
Java
/*
|
|
* Minecraft Forge
|
|
* Copyright (c) 2016-2018.
|
|
*
|
|
* This library is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
* License as published by the Free Software Foundation version 2.1
|
|
* of the License.
|
|
*
|
|
* This library is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
* Lesser General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
* License along with this library; if not, write to the Free Software
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
*/
|
|
|
|
package net.minecraftforge.fml.common.asm.deobf;
|
|
|
|
import org.objectweb.asm.ClassVisitor;
|
|
import org.objectweb.asm.FieldVisitor;
|
|
import org.objectweb.asm.Handle;
|
|
import org.objectweb.asm.MethodVisitor;
|
|
import org.objectweb.asm.Opcodes;
|
|
import org.objectweb.asm.Type;
|
|
import org.objectweb.asm.commons.Remapper;
|
|
import org.objectweb.asm.commons.RemappingClassAdapter;
|
|
import org.objectweb.asm.commons.RemappingMethodAdapter;
|
|
|
|
import java.util.Arrays;
|
|
import java.util.List;
|
|
|
|
public class FMLRemappingAdapter extends RemappingClassAdapter {
|
|
public FMLRemappingAdapter(ClassVisitor cv)
|
|
{
|
|
super(cv, FMLDeobfuscatingRemapper.INSTANCE);
|
|
}
|
|
|
|
private static final List<Handle> META_FACTORIES = Arrays.asList(
|
|
new Handle(Opcodes.H_INVOKESTATIC, "java/lang/invoke/LambdaMetafactory", "metafactory",
|
|
"(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;",
|
|
false),
|
|
new Handle(Opcodes.H_INVOKESTATIC, "java/lang/invoke/LambdaMetafactory", "altMetafactory",
|
|
"(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;[Ljava/lang/Object;)Ljava/lang/invoke/CallSite;",
|
|
false)
|
|
);
|
|
|
|
@Override
|
|
public void visit(int version, int access, String name, String signature, String superName, String[] interfaces)
|
|
{
|
|
if (interfaces == null)
|
|
{
|
|
interfaces = new String[0];
|
|
}
|
|
FMLDeobfuscatingRemapper.INSTANCE.mergeSuperMaps(name, superName, interfaces);
|
|
super.visit(version, access, name, signature, superName, interfaces);
|
|
}
|
|
|
|
@Override
|
|
public FieldVisitor visitField(int access, String name, String desc, String signature, Object value) {
|
|
FMLDeobfuscatingRemapper remapper = FMLDeobfuscatingRemapper.INSTANCE;
|
|
FieldVisitor fv = cv.visitField(access,
|
|
remapper.mapMemberFieldName(className, name, desc),
|
|
remapper.mapDesc(desc), remapper.mapSignature(signature, true),
|
|
remapper.mapValue(value));
|
|
return createRemappingFieldAdapter(fv);
|
|
}
|
|
|
|
@Override
|
|
protected MethodVisitor createRemappingMethodAdapter(int access, String newDesc, MethodVisitor mv)
|
|
{
|
|
return new StaticFixingMethodVisitor(access, newDesc, mv, remapper);
|
|
}
|
|
|
|
private static class StaticFixingMethodVisitor extends RemappingMethodAdapter
|
|
{
|
|
|
|
public StaticFixingMethodVisitor(int access, String desc, MethodVisitor mv, Remapper remapper)
|
|
{
|
|
super(access, desc, mv, remapper);
|
|
}
|
|
|
|
@Override
|
|
public void visitFieldInsn(int opcode, String originalType, String originalName, String desc)
|
|
{
|
|
// This method solves the problem of a static field reference changing type. In all probability it is a
|
|
// compatible change, however we need to fix up the desc to point at the new type
|
|
String type = remapper.mapType(originalType);
|
|
String fieldName = remapper.mapFieldName(originalType, originalName, desc);
|
|
String newDesc = remapper.mapDesc(desc);
|
|
if (opcode == Opcodes.GETSTATIC && type.startsWith("net/minecraft/") && newDesc.startsWith("Lnet/minecraft/"))
|
|
{
|
|
String replDesc = FMLDeobfuscatingRemapper.INSTANCE.getStaticFieldType(originalType, originalName, type, fieldName);
|
|
if (replDesc != null)
|
|
{
|
|
newDesc = remapper.mapDesc(replDesc);
|
|
}
|
|
}
|
|
// super.super
|
|
if (mv != null) {
|
|
mv.visitFieldInsn(opcode, type, fieldName, newDesc);
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public void visitInvokeDynamicInsn(String name, String desc, Handle bsm, Object... bsmArgs)
|
|
{
|
|
// Special case lambda metaFactory to get new name
|
|
if (META_FACTORIES.contains(bsm))
|
|
{
|
|
String owner = Type.getReturnType(desc).getInternalName();
|
|
String odesc = ((Type) bsmArgs[0]).getDescriptor(); // First constant argument is "samMethodType - Signature and return type of method to be implemented by the function object."
|
|
name = remapper.mapMethodName(owner, name, odesc);
|
|
}
|
|
|
|
super.visitInvokeDynamicInsn(name, desc, bsm, bsmArgs);
|
|
}
|
|
}
|
|
}
|