From 9a052d86a8c1b4496ea63601cc7038fd384be429 Mon Sep 17 00:00:00 2001 From: Su5eD Date: Fri, 17 May 2024 20:55:38 +0200 Subject: [PATCH] Improve mixin compatibility --- .github/workflows/build.yml | 10 +++---- .github/workflows/publish.yml | 17 ++++++------ build.gradle | 27 +++++++++++-------- gradle/wrapper/gradle-wrapper.properties | 2 +- settings.gradle | 3 +-- .../mercury/mixin/MixinRemapperVisitor.java | 24 +++++++++++++---- .../mercury/mixin/annotation/AtData.java | 21 +++++++++++++-- .../mercury/mixin/util/MixinConstants.java | 5 ++++ 8 files changed, 75 insertions(+), 34 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 293a2f6..e43e28e 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -12,15 +12,15 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 - - name: Set up JDK 1.8 - uses: actions/setup-java@v1 + - name: Set up JDK 17 + uses: actions/setup-java@v4 with: - java-version: 8 + java-version: 17 - name: Verify Gradle Wrapper - uses: gradle/wrapper-validation-action@v1 + uses: gradle/actions/wrapper-validation@v3 - name: Build with Gradle run: ./gradlew build diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 579f7dd..659df38 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -10,21 +10,22 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 - - name: Set up JDK 1.8 - uses: actions/setup-java@v1 + - name: Set up JDK 17 + uses: actions/setup-java@v4 with: - java-version: 8 + java-version: 17 - name: Verify Gradle Wrapper - uses: gradle/wrapper-validation-action@v1 + uses: gradle/actions/wrapper-validation@v3 - name: Build with Gradle run: ./gradlew build - - name: Publish to Sonatype + - name: Publish to Maven run: ./gradlew publish env: - ORG_GRADLE_PROJECT_ossrhUsername: ${{ secrets.ORG_GRADLE_PROJECT_ossrhUsername }} - ORG_GRADLE_PROJECT_ossrhPassword: ${{ secrets.ORG_GRADLE_PROJECT_ossrhPassword }} + MAVEN_URL: ${{ secrets.MAVEN_URL }} + MAVEN_USERNAME: ${{ secrets.MAVEN_USERNAME }} + MAVEN_PASSWORD: ${{ secrets.MAVEN_PASSWORD }} diff --git a/build.gradle b/build.gradle index a32bd07..3ff7fe0 100644 --- a/build.gradle +++ b/build.gradle @@ -3,22 +3,26 @@ plugins { id 'maven-publish' id 'net.minecrell.licenser' version '0.4.1' + id 'com.github.johnrengelman.shadow' version '8.1.1' } java { - sourceCompatibility = JavaVersion.VERSION_1_8 - targetCompatibility = JavaVersion.VERSION_1_8 + sourceCompatibility = JavaVersion.VERSION_17 + targetCompatibility = JavaVersion.VERSION_17 withJavadocJar() withSourcesJar() } -group = 'org.cadixdev' +group = 'org.sinytra' archivesBaseName = project.name.toLowerCase() -version = '0.1.0-SNAPSHOT' +version = '0.2.0-SNAPSHOT' repositories { mavenCentral() + maven { + url = 'https://maven.fabricmc.net' + } if (mercuryVersion.endsWith("-SNAPSHOT")) { maven { url 'https://oss.sonatype.org/content/groups/public/' @@ -32,6 +36,11 @@ dependencies { testImplementation 'org.junit.jupiter:junit-jupiter:5.6.2' } +shadowJar { + configurations = [] + relocate 'org.eclipse', 'org.cadixdev.mercury.shadow.org.eclipse' +} + test { useJUnitPlatform() } @@ -91,15 +100,11 @@ publishing { } } repositories { - if (project.hasProperty('ossrhUsername') && project.hasProperty('ossrhPassword')) { + if (System.getenv("MAVEN_URL") != null) { maven { - url = !version.endsWith('-SNAPSHOT') ? - 'https://oss.sonatype.org/service/local/staging/deploy/maven2/' : - 'https://oss.sonatype.org/content/repositories/snapshots/' - credentials { - username = ossrhUsername - password = ossrhPassword + username System.getenv("MAVEN_USERNAME") + password System.getenv("MAVEN_PASSWORD") } } } diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 4c5803d..48c0a02 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-6.4-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/settings.gradle b/settings.gradle index ae239c6..c21fa54 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1,2 +1 @@ -rootProject.name = name - +rootProject.name = 'mercury-mixin' \ No newline at end of file diff --git a/src/main/java/org/cadixdev/mercury/mixin/MixinRemapperVisitor.java b/src/main/java/org/cadixdev/mercury/mixin/MixinRemapperVisitor.java index 13e6f81..8079a9b 100644 --- a/src/main/java/org/cadixdev/mercury/mixin/MixinRemapperVisitor.java +++ b/src/main/java/org/cadixdev/mercury/mixin/MixinRemapperVisitor.java @@ -9,6 +9,9 @@ import static org.cadixdev.mercury.mixin.annotation.AccessorType.FIELD_GETTER; import static org.cadixdev.mercury.mixin.util.MixinConstants.ACCESSOR_CLASS; import static org.cadixdev.mercury.mixin.util.MixinConstants.INJECT_CLASS; +import static org.cadixdev.mercury.mixin.util.MixinConstants.MODIFY_ARG_CLASS; +import static org.cadixdev.mercury.mixin.util.MixinConstants.MODIFY_EXPRESSION_VALUE; +import static org.cadixdev.mercury.mixin.util.MixinConstants.WRAP_OPERATION_VALUE; import static org.cadixdev.mercury.mixin.util.MixinConstants.INVOKER_CLASS; import static org.cadixdev.mercury.mixin.util.MixinConstants.MODIFY_CONSTANT_CLASS; import static org.cadixdev.mercury.mixin.util.MixinConstants.MODIFY_VARIABLE_CLASS; @@ -24,9 +27,7 @@ import org.cadixdev.bombe.type.signature.FieldSignature; import org.cadixdev.bombe.type.signature.MethodSignature; import org.cadixdev.lorenz.MappingSet; -import org.cadixdev.lorenz.model.ClassMapping; -import org.cadixdev.lorenz.model.FieldMapping; -import org.cadixdev.lorenz.model.MethodMapping; +import org.cadixdev.lorenz.model.*; import org.cadixdev.mercury.RewriteContext; import org.cadixdev.mercury.analysis.MercuryInheritanceProvider; import org.cadixdev.mercury.mixin.annotation.AccessorData; @@ -62,6 +63,7 @@ import java.util.ArrayList; import java.util.List; import java.util.Objects; +import java.util.Optional; public class MixinRemapperVisitor extends ASTVisitor { @@ -310,7 +312,10 @@ public boolean visit(final MethodDeclaration node) { if (Objects.equals(INJECT_CLASS, annotationType) || Objects.equals(REDIRECT_CLASS, annotationType) || Objects.equals(MODIFY_CONSTANT_CLASS, annotationType) - || Objects.equals(MODIFY_VARIABLE_CLASS, annotationType)) { + || Objects.equals(MODIFY_VARIABLE_CLASS, annotationType) + || Objects.equals(MODIFY_ARG_CLASS, annotationType) + || Objects.equals(WRAP_OPERATION_VALUE, annotationType) + || Objects.equals(MODIFY_EXPRESSION_VALUE, annotationType)) { final InjectData inject = InjectData.from(annotation); // Find target method(s?) @@ -435,7 +440,7 @@ private String remapInjectTarget(final ClassMapping target, final InjectTa .orElse(true)) { final MethodSignature deobfuscatedSignature = mapping.getDeobfuscatedSignature(); - return injectTarget.getMethodDescriptor().isPresent() ? + return shouldIncludeDescriptor(target, mapping, injectTarget.getMethodDescriptor()) ? deobfuscatedSignature.getName() + deobfuscatedSignature.getDescriptor().toString() : deobfuscatedSignature.getName(); } @@ -459,6 +464,12 @@ private String remapInjectTarget(final ClassMapping target, final InjectTa return remappedFull.toString(); } + private boolean shouldIncludeDescriptor(ClassMapping target, MethodMapping mapping, Optional descriptor) { + return descriptor.isPresent() + || target.getMethodMappings().stream().map(Mapping::getDeobfuscatedName).filter(mapping.getDeobfuscatedName()::equals).count() > 1 + && target.getMethodMappings().stream().map(Mapping::getObfuscatedName).filter(mapping.getObfuscatedName()::equals).count() == 1; + } + private void remapSliceAnnotation(final AST ast, final ITypeBinding declaringClass, final NormalAnnotation atAnnotation, final SliceData sliceDatum) { for (final Object raw : atAnnotation.values()) { @@ -505,6 +516,9 @@ private void remapAtAnnotation(final AST ast, final ITypeBinding declaringClass, // it's just the class name replaceExpression(ast, this.context, originalTarget, deobfTargetClass); } + } else if (atDatum.getTarget().isPresent()) { + atDatum.getTarget().get().getMethodDescriptor() + .ifPresent(desc -> replaceExpression(ast, this.context, atRawPair.getValue(), this.mappings.deobfuscate(desc).toString())); } } } diff --git a/src/main/java/org/cadixdev/mercury/mixin/annotation/AtData.java b/src/main/java/org/cadixdev/mercury/mixin/annotation/AtData.java index 142d6b8..a33d17d 100644 --- a/src/main/java/org/cadixdev/mercury/mixin/annotation/AtData.java +++ b/src/main/java/org/cadixdev/mercury/mixin/annotation/AtData.java @@ -11,6 +11,8 @@ import java.util.Objects; import java.util.Optional; +import java.util.regex.Matcher; +import java.util.regex.Pattern; /** * A container for data held in the {@code @At} annotation. @@ -19,6 +21,8 @@ * @since 0.1.0 */ public class AtData { + private static final Pattern DOT_REF_PATTERN = Pattern.compile("([\\w_$/]+)\\.(.*\\(.*?\\).+)"); + private static final Pattern METHOD_REF_PATTERN = Pattern.compile("^(\\(.*?\\).+)$"); // @At(value = "", target = "") public static AtData from(final IAnnotationBinding binding) { @@ -33,14 +37,27 @@ public static AtData from(final IAnnotationBinding binding) { else if (Objects.equals("target", pair.getName())) { final String combined = (String) pair.getValue(); + Matcher methodDescMatcher = METHOD_REF_PATTERN.matcher(combined); + if (methodDescMatcher.matches()) { + className = null; + target = InjectTarget.of(combined); + break; + } + final int semiIndex = combined.indexOf(';'); if (semiIndex >= 0) { className = combined.substring(1, semiIndex); target = InjectTarget.of(combined.substring(semiIndex + 1)); } else { - // it's just the class name, probably a NEW - className = combined; + Matcher matcher = DOT_REF_PATTERN.matcher(combined); + if (matcher.matches()) { + className = matcher.group(1); + target = InjectTarget.of(matcher.group(2)); + } else { + // it's just the class name, probably a NEW + className = combined; + } } } } diff --git a/src/main/java/org/cadixdev/mercury/mixin/util/MixinConstants.java b/src/main/java/org/cadixdev/mercury/mixin/util/MixinConstants.java index 20f1118..a5abc75 100644 --- a/src/main/java/org/cadixdev/mercury/mixin/util/MixinConstants.java +++ b/src/main/java/org/cadixdev/mercury/mixin/util/MixinConstants.java @@ -11,6 +11,7 @@ public final class MixinConstants { public static final String MIXIN_PACKAGE = "org.spongepowered.asm.mixin"; public static final String GEN_PACKAGE = MIXIN_PACKAGE + ".gen"; public static final String INJECTION_PACKAGE = MIXIN_PACKAGE + ".injection"; + public static final String EXTRAS_INJECTION_PACKAGE = "com.llamalad7.mixinextras.injector"; public static final String MIXIN_CLASS = MIXIN_PACKAGE + ".Mixin"; public static final String SHADOW_CLASS = MIXIN_PACKAGE + ".Shadow"; @@ -30,6 +31,10 @@ public final class MixinConstants { public static final String CONSTANT_CLASS = INJECTION_PACKAGE + ".Constant"; public static final String MODIFY_CONSTANT_CLASS = INJECTION_PACKAGE + ".ModifyConstant"; public static final String MODIFY_VARIABLE_CLASS = INJECTION_PACKAGE + ".ModifyVariable"; + public static final String MODIFY_ARG_CLASS = INJECTION_PACKAGE + ".ModifyArg"; + // extras + public static final String MODIFY_EXPRESSION_VALUE = EXTRAS_INJECTION_PACKAGE + ".ModifyExpressionValue"; + public static final String WRAP_OPERATION_VALUE = EXTRAS_INJECTION_PACKAGE + ".wrapoperation.WrapOperation"; private MixinConstants() { }