decompiler: provide line numbers mapping inside lambdas

master
Egor.Ushakov 10 years ago
parent a74f586e34
commit 9ba9af5425
  1. 25
      src/org/jetbrains/java/decompiler/main/ClassWriter.java
  2. 2
      src/org/jetbrains/java/decompiler/modules/decompiler/exps/NewExprent.java
  3. 64
      testData/results/TestClassLambda.dec

@ -74,7 +74,7 @@ public class ClassWriter {
} }
} }
public void classLambdaToJava(ClassNode node, TextBuffer buffer, Exprent method_object, int indent) { public void classLambdaToJava(ClassNode node, TextBuffer buffer, Exprent method_object, int indent, BytecodeMappingTracer origTracer) {
ClassWrapper wrapper = node.getWrapper(); ClassWrapper wrapper = node.getWrapper();
if (wrapper == null) { if (wrapper == null) {
return; return;
@ -85,7 +85,7 @@ public class ClassWriter {
ClassNode outerNode = (ClassNode)DecompilerContext.getProperty(DecompilerContext.CURRENT_CLASS_NODE); ClassNode outerNode = (ClassNode)DecompilerContext.getProperty(DecompilerContext.CURRENT_CLASS_NODE);
DecompilerContext.setProperty(DecompilerContext.CURRENT_CLASS_NODE, node); DecompilerContext.setProperty(DecompilerContext.CURRENT_CLASS_NODE, node);
BytecodeMappingTracer tracer = new BytecodeMappingTracer(); BytecodeMappingTracer tracer = new BytecodeMappingTracer(origTracer.getCurrentSourceLine());
try { try {
StructClass cl = wrapper.getClassStruct(); StructClass cl = wrapper.getClassStruct();
@ -138,10 +138,13 @@ public class ClassWriter {
} }
buffer.append(" {").appendLineSeparator(); buffer.append(" {").appendLineSeparator();
tracer.incrementCurrentSourceLine();
methodLambdaToJava(node, wrapper, mt, buffer, indent + 1, !lambdaToAnonymous, tracer); methodLambdaToJava(node, wrapper, mt, buffer, indent + 1, !lambdaToAnonymous, tracer);
buffer.appendIndent(indent).append("}"); buffer.appendIndent(indent).append("}");
addTracer(cl, mt, tracer);
} }
} }
finally { finally {
@ -151,6 +154,15 @@ public class ClassWriter {
DecompilerContext.getLogger().endWriteClass(); DecompilerContext.getLogger().endWriteClass();
} }
private static void addTracer(StructClass cls, StructMethod method, BytecodeMappingTracer tracer) {
StructLineNumberTableAttribute lineNumberTable =
(StructLineNumberTableAttribute)method.getAttributes().getWithKey(StructGeneralAttribute.ATTRIBUTE_LINE_NUMBER_TABLE);
tracer.setLineNumberTable(lineNumberTable);
DecompilerContext.getBytecodeSourceMapper().addTracer(cls.qualifiedName,
InterpreterUtil.makeUniqueKey(method.getName(), method.getDescriptor()),
tracer);
}
public void classToJava(ClassNode node, TextBuffer buffer, int indent, BytecodeMappingTracer tracer) { public void classToJava(ClassNode node, TextBuffer buffer, int indent, BytecodeMappingTracer tracer) {
ClassNode outerNode = (ClassNode)DecompilerContext.getProperty(DecompilerContext.CURRENT_CLASS_NODE); ClassNode outerNode = (ClassNode)DecompilerContext.getProperty(DecompilerContext.CURRENT_CLASS_NODE);
DecompilerContext.setProperty(DecompilerContext.CURRENT_CLASS_NODE, node); DecompilerContext.setProperty(DecompilerContext.CURRENT_CLASS_NODE, node);
@ -232,8 +244,7 @@ public class ClassWriter {
boolean methodSkipped = !methodToJava(node, mt, buffer, indent + 1, method_tracer); boolean methodSkipped = !methodToJava(node, mt, buffer, indent + 1, method_tracer);
if (!methodSkipped) { if (!methodSkipped) {
hasContent = true; hasContent = true;
DecompilerContext.getBytecodeSourceMapper().addTracer(cl.qualifiedName, addTracer(cl, mt, method_tracer);
InterpreterUtil.makeUniqueKey(mt.getName(), mt.getDescriptor()), method_tracer);
startLine = method_tracer.getCurrentSourceLine(); startLine = method_tracer.getCurrentSourceLine();
} }
else { else {
@ -573,10 +584,6 @@ public class ClassWriter {
boolean isDeprecated = mt.getAttributes().containsKey("Deprecated"); boolean isDeprecated = mt.getAttributes().containsKey("Deprecated");
boolean clinit = false, init = false, dinit = false; boolean clinit = false, init = false, dinit = false;
StructLineNumberTableAttribute lineNumberTable =
(StructLineNumberTableAttribute)mt.getAttributes().getWithKey(StructGeneralAttribute.ATTRIBUTE_LINE_NUMBER_TABLE);
tracer.setLineNumberTable(lineNumberTable);
MethodDescriptor md = MethodDescriptor.parseDescriptor(mt.getDescriptor()); MethodDescriptor md = MethodDescriptor.parseDescriptor(mt.getDescriptor());
int flags = mt.getAccessFlags(); int flags = mt.getAccessFlags();
@ -805,6 +812,8 @@ public class ClassWriter {
} }
// We do not have line information for method start, lets have it here for now // We do not have line information for method start, lets have it here for now
StructLineNumberTableAttribute lineNumberTable =
(StructLineNumberTableAttribute)mt.getAttributes().getWithKey(StructGeneralAttribute.ATTRIBUTE_LINE_NUMBER_TABLE);
if (lineNumberTable != null && DecompilerContext.getOption(IFernflowerPreferences.USE_DEBUG_LINE_NUMBERS)) { if (lineNumberTable != null && DecompilerContext.getOption(IFernflowerPreferences.USE_DEBUG_LINE_NUMBERS)) {
buffer.setCurrentLine(lineNumberTable.getFirstLine() - 1); buffer.setCurrentLine(lineNumberTable.getFirstLine() - 1);
} }

@ -253,7 +253,7 @@ public class NewExprent extends Exprent {
} }
Exprent methodObject = constructor == null ? null : constructor.getInstance(); Exprent methodObject = constructor == null ? null : constructor.getInstance();
TextBuffer clsBuf = new TextBuffer(); TextBuffer clsBuf = new TextBuffer();
new ClassWriter().classLambdaToJava(child, clsBuf, methodObject, indent); new ClassWriter().classLambdaToJava(child, clsBuf, methodObject, indent, tracer);
buf.append(clsBuf); buf.append(clsBuf);
tracer.incrementCurrentSourceLine(clsBuf.countLines()); tracer.incrementCurrentSourceLine(clsBuf.countLines());
} }

@ -18,8 +18,8 @@ public class TestClassLambda {
List var1 = Arrays.asList(new Integer[]{Integer.valueOf(1), Integer.valueOf(2), Integer.valueOf(3), Integer.valueOf(4), Integer.valueOf(5), Integer.valueOf(6), Integer.valueOf(7)});// 29 List var1 = Arrays.asList(new Integer[]{Integer.valueOf(1), Integer.valueOf(2), Integer.valueOf(3), Integer.valueOf(4), Integer.valueOf(5), Integer.valueOf(6), Integer.valueOf(7)});// 29
int var2 = (int)Math.random();// 30 int var2 = (int)Math.random();// 30
var1.forEach((var2x) -> {// 32 var1.forEach((var2x) -> {// 32
int var3 = 2 * var2x.intValue(); int var3 = 2 * var2x.intValue();// 33
System.out.println(var3 + var2 + this.field); System.out.println(var3 + var2 + this.field);// 34
}); });
} }
@ -82,13 +82,25 @@ public class TestClassLambda {
Runnable var2 = () -> { Runnable var2 = () -> {
Runnable var1x = () -> { Runnable var1x = () -> {
System.out.println("hello2" + var1); System.out.println("hello2" + var1);
}; };// 87
System.out.println("hello1" + var1); System.out.println("hello1" + var1);// 88
};// 86 };// 86
} }
} }
class 'pkg/TestClassLambda' { class 'pkg/TestClassLambda' {
method 'lambda$testLambda$0 (ILjava/lang/Integer;)V' {
0 20
2 20
5 20
6 20
7 21
c 21
e 21
11 21
12 21
}
method 'testLambda ()V' { method 'testLambda ()V' {
7 17 7 17
8 17 8 17
@ -112,6 +124,20 @@ class 'pkg/TestClassLambda' {
4a 19 4a 19
} }
method 'lambda$testLambda1$1 (I)V' {
0 28
a 28
13 28
16 28
}
method 'lambda$testLambda1$2 (I)V' {
0 31
a 31
13 31
16 31
}
method 'testLambda1 ()V' { method 'testLambda1 ()V' {
0 26 0 26
3 26 3 26
@ -120,6 +146,11 @@ class 'pkg/TestClassLambda' {
12 32 12 32
} }
method 'lambda$testLambda2$3 (II)I' {
2 37
5 37
}
method 'testLambda2 ()V' { method 'testLambda2 ()V' {
5 36 5 36
} }
@ -138,6 +169,12 @@ class 'pkg/TestClassLambda' {
e 51 e 51
} }
method 'lambda$testLambda6$4 (IILjava/lang/String;)Z' {
2 59
9 59
15 59
}
method 'testLambda6 ()V' { method 'testLambda6 ()V' {
7 55 7 55
9 56 9 56
@ -172,6 +209,21 @@ class 'pkg/TestClassLambda' {
1 76 1 76
} }
method 'lambda$null$5 (I)V' {
0 83
a 83
13 83
16 83
}
method 'lambda$nestedLambdas$6 (I)V' {
6 84
7 85
11 85
1a 85
1d 85
}
method 'nestedLambdas ()V' { method 'nestedLambdas ()V' {
0 80 0 80
1 80 1 80
@ -183,6 +235,8 @@ Lines mapping:
29 <-> 18 29 <-> 18
30 <-> 19 30 <-> 19
32 <-> 20 32 <-> 20
33 <-> 21
34 <-> 22
39 <-> 27 39 <-> 27
40 <-> 30 40 <-> 30
41 <-> 33 41 <-> 33
@ -201,3 +255,5 @@ Lines mapping:
81 <-> 77 81 <-> 77
85 <-> 81 85 <-> 81
86 <-> 87 86 <-> 87
87 <-> 85
88 <-> 86

Loading…
Cancel
Save