Skip to content

Commit 88a7b3e

Browse files
committed
build/mixin: Allow creating new classes
Via a CompatMixin so 1) we can keep them organized in packages, and 2) we can create class nested inside of Mixin classes
1 parent fb8dffe commit 88a7b3e

File tree

2 files changed

+34
-1
lines changed

2 files changed

+34
-1
lines changed

build-logic/src/main/kotlin/essential/CompatMixinTask.kt

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,8 +55,9 @@ abstract class CompatMixinTask : DefaultTask() {
5555
val target = args["value"]?.toString()?.removeSurrounding("L", ";")?.replace('/', '.')
5656
?: args["target"]?.toString()
5757
?: throw IllegalArgumentException("`@CompatMixin` annotation in $classFile is invalid.")
58+
val createTarget = (args["createTarget"] as Boolean?) ?: false
5859

59-
mixins.getOrPut(target, ::mutableListOf).add(Mixin(classFile.toPath(), cls))
60+
mixins.getOrPut(target, ::mutableListOf).add(Mixin(classFile.toPath(), cls, createTarget))
6061
excludedClasses += cls.name.replace('/', '.')
6162
}
6263

@@ -97,6 +98,35 @@ abstract class CompatMixinTask : DefaultTask() {
9798
zipOut.closeEntry()
9899
}
99100
}
101+
102+
mixins.entries.removeIf { (target, targetMixins) ->
103+
val source = targetMixins.find { it.createTarget }
104+
if (source == null) return@removeIf false
105+
106+
val outputEntry = ZipEntry(target.replace(".", "/") + ".class")
107+
outputEntry.time = CONSTANT_TIME_FOR_ZIP_ENTRIES
108+
zipOut.putNextEntry(outputEntry)
109+
110+
val cls = ClassNode()
111+
cls.name = target.replace(".", "/")
112+
cls.version = source.node.version
113+
cls.access = source.node.access
114+
cls.superName = mixinRemapper.mapType(source.node.superName)
115+
cls.outerClass = mixinRemapper.mapType(source.node.outerClass)
116+
cls.sourceFile = source.node.sourceFile
117+
cls.sourceDebug = source.node.sourceDebug
118+
119+
for (targetMixin in targetMixins) {
120+
merge(targetMixin.node, cls, mixinRemapper)
121+
}
122+
123+
zipOut.write(ClassWriter(0).apply {
124+
cls.accept(ClassRemapper(this, mixinRemapper))
125+
}.toByteArray())
126+
127+
zipOut.closeEntry()
128+
true
129+
}
100130
}
101131

102132
if (mixins.isNotEmpty()) {
@@ -214,6 +244,7 @@ abstract class CompatMixinTask : DefaultTask() {
214244
private data class Mixin(
215245
val source: Path,
216246
val node: ClassNode,
247+
val createTarget: Boolean,
217248
)
218249

219250
companion object {

mixin/src/main/java/gg/essential/CompatMixin.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,4 +13,6 @@
1313
Class<?> value() default Void.class;
1414

1515
String target() default "";
16+
17+
boolean createTarget() default false;
1618
}

0 commit comments

Comments
 (0)