diff --git a/src/main/java/net/fabricmc/tinyremapper/extension/mixin/hard/HardTargetMixinMethodVisitor.java b/src/main/java/net/fabricmc/tinyremapper/extension/mixin/hard/HardTargetMixinMethodVisitor.java
index f7937d01..c4ba2894 100644
--- a/src/main/java/net/fabricmc/tinyremapper/extension/mixin/hard/HardTargetMixinMethodVisitor.java
+++ b/src/main/java/net/fabricmc/tinyremapper/extension/mixin/hard/HardTargetMixinMethodVisitor.java
@@ -30,8 +30,6 @@
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.MxMember;
-import net.fabricmc.tinyremapper.extension.mixin.hard.annotation.AccessorAnnotationVisitor;
-import net.fabricmc.tinyremapper.extension.mixin.hard.annotation.InvokerAnnotationVisitor;
import net.fabricmc.tinyremapper.extension.mixin.hard.annotation.OverwriteAnnotationVisitor;
import net.fabricmc.tinyremapper.extension.mixin.hard.annotation.ShadowAnnotationVisitor;
@@ -57,10 +55,6 @@ public AnnotationVisitor visitAnnotation(String descriptor, boolean visible) {
av = new ShadowAnnotationVisitor(data, av, method, targets);
} else if (Annotation.OVERWRITE.equals(descriptor)) {
av = new OverwriteAnnotationVisitor(data, av, method, targets);
- } else 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);
}
return av;
diff --git a/src/main/java/net/fabricmc/tinyremapper/extension/mixin/hard/annotation/AccessorAnnotationVisitor.java b/src/main/java/net/fabricmc/tinyremapper/extension/mixin/hard/annotation/AccessorAnnotationVisitor.java
deleted file mode 100644
index 49fb5a49..00000000
--- a/src/main/java/net/fabricmc/tinyremapper/extension/mixin/hard/annotation/AccessorAnnotationVisitor.java
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- * Copyright (c) 2016, 2018, Player, asie
- * Copyright (c) 2021, 2023, 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.hard.annotation;
-
-import java.util.Collection;
-import java.util.List;
-import java.util.Objects;
-import java.util.function.Consumer;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-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.common.data.MxMember;
-import net.fabricmc.tinyremapper.extension.mixin.hard.util.CamelPrefixString;
-import net.fabricmc.tinyremapper.extension.mixin.hard.util.ConvertibleMappable;
-import net.fabricmc.tinyremapper.extension.mixin.hard.util.IConvertibleString;
-
-/**
- * In case of multi-target, if a remap conflict is detected,
- * an error message will show up and the behaviour is undefined.
- * If after strip the prefix, all characters are UPPER_CASE, then
- * do not lower the first character of the remaining part.
- */
-public class AccessorAnnotationVisitor extends AnnotationVisitor {
- private final Collection> tasks;
- private final MxMember method;
- private final List targets;
-
- private boolean isSoftTarget;
-
- public AccessorAnnotationVisitor(Collection> tasks, AnnotationVisitor delegate, MxMember method, List targets) {
- super(Constant.ASM_VERSION, delegate);
-
- this.tasks = Objects.requireNonNull(tasks);
- this.method = Objects.requireNonNull(method);
- this.targets = Objects.requireNonNull(targets);
-
- this.isSoftTarget = false;
- }
-
- @Override
- public void visit(String name, Object value) {
- if (name.equals(AnnotationElement.VALUE)) {
- isSoftTarget = true;
- }
-
- super.visit(name, value);
- }
-
- @Override
- public void visitEnd() {
- if (!isSoftTarget) {
- tasks.add(data -> new AccessorMappable(data, method, targets).result());
- }
-
- super.visitEnd();
- }
-
- private static class AccessorMappable extends ConvertibleMappable {
- private final String prefix;
- private final String fieldDesc;
-
- private static final Pattern GETTER_PATTERN = Pattern.compile("(?<=\\(\\)).*");
- private static final Pattern SETTER_PATTERN = Pattern.compile("(?<=\\().*(?=\\)V)");
-
- AccessorMappable(CommonData data, MxMember self, Collection targets) {
- super(data, self, targets);
-
- if (self.getName().startsWith("get")) {
- this.prefix = "get";
- } else if (self.getName().startsWith("set")) {
- this.prefix = "set";
- } else if (self.getName().startsWith("is")) {
- this.prefix = "is";
- } else {
- throw new RuntimeException(String.format("%s does not start with get, set or is.", self.getName()));
- }
-
- Matcher getterMatcher = GETTER_PATTERN.matcher(self.getDesc());
- Matcher setterMatcher = SETTER_PATTERN.matcher(self.getDesc());
-
- if (getterMatcher.find()) {
- this.fieldDesc = getterMatcher.group();
- } else if (setterMatcher.find()) {
- this.fieldDesc = setterMatcher.group();
- } else {
- throw new RuntimeException(String.format("%s is not getter or setter descriptor", self.getDesc()));
- }
- }
-
- @Override
- protected IConvertibleString getName() {
- return new CamelPrefixString(prefix, self.getName());
- }
-
- @Override
- protected String getDesc() {
- return fieldDesc;
- }
- }
-}
diff --git a/src/main/java/net/fabricmc/tinyremapper/extension/mixin/hard/annotation/InvokerAnnotationVisitor.java b/src/main/java/net/fabricmc/tinyremapper/extension/mixin/hard/annotation/InvokerAnnotationVisitor.java
deleted file mode 100644
index c3e835ea..00000000
--- a/src/main/java/net/fabricmc/tinyremapper/extension/mixin/hard/annotation/InvokerAnnotationVisitor.java
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * Copyright (c) 2016, 2018, Player, asie
- * Copyright (c) 2021, 2023, 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.hard.annotation;
-
-import java.util.Collection;
-import java.util.List;
-import java.util.Objects;
-import java.util.function.Consumer;
-
-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.common.data.MxMember;
-import net.fabricmc.tinyremapper.extension.mixin.hard.util.CamelPrefixString;
-import net.fabricmc.tinyremapper.extension.mixin.hard.util.ConvertibleMappable;
-import net.fabricmc.tinyremapper.extension.mixin.hard.util.IConvertibleString;
-
-/**
- * In case of multi-target, if a remap conflict is detected,
- * an error message will show up and the behaviour is undefined.
- * If after strip the prefix, all characters are UPPER_CASE, then
- * do not lower the first character of the remaining part.
- */
-public class InvokerAnnotationVisitor extends AnnotationVisitor {
- private final Collection> tasks;
- private final MxMember method;
- private final List targets;
-
- private boolean isSoftTarget;
-
- public InvokerAnnotationVisitor(Collection> tasks, AnnotationVisitor delegate, MxMember method, List targets) {
- super(Constant.ASM_VERSION, delegate);
-
- this.tasks = Objects.requireNonNull(tasks);
- this.method = Objects.requireNonNull(method);
- this.targets = Objects.requireNonNull(targets);
-
- this.isSoftTarget = false;
- }
-
- @Override
- public void visit(String name, Object value) {
- if (name.equals(AnnotationElement.VALUE)) {
- isSoftTarget = true;
- }
-
- super.visit(name, value);
- }
-
- @Override
- public void visitEnd() {
- if (!isSoftTarget) {
- tasks.add(data -> new InvokerMappable(data, method, targets).result());
- }
-
- super.visitEnd();
- }
-
- private static class InvokerMappable extends ConvertibleMappable {
- private final String prefix;
-
- InvokerMappable(CommonData data, MxMember self, Collection targets) {
- super(data, self, targets);
-
- if (self.getName().startsWith("call")) {
- this.prefix = "call";
- } else if (self.getName().startsWith("invoke")) {
- this.prefix = "invoke";
- } else if (self.getName().startsWith("new")) {
- this.prefix = "new";
- } else if (self.getName().startsWith("create")) {
- this.prefix = "create";
- } else {
- throw new RuntimeException(String.format("%s does not start with call or invoke.", self.getName()));
- }
- }
-
- @Override
- protected IConvertibleString getName() {
- return new CamelPrefixString(prefix, self.getName());
- }
-
- @Override
- protected String getDesc() {
- return self.getDesc();
- }
- }
-}
diff --git a/src/main/java/net/fabricmc/tinyremapper/extension/mixin/soft/annotation/AccessorAnnotationVisitor.java b/src/main/java/net/fabricmc/tinyremapper/extension/mixin/soft/annotation/AccessorAnnotationVisitor.java
index 52ed794b..fe31893e 100644
--- a/src/main/java/net/fabricmc/tinyremapper/extension/mixin/soft/annotation/AccessorAnnotationVisitor.java
+++ b/src/main/java/net/fabricmc/tinyremapper/extension/mixin/soft/annotation/AccessorAnnotationVisitor.java
@@ -25,6 +25,7 @@
import org.objectweb.asm.AnnotationVisitor;
+import net.fabricmc.tinyremapper.extension.mixin.common.StringUtility;
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;
@@ -38,9 +39,12 @@
public class AccessorAnnotationVisitor extends AnnotationVisitor {
private final CommonData data;
+ private final MxMember method;
private final List targets;
private final String fieldDesc;
+ private boolean isSoftTarget;
+
private static final Pattern GETTER_PATTERN = Pattern.compile("(?<=\\(\\)).*");
private static final Pattern SETTER_PATTERN = Pattern.compile("(?<=\\().*(?=\\)V)");
@@ -50,6 +54,7 @@ public AccessorAnnotationVisitor(CommonData data, AnnotationVisitor delegate, Mx
this.data = Objects.requireNonNull(data);
Objects.requireNonNull(method);
+ this.method = method;
this.targets = Objects.requireNonNull(targets);
Matcher getterMatcher = GETTER_PATTERN.matcher(method.getDesc());
@@ -67,11 +72,41 @@ public AccessorAnnotationVisitor(CommonData data, AnnotationVisitor delegate, Mx
@Override
public void visit(String name, Object value) {
if (name.equals(AnnotationElement.VALUE)) {
+ isSoftTarget = true;
String fieldName = Objects.requireNonNull((String) value);
-
- value = new NamedMappable(data, fieldName, fieldDesc, targets).result();
+ setAnnotationValue(fieldName);
+ return;
}
super.visit(name, value);
}
+
+ @Override
+ public void visitEnd() {
+ if (!isSoftTarget) {
+ setAnnotationValue(inferFieldName());
+ }
+
+ super.visitEnd();
+ }
+
+ private void setAnnotationValue(String fieldName) {
+ super.visit(AnnotationElement.VALUE, new NamedMappable(data, fieldName, fieldDesc, targets).result());
+ }
+
+ private String inferFieldName() {
+ String prefix;
+
+ if (method.getName().startsWith("get")) {
+ prefix = "get";
+ } else if (method.getName().startsWith("set")) {
+ prefix = "set";
+ } else if (method.getName().startsWith("is")) {
+ prefix = "is";
+ } else {
+ throw new RuntimeException(String.format("%s does not start with get, set or is.", method.getName()));
+ }
+
+ return StringUtility.removeCamelPrefix(prefix, method.getName());
+ }
}
diff --git a/src/main/java/net/fabricmc/tinyremapper/extension/mixin/soft/annotation/InvokerAnnotationVisitor.java b/src/main/java/net/fabricmc/tinyremapper/extension/mixin/soft/annotation/InvokerAnnotationVisitor.java
index ead0c50b..d415a6df 100644
--- a/src/main/java/net/fabricmc/tinyremapper/extension/mixin/soft/annotation/InvokerAnnotationVisitor.java
+++ b/src/main/java/net/fabricmc/tinyremapper/extension/mixin/soft/annotation/InvokerAnnotationVisitor.java
@@ -23,6 +23,7 @@
import org.objectweb.asm.AnnotationVisitor;
+import net.fabricmc.tinyremapper.extension.mixin.common.StringUtility;
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;
@@ -39,6 +40,8 @@ public class InvokerAnnotationVisitor extends AnnotationVisitor {
private final List targets;
+ private boolean isSoftTarget;
+
public InvokerAnnotationVisitor(CommonData data, AnnotationVisitor delegate, MxMember method, List targets) {
super(Constant.ASM_VERSION, Objects.requireNonNull(delegate));
@@ -51,12 +54,49 @@ public InvokerAnnotationVisitor(CommonData data, AnnotationVisitor delegate, MxM
@Override
public void visit(String name, Object value) {
if (name.equals(AnnotationElement.VALUE)) {
+ isSoftTarget = true;
String methodName = Objects.requireNonNull((String) value);
- String methodDesc = method.getDesc();
- value = new NamedMappable(data, methodName, methodDesc, targets).result();
+ setAnnotationValue(methodName);
+ return;
}
super.visit(name, value);
}
+
+ @Override
+ public void visitEnd() {
+ if (!isSoftTarget) {
+ String inferredName = inferMethodName();
+
+ if (inferredName != null) {
+ setAnnotationValue(inferredName);
+ }
+ }
+
+ super.visitEnd();
+ }
+
+ private void setAnnotationValue(String methodName) {
+ super.visit(AnnotationElement.VALUE, new NamedMappable(data, methodName, method.getDesc(), targets).result());
+ }
+
+ private String inferMethodName() {
+ if (method.getName().startsWith("new") || method.getName().startsWith("create")) {
+ // The rest of the name isn't important, leave it as-is
+ return null;
+ }
+
+ String prefix;
+
+ if (method.getName().startsWith("call")) {
+ prefix = "call";
+ } else if (method.getName().startsWith("invoke")) {
+ prefix = "invoke";
+ } else {
+ throw new RuntimeException(String.format("%s does not start with call or invoke.", method.getName()));
+ }
+
+ return StringUtility.removeCamelPrefix(prefix, method.getName());
+ }
}