11package org.parchmentmc.tasks
22
3- import org.cadixdev.lorenz.MappingSet
3+ import net.fabricmc.mappingio.MappingReader
4+ import net.fabricmc.mappingio.format.MappingFormat
5+ import net.fabricmc.mappingio.tree.MappingTree
6+ import net.fabricmc.mappingio.tree.MemoryMappingTree
47import org.gradle.api.DefaultTask
58import org.gradle.api.file.DirectoryProperty
69import org.gradle.api.file.RegularFileProperty
@@ -11,106 +14,92 @@ import org.objectweb.asm.tree.ClassNode
1114import org.objectweb.asm.tree.FieldInsnNode
1215import org.objectweb.asm.tree.VarInsnNode
1316import org.parchmentmc.util.*
14- import org.parchmentmc.util.lorenz.FabricEnigmaReader
1517import java.lang.constant.ConstantDescs
1618
1719abstract class ScanInitParamsJar : DefaultTask () {
1820
1921 @get:InputFile
20- @get:PathSensitive(PathSensitivity .RELATIVE )
22+ @get:PathSensitive(PathSensitivity .NONE )
2123 abstract val inputJar: RegularFileProperty
2224
23- @get:Optional
2425 @get:InputDirectory
2526 @get:PathSensitive(PathSensitivity .RELATIVE )
2627 abstract val inputMapping: DirectoryProperty
2728
2829 @TaskAction
2930 fun run () {
30- val set: MappingSet ?
31- if (inputMapping.isPresent) {
32- set = MappingSet .create()
33- inputMapping.asFileTree.filter { file -> file.name.endsWith(" .mapping" ) }
34- .forEach { file ->
35- FabricEnigmaReader (file.bufferedReader(Charsets .UTF_8 )).use { reader ->
36- reader.read(set)
37- }
38- }
39- } else {
40- set = null
41- }
31+ val tree = MemoryMappingTree ()
32+ MappingReader .read(
33+ inputMapping.path,
34+ MappingFormat .ENIGMA_DIR ,
35+ tree
36+ )
4237
4338 inputJar.path.openZip().use { jar ->
4439 JarProcessing .processJar(
4540 jar,
46- ScanParameterProcessor (set )
41+ ScanParameterProcessor (tree )
4742 )
4843 }
4944 }
5045
51- private class ScanParameterProcessor (private val mapping : MappingSet ? ) : JarProcessing.ClassProcessor.NodeBased, AsmUtil {
46+ private class ScanParameterProcessor (
47+ private val mappings : MappingTree
48+ ) : JarProcessing.ClassProcessor.NodeBased, AsmUtil {
5249
5350 override fun processClass (node : ClassNode , classNodeCache : ClassNodeCache ) {
5451 if (Opcodes .ACC_RECORD in node.access || Opcodes .ACC_SYNTHETIC in node.access) {
5552 return
5653 }
5754
5855 node.methods.forEach { method ->
59- if (method.name == ConstantDescs .INIT_NAME ) {
60- if (method.parameters == null && Type .getArgumentTypes(method.desc).size == 0 ) {
61- return @forEach
62- }
56+ if (method.name != ConstantDescs .INIT_NAME ) {
57+ return @forEach
58+ }
59+ if (Type .getArgumentCount(method.desc) == 0 ) {
60+ return @forEach
61+ }
6362
64- val expectedNames = sortedMapOf<Int , String >()
65- val insns = method.instructions.iterator()
66- val locals = mutableSetOf<Int >()
67- while (insns.hasNext()) {
68- val insn = insns.next()
69- if (insn.opcode >= Opcodes .ISTORE && insn.opcode <= Opcodes .ASTORE ) {
70- locals.add((insn as VarInsnNode ).`var `)
71- continue
72- }
63+ val expectedNames = sortedMapOf<Int , String >()
64+ val insns = method.instructions.iterator()
65+ val locals = mutableSetOf<Int >()
66+ while (insns.hasNext()) {
67+ val insn = insns.next()
68+ if (insn.opcode >= Opcodes .ISTORE && insn.opcode <= Opcodes .ASTORE ) {
69+ locals.add((insn as VarInsnNode ).`var `)
70+ continue
71+ }
7372
74- if (insn.previous != null && (insn.previous.opcode >= Opcodes .ILOAD && insn.previous.opcode <= Opcodes .ALOAD )) {
75- val index = (insn.previous as VarInsnNode ).`var `
76- if (index != 0 && ! locals.contains(index)) { // skip this and lvt assignment
77- if (insn.opcode == Opcodes .PUTFIELD && (insn as FieldInsnNode ).owner == node.name) {
78- if (insn.name.startsWith(" this$" ) || insn.name.startsWith(" val$" )) { // skip outer class reference from nested class/method
79- continue
80- }
81- expectedNames[index] = insn.name
73+ if (insn.previous != null && (insn.previous.opcode >= Opcodes .ILOAD && insn.previous.opcode <= Opcodes .ALOAD )) {
74+ val index = (insn.previous as VarInsnNode ).`var `
75+ if (index != 0 && ! locals.contains(index)) { // skip this and lvt assignment
76+ if (insn.opcode == Opcodes .PUTFIELD && (insn as FieldInsnNode ).owner == node.name) {
77+ if (insn.name.startsWith(" this$" ) || insn.name.startsWith(" val$" )) { // skip outer class reference from nested class/method
78+ continue
8279 }
80+ expectedNames[index] = insn.name
8381 }
8482 }
8583 }
84+ }
8685
87- val currentNames: Map <Int , String >
88- if (mapping == null && method.parameters != null ) {
89- currentNames =
90- method.parameters
91- .filter { node -> ! (Opcodes .ACC_MANDATED in node.access || Opcodes .ACC_SYNTHETIC in node.access) }
92- .mapIndexed { index, node ->
93- fromParamToLvtIndex(index, method) to node.name
94- }
95- .toMap()
96- } else if (mapping != null ) {
97- currentNames = mapping.getClassMapping(node.name)
98- .flatMap { it.getMethodMapping(method.name, method.desc) }
99- .map { method ->
100- method.parameterMappings
101- .associate { it.index to it.deobfuscatedName }
102- }.orElseGet { mapOf () }
103- } else {
104- currentNames = mapOf ()
105- }
106- if (currentNames != expectedNames && currentNames.size <= expectedNames.size) {
107- println (node.name)
108- println (method.name + " " + method.desc)
109- println (" current : $currentNames " )
110- println (" expected: $expectedNames " )
111- expectedNames.forEach { entry ->
112- println (" ARG ${entry.key} ${entry.value} " )
113- }
86+ // search existing mapping recursively since overridden methods mapping are propagated once exported
87+ var args: Collection <MappingTree .MethodArgMapping >? = null
88+ var currentNode: ClassNode ? = node
89+ do {
90+ val node = currentNode ? : break
91+ args = mappings.getClass(node.name)?.getMethod(method.name, method.desc)?.args
92+ currentNode = classNodeCache.findClass(node.superName)
93+ } while (currentNode != null && (args == null || args.isEmpty()))
94+
95+ val currentNames = args?.associate { it.lvIndex to it.getDstName(0 ) } ? : mapOf ()
96+ if (currentNames != expectedNames && currentNames.size <= expectedNames.size) {
97+ println (node.name)
98+ println (method.name + " " + method.desc)
99+ println (" current : $currentNames " )
100+ println (" expected: $expectedNames " )
101+ expectedNames.forEach { entry ->
102+ println (" ARG ${entry.key} ${entry.value} " )
114103 }
115104 }
116105 }
0 commit comments