Skip to content

Commit

Permalink
add ability to remap mixins in place
Browse files Browse the repository at this point in the history
  • Loading branch information
wagyourtail committed Nov 30, 2023
1 parent 2cafba1 commit a56dc30
Show file tree
Hide file tree
Showing 25 changed files with 389 additions and 75 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -25,5 +25,7 @@ interface MixinRemapOptions {
@ApiStatus.Experimental
fun resetRefmapBuilder()
fun off()

fun disableRefmap()
fun disableRefmap(keys: List<String> = listOf("BaseMixin", "JarModAgent"))
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import org.objectweb.asm.ClassVisitor
import xyz.wagyourtail.unimined.api.mapping.mixin.MixinRemapOptions
import xyz.wagyourtail.unimined.internal.mapping.extension.jma.hard.JMAHard
import xyz.wagyourtail.unimined.internal.mapping.extension.jma.refmap.JMARefmap
import xyz.wagyourtail.unimined.internal.mapping.extension.jma.refmap.JarModAgentMetaData
import xyz.wagyourtail.unimined.internal.mapping.extension.jma.JarModAgentMetaData
import xyz.wagyourtail.unimined.internal.mapping.extension.mixin.OfficialMixinMetaData
import xyz.wagyourtail.unimined.internal.mapping.extension.mixin.hard.BaseMixinHard
import xyz.wagyourtail.unimined.internal.mapping.extension.mixin.hard.HardTargetRemappingClassVisitor
Expand All @@ -30,7 +30,6 @@ import java.nio.file.FileSystem
import java.nio.file.Path
import java.util.*
import java.util.concurrent.CompletableFuture
import java.util.concurrent.ConcurrentHashMap
import java.util.concurrent.ConcurrentLinkedDeque

class MixinRemapExtension(
Expand Down Expand Up @@ -60,7 +59,7 @@ class MixinRemapExtension(
)

var off by FinalizeOnRead(false)
var noRefmap by FinalizeOnRead(false)
var noRefmap: Set<String> by FinalizeOnRead(setOf())

@ApiStatus.Internal
fun modifyMetadataReader(modifier: (MixinRemapExtension) -> MixinMetadata) {
Expand All @@ -85,8 +84,11 @@ class MixinRemapExtension(
}

override fun disableRefmap() {
noRefmap = true
TODO("todo. duplicate behavior of tinyremapper hard target/soft target remapping")
disableRefmap(listOf("BaseMixin", "JarModAgent"))
}

override fun disableRefmap(keys: List<String>) {
noRefmap = keys.toSet()
}

override fun enableMixinExtra() {
Expand Down Expand Up @@ -120,7 +122,7 @@ class MixinRemapExtension(

override fun reset() {
off = false
noRefmap = false
noRefmap = setOf()
resetMetadataReader()
resetHardRemapper()
resetRefmapBuilder()
Expand Down Expand Up @@ -203,6 +205,7 @@ class MixinRemapExtension(
target,
next,
mappings,
extension,
onEnd = {
if (target.size() > 0) {
extension.logger.info("[RefmapBuilder] adding ${target.size()} mappings for ${cls.name}")
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package xyz.wagyourtail.unimined.internal.mapping.extension.jma.refmap
package xyz.wagyourtail.unimined.internal.mapping.extension.jma

import com.google.gson.GsonBuilder
import com.google.gson.JsonObject
Expand Down Expand Up @@ -94,7 +94,11 @@ class JarModAgentMetaData(parent: MixinRemapExtension) : MixinRemapExtension.Mix
if (refmaps.isNotEmpty()) {
val manifest = Manifest(fs.getPath("META-INF/MANIFEST.MF").inputStream())

manifest.mainAttributes.putValue("JarModAgent-Refmaps", refmaps.keys.joinToString(" "))
if (!parent.noRefmap.contains("JarModAgent")) {
manifest.mainAttributes.putValue("JarModAgent-Refmaps", refmaps.keys.joinToString(" "))
} else {
manifest.mainAttributes.remove("JarModAgent-Refmaps")
}

fs.getPath("META-INF/MANIFEST.MF")
.outputStream(StandardOpenOption.TRUNCATE_EXISTING, StandardOpenOption.CREATE).use {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,16 @@ class CTargetAnnotationVisitor(parent: AnnotationVisitor?, remap: AtomicBoolean,
private val mapper = refmapBuilder.mapper
private val refmap = refmapBuilder.refmap
private val mixinName = refmapBuilder.mixinName
private val noRefmap = refmapBuilder.mixinRemapExtension.noRefmap.contains("JarModAgent")

override fun visit(name: String, value: Any) {
super.visit(name, value)
if (name == AnnotationElement.TARGET) targetName = (value as String).replace(" ", "")
if (name == AnnotationElement.TARGET) {
targetName = (value as String).replace(" ", "")
if (!noRefmap) super.visit(name, value)
} else {
super.visit(name, value)
}
}

override fun visitAnnotation(name: String, descriptor: String): AnnotationVisitor {
Expand All @@ -48,7 +54,6 @@ class CTargetAnnotationVisitor(parent: AnnotationVisitor?, remap: AtomicBoolean,
}

override fun visitEnd() {
super.visitEnd()
if (remapAt && targetName != null) {
val matchFd = targetField.matchEntire(targetName!!)
if (matchFd != null) {
Expand Down Expand Up @@ -85,6 +90,9 @@ class CTargetAnnotationVisitor(parent: AnnotationVisitor?, remap: AtomicBoolean,
val mappedName = mapper.mapName(it)
val mappedDesc = mapper.mapDesc(it)
refmap.addProperty(this.targetName, "L$mappedOwner;$mappedName:$mappedDesc")
if (noRefmap) {
super.visit(AnnotationElement.TARGET, "L$mappedOwner;$mappedName:$mappedDesc")
}
}
}
if (!target.isPresent || !targetClass.isPresent) {
Expand All @@ -96,7 +104,11 @@ class CTargetAnnotationVisitor(parent: AnnotationVisitor?, remap: AtomicBoolean,
)
}"
)
if (noRefmap) {
super.visit(AnnotationElement.TARGET, this.targetName)
}
}
super.visitEnd()
return
}
val matchMd = targetMethod.matchEntire(targetName!!)
Expand Down Expand Up @@ -134,6 +146,9 @@ class CTargetAnnotationVisitor(parent: AnnotationVisitor?, remap: AtomicBoolean,
val mappedName = mapper.mapName(it)
val mappedDesc = mapper.mapDesc(it)
refmap.addProperty(this.targetName, "L$mappedOwner;$mappedName$mappedDesc")
if (noRefmap) {
super.visit(AnnotationElement.TARGET, "L$mappedOwner;$mappedName$mappedDesc")
}
}
}
if (!target.isPresent || !targetClass.isPresent) {
Expand All @@ -145,7 +160,11 @@ class CTargetAnnotationVisitor(parent: AnnotationVisitor?, remap: AtomicBoolean,
)
}"
)
if (noRefmap) {
super.visit(AnnotationElement.TARGET, this.targetName)
}
}
super.visitEnd()
return
}
if (targetName!!.startsWith("(")) {
Expand All @@ -155,16 +174,29 @@ class CTargetAnnotationVisitor(parent: AnnotationVisitor?, remap: AtomicBoolean,
val mapped = mapper.asTrRemapper().mapDesc(existing)
if (mapped == existing) {
logger.warn("Failed to remap $existing")
if (noRefmap) {
super.visit(AnnotationElement.TARGET, this.targetName)
}
super.visitEnd()
return
}
refmap.addProperty(this.targetName, mapped)
super.visitEnd()
return
} else {
val mapped = mapper.asTrRemapper().mapDesc(targetName)
if (mapped == targetName) {
logger.warn("Failed to remap $targetName")
if (noRefmap) {
super.visit(AnnotationElement.TARGET, this.targetName)
}
return
} else {
refmap.addProperty(this.targetName, mapped)
if (noRefmap) {
super.visit(AnnotationElement.TARGET, mapped)
}
super.visitEnd()
return
}
}
Expand Down Expand Up @@ -194,8 +226,12 @@ class CTargetAnnotationVisitor(parent: AnnotationVisitor?, remap: AtomicBoolean,
target.ifPresent {
val mapped = mapper.mapName(it)
refmap.addProperty(this.targetName, "L$mapped;")
if (noRefmap) {
super.visit(AnnotationElement.TARGET, "L$mapped;")
}
}
if (target.isPresent) {
super.visitEnd()
return
}
}
Expand All @@ -208,6 +244,14 @@ class CTargetAnnotationVisitor(parent: AnnotationVisitor?, remap: AtomicBoolean,
)
}"
)
if (noRefmap) {
super.visit(AnnotationElement.TARGET, this.targetName)
}
} else if (targetName != null) {
if (noRefmap) {
super.visit(AnnotationElement.TARGET, this.targetName)
}
}
super.visitEnd()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -37,17 +37,13 @@ abstract class CAbstractFieldAnnotationVisitor(
protected val mixinName = refmapBuilder.mixinName
protected val targetClasses = refmapBuilder.targetClasses
protected val allowImplicitWildcards = refmapBuilder.allowImplicitWildcards
protected val noRefmap = refmapBuilder.mixinRemapExtension.noRefmap.contains("JarModAgent")

override fun visit(name: String?, value: Any) {
super.visit(name, value)
if (name == AnnotationElement.REMAP) remap.set(value as Boolean)
}

override fun visitEnd() {
super.visitEnd()
remapTargetNames()
}

open fun getTargetNameAndDescs(targetField: String): Pair<String, Set<String?>> {
val targetDescs = setOf(if (targetField.contains(":")) {
targetField.substringAfter(":")
Expand All @@ -58,7 +54,7 @@ abstract class CAbstractFieldAnnotationVisitor(
return targetName to targetDescs
}

open fun remapTargetNames() {
open fun remapTargetNames(noRefmapAcceptor: (String) -> Unit) {
if (remap.get()) {
outer@for (targetField in targetNames) {
val (targetName, targetDescs) = getTargetNameAndDescs(targetField)
Expand Down Expand Up @@ -94,8 +90,10 @@ abstract class CAbstractFieldAnnotationVisitor(
val mappedDesc = mapper.mapDesc(targetVal)
if (targetClasses.size > 1) {
refmap.addProperty(targetField, "$mappedName$mappedDesc")
noRefmapAcceptor("$mappedName$mappedDesc")
} else {
refmap.addProperty(targetField, "L$mappedClass;$mappedName:$mappedDesc")
noRefmapAcceptor("L$mappedClass;$mappedName:$mappedDesc")
}
}

Expand All @@ -107,6 +105,11 @@ abstract class CAbstractFieldAnnotationVisitor(
logger.warn(
"Failed to resolve $annotationName $targetField ($targetDescs) on ($fieldName:$fieldDescriptor) $fieldSignature in $mixinName"
)
noRefmapAcceptor(targetField)
}
} else {
for (targetField in targetNames) {
noRefmapAcceptor(targetField)
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,10 +47,22 @@ class CShadowFieldAnnotationVisitor(
override fun visit(name: String?, value: Any) {
if (name == AnnotationElement.VALUE) {
targetNames.add(value as String)
if (!noRefmap) {
super.visit(name, value)
}
} else {
super.visit(name, value)
}
super.visit(name, value)
}

override fun visitEnd() {
remapTargetNames {
if (noRefmap) {
super.visit(AnnotationElement.VALUE, it)
}
}
super.visitEnd()
}

override fun getTargetNameAndDescs(targetField: String): Pair<String, Set<String?>> {
return if (targetField.contains(":")) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,17 +36,13 @@ abstract class CAbstractMethodAnnotationVisitor(
protected val mixinName = refmapBuilder.mixinName
protected val targetClasses = refmapBuilder.targetClasses
protected val allowImplicitWildcards = refmapBuilder.allowImplicitWildcards
protected val noRefmap = refmapBuilder.mixinRemapExtension.noRefmap.contains("BaseMixin")

override fun visit(name: String?, value: Any) {
super.visit(name, value)
if (name == AnnotationElement.REMAP) remap.set(value as Boolean)
}

override fun visitEnd() {
super.visitEnd()
remapTargetNames()
}

open fun getTargetNameAndDescs(targetMethod: String, wildcard: Boolean): Pair<String, Set<String?>> {
val targetDescs = setOf(if (targetMethod.contains("(")) {
"(" + targetMethod.substringAfter("(")
Expand All @@ -61,12 +57,13 @@ abstract class CAbstractMethodAnnotationVisitor(
return targetName to targetDescs
}

open fun remapTargetNames() {
open fun remapTargetNames(noRefmapAcceptor: (String) -> Unit) {
if (remap.get()) {
outer@for (targetMethod in targetNames) {
if (targetMethod == "<init>" || targetMethod == "<clinit>" ||
targetMethod == "<init>*"
) {
noRefmapAcceptor(targetMethod)
continue
}
val wildcard = targetMethod.endsWith("*")
Expand Down Expand Up @@ -122,8 +119,10 @@ abstract class CAbstractMethodAnnotationVisitor(
val mappedDesc = /* if (implicitWildcard) "" else */ if (wildcard && mappedName != "<clinit>") "*" else mapper.mapDesc(targetVal)
if (targetClasses.size > 1) {
refmap.addProperty(targetMethod, "$mappedName$mappedDesc")
noRefmapAcceptor("$mappedName$mappedDesc")
} else {
refmap.addProperty(targetMethod, "L$mappedClass;$mappedName$mappedDesc")
noRefmapAcceptor("L$mappedClass;$mappedName$mappedDesc")
}
}

Expand All @@ -135,6 +134,7 @@ abstract class CAbstractMethodAnnotationVisitor(
logger.warn(
"Failed to resolve $annotationName $targetMethod ($targetDescs) on ($methodName$methodDescriptor) $methodSignature in $mixinName"
)
noRefmapAcceptor(targetMethod)
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,17 +50,16 @@ class CInjectAnnotationVisitor(
}

override fun visitArray(name: String): AnnotationVisitor {
val delegate = super.visitArray(name)
return when (name) {
AnnotationElement.TARGET -> {
ArrayVisitorWrapper(Constant.ASM_VERSION, delegate) { CTargetAnnotationVisitor(it, remap, refmapBuilder) }
ArrayVisitorWrapper(Constant.ASM_VERSION, super.visitArray(name)) { CTargetAnnotationVisitor(it, remap, refmapBuilder) }
}

AnnotationElement.SLICE -> {
ArrayVisitorWrapper(Constant.ASM_VERSION, delegate) { CSliceAnnotationVisitor(it, remap, refmapBuilder) }
ArrayVisitorWrapper(Constant.ASM_VERSION, super.visitArray(name)) { CSliceAnnotationVisitor(it, remap, refmapBuilder) }
}
AnnotationElement.METHOD -> {
object: AnnotationVisitor(Constant.ASM_VERSION, delegate) {
object: AnnotationVisitor(Constant.ASM_VERSION, if (noRefmap) null else super.visitArray(name)) {
override fun visit(name: String?, value: Any) {
super.visit(name, value)
targetNames.add(value as String)
Expand All @@ -69,11 +68,24 @@ class CInjectAnnotationVisitor(
}

else -> {
delegate
super.visitArray(name)
}
}
}

override fun visitEnd() {
val method = if (noRefmap) {
super.visitArray(AnnotationElement.METHOD)
} else {
null
}
remapTargetNames {
method?.visit(null, it)
}
method?.visitEnd()
super.visitEnd()
}

private val callbackInfo = "Lnet/lenni0451/classtransform/InjectionCallback"

private fun stripCallbackInfoFromDesc(): Set<String?> {
Expand Down
Loading

0 comments on commit a56dc30

Please sign in to comment.