Skip to content

Commit

Permalink
fix lambda to anonymous class regression (#336)
Browse files Browse the repository at this point in the history
* fix lambda to anonymous class option

* add regression tests for feature

* get method references to decompile correctly again
  • Loading branch information
tildejustin authored Jan 21, 2024
1 parent a3de77e commit 9dc14fc
Show file tree
Hide file tree
Showing 6 changed files with 151 additions and 9 deletions.
18 changes: 9 additions & 9 deletions src/org/jetbrains/java/decompiler/main/ClassWriter.java
Original file line number Diff line number Diff line change
Expand Up @@ -192,10 +192,10 @@ public void classLambdaToJava(ClassNode node, TextBuffer buffer, Exprent method_
MethodDescriptor md_lambda = MethodDescriptor.parseDescriptor(node.lambdaInformation.method_descriptor);

boolean simpleLambda = false;
boolean written = false;

if (!lambdaToAnonymous) {
RootStatement root = wrapper.getMethodWrapper(mt.getName(), mt.getDescriptor()).root;
boolean written = false;
if (DecompilerContext.getOption(IFernflowerPreferences.MARK_CORRESPONDING_SYNTHETICS)) {
buffer.append("/* ")
.appendMethod(node.lambdaInformation.content_method_name,
Expand Down Expand Up @@ -310,16 +310,16 @@ public void classLambdaToJava(ClassNode node, TextBuffer buffer, Exprent method_
}
}
}

if (!simpleLambda) {
buffer.append(" {").appendLineSeparator();

methodLambdaToJava(node, wrapper, mt, buffer, indent + 1, !lambdaToAnonymous);

buffer.appendIndent(indent).append("}");
}
}
}

if ((!simpleLambda && !written) || lambdaToAnonymous) {
buffer.append(" {").appendLineSeparator();

methodLambdaToJava(node, wrapper, mt, buffer, indent + 1, !lambdaToAnonymous);

buffer.appendIndent(indent).append("}");
}
}
}
finally {
Expand Down
16 changes: 16 additions & 0 deletions test/org/jetbrains/java/decompiler/SingleClassesTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,17 @@ public String getMethodDoc(StructClass structClass, StructMethod structMethod) {
IFernflowerPreferences.VERIFY_ANONYMOUS_CLASSES, "1",
IFernflowerPreferences.MARK_CORRESPONDING_SYNTHETICS, "1"
);
registerSet("Lambda to Anonymous Class", this::registerLambdaToAnonymousClass,
IFernflowerPreferences.BYTECODE_SOURCE_MAPPING, "1",
IFernflowerPreferences.DUMP_ORIGINAL_LINES, "1",
IFernflowerPreferences.DUMP_EXCEPTION_ON_ERROR, "0",
IFernflowerPreferences.IGNORE_INVALID_BYTECODE, "1",
IFernflowerPreferences.VERIFY_ANONYMOUS_CLASSES, "1",
IFernflowerPreferences.INCLUDE_ENTIRE_CLASSPATH, "0",
IFernflowerPreferences.TERNARY_CONDITIONS, "1",
IFernflowerPreferences.FORCE_JSR_INLINE, "1",
IFernflowerPreferences.LAMBDA_TO_ANONYMOUS_CLASS, "1"
);
// TODO: user renamer class test
}

Expand Down Expand Up @@ -843,4 +854,9 @@ private void registerSyntheticsMarking() {
register(JAVA_8, "TestAnonymousClassNaming");
register(JAVA_8, "TestLocalClassNaming");
}

private void registerLambdaToAnonymousClass() {
register(JAVA_8, "TestLambdaToAnonymousClass");
register(JAVA_8, "TestLambdaToAnonymousClass2");
}
}
24 changes: 24 additions & 0 deletions testData/results/pkg/TestLambdaToAnonymousClass.dec
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package pkg;

public class TestLambdaToAnonymousClass {
Runnable f = new Runnable() {
public run() {
System.out.println();// 4
}
};
}

class 'pkg/TestLambdaToAnonymousClass' {
method 'lambda$new$0 ()V' {
0 5
1 5
2 5
3 5
4 5
5 5
6 6
}
}

Lines mapping:
4 <-> 6
83 changes: 83 additions & 0 deletions testData/results/pkg/TestLambdaToAnonymousClass2.dec
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
package pkg;

import java.util.List;
import java.util.function.BiConsumer;
import java.util.function.Function;
import java.util.function.IntFunction;

public class TestLambdaToAnonymousClass2 {
public void test() {
BiConsumer<List<String>, Integer> $ = new BiConsumer() {// 8
public accept(List l, Integer i) {
Character[] a = (Character[])l.stream().map(new Function() {// 9
public apply(String st) {
return st.charAt(i);// 10
}
}).toArray(new IntFunction() {
public apply(int x$0) {
return new Character[x$0];// 11
}
});
}// 12
};
}// 13
}

class 'pkg/TestLambdaToAnonymousClass2' {
method 'test ()V' {
5 9
6 22
}

method 'lambda$test$2 (Ljava/util/List;Ljava/lang/Integer;)V' {
0 11
1 11
2 11
3 11
4 11
5 11
c 11
d 11
e 11
f 11
10 11
16 15
17 15
18 15
19 15
1a 15
1b 11
1c 11
1d 11
1e 11
1f 20
}

method 'lambda$null$0 (Ljava/lang/Integer;Ljava/lang/String;)Ljava/lang/Character;' {
0 13
1 13
2 13
3 13
4 13
5 13
6 13
7 13
8 13
9 13
a 13
b 13
}

method 'lambda$null$1 (I)[Ljava/lang/Character;' {
0 17
4 17
}
}

Lines mapping:
8 <-> 10
9 <-> 12
10 <-> 14
11 <-> 18
12 <-> 21
13 <-> 23
5 changes: 5 additions & 0 deletions testData/src/java8/pkg/TestLambdaToAnonymousClass.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package pkg;

public class TestLambdaToAnonymousClass {
Runnable f = () -> System.out.println();
}
14 changes: 14 additions & 0 deletions testData/src/java8/pkg/TestLambdaToAnonymousClass2.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package pkg;

import java.util.List;
import java.util.function.*;

public class TestLambdaToAnonymousClass2 {
public void test() {
BiConsumer<List<String>, Integer> $ = (l, i) -> {
Character[] a = l.stream()
.map(st -> st.charAt(i))
.toArray(Character[]::new);
};
}
}

0 comments on commit 9dc14fc

Please sign in to comment.