Skip to content

Commit

Permalink
Make LineNumberRemapper stop trying to guess line numbers (#1235)
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
tranquillity-codes authored Dec 23, 2024
1 parent 2ba633b commit 3fce262
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
}
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit 3fce262

Please sign in to comment.