decompiler: provide line numbers mapping inside lambdas
This commit is contained in:
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user