diff --git a/src/main/java/net/fabricmc/tinyremapper/extension/mixin/common/data/Annotation.java b/src/main/java/net/fabricmc/tinyremapper/extension/mixin/common/data/Annotation.java index 514809d7..39b01d0a 100644 --- a/src/main/java/net/fabricmc/tinyremapper/extension/mixin/common/data/Annotation.java +++ b/src/main/java/net/fabricmc/tinyremapper/extension/mixin/common/data/Annotation.java @@ -71,4 +71,6 @@ public final class Annotation { public static final String MIXIN_EXTRAS_WRAP_OPERATION = "Lcom/llamalad7/mixinextras/injector/wrapoperation/WrapOperation;"; public static final String MIXIN_EXTRAS_WRAP_WITH_CONDITION = "Lcom/llamalad7/mixinextras/injector/WrapWithCondition;"; public static final String MIXIN_EXTRAS_WRAP_WITH_CONDITION_V2 = "Lcom/llamalad7/mixinextras/injector/v2/WrapWithCondition;"; + public static final String MIXIN_EXTRAS_DEFINITIONS = "Lcom/llamalad7/mixinextras/expression/Definitions;"; + public static final String MIXIN_EXTRAS_DEFINITION = "Lcom/llamalad7/mixinextras/expression/Definition;"; } diff --git a/src/main/java/net/fabricmc/tinyremapper/extension/mixin/common/data/AnnotationElement.java b/src/main/java/net/fabricmc/tinyremapper/extension/mixin/common/data/AnnotationElement.java index 6e69a2ac..e2c60408 100644 --- a/src/main/java/net/fabricmc/tinyremapper/extension/mixin/common/data/AnnotationElement.java +++ b/src/main/java/net/fabricmc/tinyremapper/extension/mixin/common/data/AnnotationElement.java @@ -34,4 +34,6 @@ public final class AnnotationElement { public static final String TO = "to"; public static final String SLICE = "slice"; public static final String METHOD = "method"; + public static final String DEFINITION_METHOD = "method"; + public static final String DEFINITION_FIELD = "field"; } diff --git a/src/main/java/net/fabricmc/tinyremapper/extension/mixin/soft/SoftTargetMixinMethodVisitor.java b/src/main/java/net/fabricmc/tinyremapper/extension/mixin/soft/SoftTargetMixinMethodVisitor.java index 3991cbe4..75148c63 100644 --- a/src/main/java/net/fabricmc/tinyremapper/extension/mixin/soft/SoftTargetMixinMethodVisitor.java +++ b/src/main/java/net/fabricmc/tinyremapper/extension/mixin/soft/SoftTargetMixinMethodVisitor.java @@ -30,6 +30,8 @@ import net.fabricmc.tinyremapper.extension.mixin.common.data.MxMember; import net.fabricmc.tinyremapper.extension.mixin.soft.annotation.AccessorAnnotationVisitor; import net.fabricmc.tinyremapper.extension.mixin.soft.annotation.InvokerAnnotationVisitor; +import net.fabricmc.tinyremapper.extension.mixin.soft.annotation.injection.DefinitionAnnotationVisitor; +import net.fabricmc.tinyremapper.extension.mixin.soft.annotation.injection.DefinitionsAnnotationVisitor; import net.fabricmc.tinyremapper.extension.mixin.soft.annotation.injection.InjectAnnotationVisitor; import net.fabricmc.tinyremapper.extension.mixin.soft.annotation.injection.ModifyArgAnnotationVisitor; import net.fabricmc.tinyremapper.extension.mixin.soft.annotation.injection.ModifyArgsAnnotationVisitor; @@ -62,36 +64,41 @@ class SoftTargetMixinMethodVisitor extends MethodVisitor { public AnnotationVisitor visitAnnotation(String descriptor, boolean visible) { AnnotationVisitor av = super.visitAnnotation(descriptor, visible); - if (Annotation.ACCESSOR.equals(descriptor)) { - av = new AccessorAnnotationVisitor(data, av, method, targets); - } else if (Annotation.INVOKER.equals(descriptor)) { - av = new InvokerAnnotationVisitor(data, av, method, targets); - } else if (Annotation.INJECT.equals(descriptor)) { - av = new InjectAnnotationVisitor(data, av, targets); - } else if (Annotation.MODIFY_ARG.equals(descriptor)) { - av = new ModifyArgAnnotationVisitor(data, av, targets); - } else if (Annotation.MODIFY_ARGS.equals(descriptor)) { - av = new ModifyArgsAnnotationVisitor(data, av, targets); - } else if (Annotation.MODIFY_CONSTANT.equals(descriptor)) { - av = new ModifyConstantAnnotationVisitor(data, av, targets); - } else if (Annotation.MODIFY_VARIABLE.equals(descriptor)) { - av = new ModifyVariableAnnotationVisitor(data, av, targets); - } else if (Annotation.REDIRECT.equals(descriptor)) { - av = new RedirectAnnotationVisitor(data, av, targets); - } else if (Annotation.MIXIN_EXTRAS_MODIFY_EXPRESSION_VALUE.equals(descriptor)) { - av = new ModifyExpressionValueAnnotationVisitor(data, av, targets); - } else if (Annotation.MIXIN_EXTRAS_MODIFY_RECEIVER.equals(descriptor)) { - av = new ModifyReceiverAnnotationVisitor(data, av, targets); - } else if (Annotation.MIXIN_EXTRAS_MODIFY_RETURN_VALUE.equals(descriptor)) { - av = new ModifyReturnValueAnnotationVisitor(data, av, targets); - } else if (Annotation.MIXIN_EXTRAS_WRAP_METHOD.equals(descriptor)) { - av = new WrapMethodAnnotationVisitor(data, av, targets); - } else if (Annotation.MIXIN_EXTRAS_WRAP_OPERATION.equals(descriptor)) { - av = new WrapOperationAnnotationVisitor(data, av, targets); - } else if (Annotation.MIXIN_EXTRAS_WRAP_WITH_CONDITION.equals(descriptor)) { - av = new WrapWithConditionAnnotationVisitor(data, av, targets); - } else if (Annotation.MIXIN_EXTRAS_WRAP_WITH_CONDITION_V2.equals(descriptor)) { - av = new WrapWithConditionV2AnnotationVisitor(data, av, targets); + switch (descriptor) { + case Annotation.ACCESSOR: + return new AccessorAnnotationVisitor(data, av, method, targets); + case Annotation.INVOKER: + return new InvokerAnnotationVisitor(data, av, method, targets); + case Annotation.INJECT: + return new InjectAnnotationVisitor(data, av, targets); + case Annotation.MODIFY_ARG: + return new ModifyArgAnnotationVisitor(data, av, targets); + case Annotation.MODIFY_ARGS: + return new ModifyArgsAnnotationVisitor(data, av, targets); + case Annotation.MODIFY_CONSTANT: + return new ModifyConstantAnnotationVisitor(data, av, targets); + case Annotation.MODIFY_VARIABLE: + return new ModifyVariableAnnotationVisitor(data, av, targets); + case Annotation.REDIRECT: + return new RedirectAnnotationVisitor(data, av, targets); + case Annotation.MIXIN_EXTRAS_MODIFY_EXPRESSION_VALUE: + return new ModifyExpressionValueAnnotationVisitor(data, av, targets); + case Annotation.MIXIN_EXTRAS_MODIFY_RECEIVER: + return new ModifyReceiverAnnotationVisitor(data, av, targets); + case Annotation.MIXIN_EXTRAS_MODIFY_RETURN_VALUE: + return new ModifyReturnValueAnnotationVisitor(data, av, targets); + case Annotation.MIXIN_EXTRAS_WRAP_METHOD: + return new WrapMethodAnnotationVisitor(data, av, targets); + case Annotation.MIXIN_EXTRAS_WRAP_OPERATION: + return new WrapOperationAnnotationVisitor(data, av, targets); + case Annotation.MIXIN_EXTRAS_WRAP_WITH_CONDITION: + return new WrapWithConditionAnnotationVisitor(data, av, targets); + case Annotation.MIXIN_EXTRAS_WRAP_WITH_CONDITION_V2: + return new WrapWithConditionV2AnnotationVisitor(data, av, targets); + case Annotation.MIXIN_EXTRAS_DEFINITIONS: + return new DefinitionsAnnotationVisitor(data, av); + case Annotation.MIXIN_EXTRAS_DEFINITION: + return new DefinitionAnnotationVisitor(data, av); } return av; diff --git a/src/main/java/net/fabricmc/tinyremapper/extension/mixin/soft/annotation/injection/AtAnnotationVisitor.java b/src/main/java/net/fabricmc/tinyremapper/extension/mixin/soft/annotation/injection/AtAnnotationVisitor.java index 93c9fa0a..1c3b8260 100644 --- a/src/main/java/net/fabricmc/tinyremapper/extension/mixin/soft/annotation/injection/AtAnnotationVisitor.java +++ b/src/main/java/net/fabricmc/tinyremapper/extension/mixin/soft/annotation/injection/AtAnnotationVisitor.java @@ -19,19 +19,15 @@ package net.fabricmc.tinyremapper.extension.mixin.soft.annotation.injection; import java.util.Objects; -import java.util.Optional; import org.objectweb.asm.AnnotationVisitor; import org.objectweb.asm.tree.AnnotationNode; -import net.fabricmc.tinyremapper.api.TrMember; import net.fabricmc.tinyremapper.extension.mixin.common.IMappable; -import net.fabricmc.tinyremapper.extension.mixin.common.ResolveUtility; import net.fabricmc.tinyremapper.extension.mixin.common.data.Annotation; import net.fabricmc.tinyremapper.extension.mixin.common.data.AnnotationElement; import net.fabricmc.tinyremapper.extension.mixin.common.data.CommonData; import net.fabricmc.tinyremapper.extension.mixin.common.data.Constant; -import net.fabricmc.tinyremapper.extension.mixin.common.data.Message; import net.fabricmc.tinyremapper.extension.mixin.soft.data.MemberInfo; /** @@ -87,7 +83,7 @@ public void visit(String name, Object value) { if (this.value.equals("NEW")) { value = new AtConstructorMappable(data, info).result().toString(); } else { - value = new AtMethodMappable(data, info).result().toString(); + value = new AtMemberMappable(data, info).result().toString(); } } } @@ -122,36 +118,6 @@ public void visit(String name, Object value) { } } - private static class AtMethodMappable implements IMappable { - private final CommonData data; - private final MemberInfo info; - - AtMethodMappable(CommonData data, MemberInfo info) { - this.data = Objects.requireNonNull(data); - this.info = Objects.requireNonNull(info); - } - - @Override - public MemberInfo result() { - if (!info.isFullyQualified()) { - data.getLogger().warn(Message.NOT_FULLY_QUALIFIED, info); - return info; - } - - Optional resolved = data.resolver.resolveMember(info.getOwner(), info.getName(), info.getDesc(), ResolveUtility.FLAG_UNIQUE | ResolveUtility.FLAG_RECURSIVE); - - if (resolved.isPresent()) { - String newOwner = data.mapper.asTrRemapper().map(info.getOwner()); - String newName = data.mapper.mapName(resolved.get()); - String newDesc = data.mapper.mapDesc(resolved.get()); - - return new MemberInfo(newOwner, newName, info.getQuantifier(), newDesc); - } else { - return info; - } - } - } - private static class AtConstructorMappable implements IMappable { private final CommonData data; private final MemberInfo info; diff --git a/src/main/java/net/fabricmc/tinyremapper/extension/mixin/soft/annotation/injection/AtMemberMappable.java b/src/main/java/net/fabricmc/tinyremapper/extension/mixin/soft/annotation/injection/AtMemberMappable.java new file mode 100644 index 00000000..7ad23ed1 --- /dev/null +++ b/src/main/java/net/fabricmc/tinyremapper/extension/mixin/soft/annotation/injection/AtMemberMappable.java @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2016, 2018, Player, asie + * Copyright (c) 2025, FabricMC + * + * This program 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, either version 3 of the License, or + * (at your option) any later version. + * + * This program 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 program. If not, see . + */ + +package net.fabricmc.tinyremapper.extension.mixin.soft.annotation.injection; + +import java.util.Objects; +import java.util.Optional; + +import net.fabricmc.tinyremapper.api.TrMember; +import net.fabricmc.tinyremapper.extension.mixin.common.IMappable; +import net.fabricmc.tinyremapper.extension.mixin.common.ResolveUtility; +import net.fabricmc.tinyremapper.extension.mixin.common.data.CommonData; +import net.fabricmc.tinyremapper.extension.mixin.common.data.Message; +import net.fabricmc.tinyremapper.extension.mixin.soft.data.MemberInfo; + +class AtMemberMappable implements IMappable { + private final CommonData data; + private final MemberInfo info; + + AtMemberMappable(CommonData data, MemberInfo info) { + this.data = Objects.requireNonNull(data); + this.info = Objects.requireNonNull(info); + } + + @Override + public MemberInfo result() { + if (!info.isFullyQualified()) { + data.getLogger().warn(Message.NOT_FULLY_QUALIFIED, info); + return info; + } + + Optional resolved = data.resolver.resolveMember(info.getOwner(), info.getName(), info.getDesc(), ResolveUtility.FLAG_UNIQUE | ResolveUtility.FLAG_RECURSIVE); + + if (resolved.isPresent()) { + String newOwner = data.mapper.asTrRemapper().map(info.getOwner()); + String newName = data.mapper.mapName(resolved.get()); + String newDesc = data.mapper.mapDesc(resolved.get()); + + return new MemberInfo(newOwner, newName, info.getQuantifier(), newDesc); + } else { + return info; + } + } +} diff --git a/src/main/java/net/fabricmc/tinyremapper/extension/mixin/soft/annotation/injection/DefinitionAnnotationVisitor.java b/src/main/java/net/fabricmc/tinyremapper/extension/mixin/soft/annotation/injection/DefinitionAnnotationVisitor.java new file mode 100644 index 00000000..1f9245ec --- /dev/null +++ b/src/main/java/net/fabricmc/tinyremapper/extension/mixin/soft/annotation/injection/DefinitionAnnotationVisitor.java @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2016, 2018, Player, asie + * Copyright (c) 2025, FabricMC + * + * This program 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, either version 3 of the License, or + * (at your option) any later version. + * + * This program 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 program. If not, see . + */ + +package net.fabricmc.tinyremapper.extension.mixin.soft.annotation.injection; + +import java.util.Objects; + +import org.objectweb.asm.AnnotationVisitor; + +import net.fabricmc.tinyremapper.extension.mixin.common.data.AnnotationElement; +import net.fabricmc.tinyremapper.extension.mixin.common.data.CommonData; +import net.fabricmc.tinyremapper.extension.mixin.common.data.Constant; +import net.fabricmc.tinyremapper.extension.mixin.soft.data.MemberInfo; + +public class DefinitionAnnotationVisitor extends AnnotationVisitor { + private final CommonData data; + + public DefinitionAnnotationVisitor(CommonData data, AnnotationVisitor delegate) { + super(Constant.ASM_VERSION, Objects.requireNonNull(delegate)); + + this.data = Objects.requireNonNull(data); + } + + @Override + public AnnotationVisitor visitArray(String name) { + AnnotationVisitor av = super.visitArray(name); + switch (name) { + case AnnotationElement.DEFINITION_METHOD: + case AnnotationElement.DEFINITION_FIELD: + return new MemberRemappingVisitor(data, av); + } + + return av; + } + + private static class MemberRemappingVisitor extends AnnotationVisitor { + private final CommonData data; + + MemberRemappingVisitor(CommonData data, AnnotationVisitor delegate) { + super(Constant.ASM_VERSION, Objects.requireNonNull(delegate)); + + this.data = Objects.requireNonNull(data); + } + + @Override + public void visit(String name, Object value) { + MemberInfo info = MemberInfo.parse(Objects.requireNonNull((String) value)); + + if (info != null) { + value = new AtMemberMappable(data, info).result().toString(); + } + + super.visit(name, value); + } + } +} diff --git a/src/main/java/net/fabricmc/tinyremapper/extension/mixin/soft/annotation/injection/DefinitionsAnnotationVisitor.java b/src/main/java/net/fabricmc/tinyremapper/extension/mixin/soft/annotation/injection/DefinitionsAnnotationVisitor.java new file mode 100644 index 00000000..c696a9b6 --- /dev/null +++ b/src/main/java/net/fabricmc/tinyremapper/extension/mixin/soft/annotation/injection/DefinitionsAnnotationVisitor.java @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2016, 2018, Player, asie + * Copyright (c) 2025, FabricMC + * + * This program 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, either version 3 of the License, or + * (at your option) any later version. + * + * This program 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 program. If not, see . + */ + +package net.fabricmc.tinyremapper.extension.mixin.soft.annotation.injection; + +import java.util.Objects; + +import org.objectweb.asm.AnnotationVisitor; + +import net.fabricmc.tinyremapper.extension.mixin.common.data.AnnotationElement; +import net.fabricmc.tinyremapper.extension.mixin.common.data.CommonData; +import net.fabricmc.tinyremapper.extension.mixin.common.data.Constant; + +public class DefinitionsAnnotationVisitor extends AnnotationVisitor { + private final CommonData data; + + public DefinitionsAnnotationVisitor(CommonData data, AnnotationVisitor delegate) { + super(Constant.ASM_VERSION, Objects.requireNonNull(delegate)); + + this.data = Objects.requireNonNull(data); + } + + @Override + public AnnotationVisitor visitArray(String name) { + AnnotationVisitor av = super.visitArray(name); + + if (name.equals(AnnotationElement.VALUE)) { + return new DefinitionRemappingVisitor(data, av); + } + + return av; + } + + private static class DefinitionRemappingVisitor extends AnnotationVisitor { + private final CommonData data; + + DefinitionRemappingVisitor(CommonData data, AnnotationVisitor delegate) { + super(Constant.ASM_VERSION, Objects.requireNonNull(delegate)); + + this.data = Objects.requireNonNull(data); + } + + @Override + public AnnotationVisitor visitAnnotation(String name, String descriptor) { + return new DefinitionAnnotationVisitor(data, super.visitAnnotation(name, descriptor)); + } + } +}