From c9438c5e280eb3ae6045197a3dcd1637b6fa1cdd Mon Sep 17 00:00:00 2001 From: tranquillity-codes <120999089+tranquillity-codes@users.noreply.github.com> Date: Wed, 18 Dec 2024 18:38:35 +0100 Subject: [PATCH] Make LineNumberRemapper stop trying to guess line numbers Usually the guesses were wrong, so instead let's not generate a LineNumberTable for lines that lack a mapping in the linemap. This makes the behavior on decompiler bugs/issues more predictable. --- .../loom/decompilers/LineNumberRemapper.java | 14 ++++------- .../test/unit/LineNumberRemapperTests.groovy | 25 +++++++++++++++++++ 2 files changed, 30 insertions(+), 9 deletions(-) diff --git a/src/main/java/net/fabricmc/loom/decompilers/LineNumberRemapper.java b/src/main/java/net/fabricmc/loom/decompilers/LineNumberRemapper.java index 9b3ab78f7..705be2564 100644 --- a/src/main/java/net/fabricmc/loom/decompilers/LineNumberRemapper.java +++ b/src/main/java/net/fabricmc/loom/decompilers/LineNumberRemapper.java @@ -106,20 +106,16 @@ public MethodVisitor visitMethod(int access, String name, String descriptor, Str return new MethodVisitor(api, super.visitMethod(access, name, descriptor, signature, exceptions)) { @Override public void visitLineNumber(int line, Label start) { - int tLine = line; - - if (tLine <= 0) { + if (line <= 0) { super.visitLineNumber(line, start); - } else if (tLine >= lineNumbers.maxLine()) { + } else if (line >= lineNumbers.maxLine()) { super.visitLineNumber(lineNumbers.maxLineDest(), start); } else { - Integer matchedLine = null; + Integer matchedLine = lineNumbers.lineMap().get(line); - while (tLine <= lineNumbers.maxLine() && ((matchedLine = lineNumbers.lineMap().get(tLine)) == null)) { - tLine++; + if(matchedLine != null) { + super.visitLineNumber(matchedLine, start); } - - super.visitLineNumber(matchedLine != null ? matchedLine : lineNumbers.maxLineDest(), start); } } }; diff --git a/src/test/groovy/net/fabricmc/loom/test/unit/LineNumberRemapperTests.groovy b/src/test/groovy/net/fabricmc/loom/test/unit/LineNumberRemapperTests.groovy index e07bfc705..c9ef451f2 100644 --- a/src/test/groovy/net/fabricmc/loom/test/unit/LineNumberRemapperTests.groovy +++ b/src/test/groovy/net/fabricmc/loom/test/unit/LineNumberRemapperTests.groovy @@ -65,6 +65,31 @@ class LineNumberRemapperTests extends Specification { readLineNumbers(unpacked) == [37, 39, 40] } + def "remapLinenumbersExclude"() { + given: + def className = LineNumberSource.class.name.replace('.', '/') + def input = ZipTestUtils.createZipFromBytes([(className + ".class"): getClassBytes(LineNumberSource.class)]) + + // + 10 to each line number + def entry = new ClassLineNumbers.Entry(className, 30, 40, [ + 27: 37, + 30: 40 + ]) + def lineNumbers = new ClassLineNumbers([(className): entry]) + + def outputJar = Files.createTempDirectory("loom").resolve("output.jar") + + when: + def remapper = new LineNumberRemapper(lineNumbers) + remapper.process(input, outputJar) + + def unpacked = ZipUtils.unpack(outputJar, className + ".class") + + then: + readLineNumbers(getClassBytes(LineNumberSource.class)) == [27, 29, 30] + readLineNumbers(unpacked) == [37, 40] + } + static byte[] getClassBytes(Class clazz) { return clazz.classLoader.getResourceAsStream(clazz.name.replace('.', '/') + ".class").withCloseable { it.bytes