From 61fea780f43eaa57ad4afe8df91cc4181644307a Mon Sep 17 00:00:00 2001 From: nbauma109 Date: Thu, 1 Jan 2026 21:14:03 +0100 Subject: [PATCH 1/2] improve code coverage --- .../transformerapi/HelloWorld.java | 7 - .../StandardTransformersTest.java | 41 ++-- .../transformerapi/ZipLoader.java | 28 +++ src/test/resources/HelloWorldCFR.txt | 10 - src/test/resources/HelloWorldFernflower.txt | 7 - src/test/resources/HelloWorldJADX.txt | 8 - src/test/resources/HelloWorldJDCoreV0.txt | 9 - src/test/resources/HelloWorldJDCoreV1.txt | 7 - src/test/resources/HelloWorldProcyon.txt | 8 - src/test/resources/HelloWorldVineflower.txt | 7 - src/test/resources/TestCompactCFR.txt | 161 +++++++++++++++ src/test/resources/TestCompactFernflower.txt | 153 ++++++++++++++ src/test/resources/TestCompactJADX.txt | 94 +++++++++ src/test/resources/TestCompactJDCoreV0.txt | 191 ++++++++++++++++++ src/test/resources/TestCompactJDCoreV1.txt | 150 ++++++++++++++ src/test/resources/TestCompactProcyon.txt | 166 +++++++++++++++ src/test/resources/TestCompactVineflower.txt | 160 +++++++++++++++ 17 files changed, 1124 insertions(+), 83 deletions(-) delete mode 100644 src/test/java/com/heliosdecompiler/transformerapi/HelloWorld.java create mode 100644 src/test/java/com/heliosdecompiler/transformerapi/ZipLoader.java delete mode 100644 src/test/resources/HelloWorldCFR.txt delete mode 100644 src/test/resources/HelloWorldFernflower.txt delete mode 100644 src/test/resources/HelloWorldJADX.txt delete mode 100644 src/test/resources/HelloWorldJDCoreV0.txt delete mode 100644 src/test/resources/HelloWorldJDCoreV1.txt delete mode 100644 src/test/resources/HelloWorldProcyon.txt delete mode 100644 src/test/resources/HelloWorldVineflower.txt create mode 100644 src/test/resources/TestCompactCFR.txt create mode 100644 src/test/resources/TestCompactFernflower.txt create mode 100644 src/test/resources/TestCompactJADX.txt create mode 100644 src/test/resources/TestCompactJDCoreV0.txt create mode 100644 src/test/resources/TestCompactJDCoreV1.txt create mode 100644 src/test/resources/TestCompactProcyon.txt create mode 100644 src/test/resources/TestCompactVineflower.txt diff --git a/src/test/java/com/heliosdecompiler/transformerapi/HelloWorld.java b/src/test/java/com/heliosdecompiler/transformerapi/HelloWorld.java deleted file mode 100644 index 75e19fb..0000000 --- a/src/test/java/com/heliosdecompiler/transformerapi/HelloWorld.java +++ /dev/null @@ -1,7 +0,0 @@ -package com.heliosdecompiler.transformerapi; - -public class HelloWorld { - public static void main(String[] args) { - System.out.println("Hello World!"); - } -} diff --git a/src/test/java/com/heliosdecompiler/transformerapi/StandardTransformersTest.java b/src/test/java/com/heliosdecompiler/transformerapi/StandardTransformersTest.java index f36ef6a..3027a63 100644 --- a/src/test/java/com/heliosdecompiler/transformerapi/StandardTransformersTest.java +++ b/src/test/java/com/heliosdecompiler/transformerapi/StandardTransformersTest.java @@ -1,73 +1,74 @@ package com.heliosdecompiler.transformerapi; import org.apache.commons.io.IOUtils; -import org.jd.core.v1.loader.ClassPathLoader; import org.junit.Test; import com.heliosdecompiler.transformerapi.common.Loader; import java.io.IOException; import java.lang.reflect.InvocationTargetException; +import java.net.URI; +import java.net.URISyntaxException; import java.nio.charset.StandardCharsets; import java.util.Collections; import java.util.Map; -import jd.core.DecompilationResult; - -import static org.junit.Assert.assertEquals; import static com.heliosdecompiler.transformerapi.StandardTransformers.Decompilers.ENGINE_CFR; -import static com.heliosdecompiler.transformerapi.StandardTransformers.Decompilers.ENGINE_PROCYON; import static com.heliosdecompiler.transformerapi.StandardTransformers.Decompilers.ENGINE_FERNFLOWER; -import static com.heliosdecompiler.transformerapi.StandardTransformers.Decompilers.ENGINE_VINEFLOWER; import static com.heliosdecompiler.transformerapi.StandardTransformers.Decompilers.ENGINE_JADX; import static com.heliosdecompiler.transformerapi.StandardTransformers.Decompilers.ENGINE_JD_CORE_V0; import static com.heliosdecompiler.transformerapi.StandardTransformers.Decompilers.ENGINE_JD_CORE_V1; - -import static jd.core.preferences.Preferences.WRITE_METADATA; +import static com.heliosdecompiler.transformerapi.StandardTransformers.Decompilers.ENGINE_PROCYON; +import static com.heliosdecompiler.transformerapi.StandardTransformers.Decompilers.ENGINE_VINEFLOWER; import static jd.core.preferences.Preferences.WRITE_LINE_NUMBERS; +import static jd.core.preferences.Preferences.WRITE_METADATA; +import static org.junit.Assert.assertEquals; + +import jd.core.DecompilationResult; public class StandardTransformersTest { @Test public void testDecompileCFR() throws Exception { - testDecompile("/HelloWorldCFR.txt", ENGINE_CFR, Map.of("showversion", "false")); + testDecompile("/TestCompactCFR.txt", ENGINE_CFR, Map.of("showversion", "false")); } - + @Test public void testDecompileProcyon() throws Exception { - testDecompile("/HelloWorldProcyon.txt", ENGINE_PROCYON, Map.of("SuppressBanner", "true")); + testDecompile("/TestCompactProcyon.txt", ENGINE_PROCYON, Map.of("SuppressBanner", "true")); } @Test public void testDecompileJADX() throws Exception { - testDecompile("/HelloWorldJADX.txt", ENGINE_JADX, Collections.emptyMap()); + testDecompile("/TestCompactJADX.txt", ENGINE_JADX, Collections.emptyMap()); } @Test public void testDecompileFernflower() throws Exception { - testDecompile("/HelloWorldFernflower.txt", ENGINE_FERNFLOWER, Collections.emptyMap()); + testDecompile("/TestCompactFernflower.txt", ENGINE_FERNFLOWER, Collections.emptyMap()); } @Test public void testDecompileVineflower() throws Exception { - testDecompile("/HelloWorldVineflower.txt", ENGINE_VINEFLOWER, Collections.emptyMap()); + testDecompile("/TestCompactVineflower.txt", ENGINE_VINEFLOWER, Collections.emptyMap()); } @Test public void testDecompileJDCoreV0() throws Exception { - testDecompile("/HelloWorldJDCoreV0.txt", ENGINE_JD_CORE_V0, Collections.emptyMap()); + testDecompile("/TestCompactJDCoreV0.txt", ENGINE_JD_CORE_V0, Collections.emptyMap()); } @Test public void testDecompileJDCoreV1() throws Exception { - testDecompile("/HelloWorldJDCoreV1.txt", ENGINE_JD_CORE_V1, Map.of(WRITE_LINE_NUMBERS, "false", WRITE_METADATA, "false")); + testDecompile("/TestCompactJDCoreV1.txt", ENGINE_JD_CORE_V1, Map.of(WRITE_LINE_NUMBERS, "false", WRITE_METADATA, "false")); } private void testDecompile(String path, String engineName, Map preferences) - throws TransformationException, IOException, IllegalAccessException, InvocationTargetException { - ClassPathLoader classPathLoader = new ClassPathLoader(); - Loader loader = new Loader(classPathLoader::canLoad, classPathLoader::load); - String internalName = HelloWorld.class.getName().replace('.', '/'); + throws TransformationException, IOException, IllegalAccessException, InvocationTargetException, URISyntaxException { + URI resource = getClass().getResource("/test-compact-expand-inline.jar").toURI(); + ZipLoader zipLoader = new ZipLoader(resource.toURL().openStream()); + Loader loader = new Loader(zipLoader::canLoad, zipLoader::load, resource); + String internalName = "test/TestCompact"; DecompilationResult result = StandardTransformers.decompile(loader, internalName, preferences, engineName); assertEqualsIgnoreEOL(getResourceAsString(path), result.getDecompiledOutput()); } diff --git a/src/test/java/com/heliosdecompiler/transformerapi/ZipLoader.java b/src/test/java/com/heliosdecompiler/transformerapi/ZipLoader.java new file mode 100644 index 0000000..e9c2445 --- /dev/null +++ b/src/test/java/com/heliosdecompiler/transformerapi/ZipLoader.java @@ -0,0 +1,28 @@ +package com.heliosdecompiler.transformerapi; + +import org.jd.core.v1.util.StringConstants; + +import java.io.IOException; +import java.io.InputStream; + +public class ZipLoader extends org.jd.core.v1.util.ZipLoader { + + public ZipLoader(InputStream in) throws IOException { + super(in); + } + + @Override + protected String makeEntryName(String entryName) { + return entryName; + } + + @Override + public byte[] load(String internalName) throws IOException { + return getMap().get(internalName + StringConstants.CLASS_FILE_SUFFIX); + } + + @Override + public boolean canLoad(String internalName) { + return getMap().containsKey(internalName + StringConstants.CLASS_FILE_SUFFIX); + } +} \ No newline at end of file diff --git a/src/test/resources/HelloWorldCFR.txt b/src/test/resources/HelloWorldCFR.txt deleted file mode 100644 index d60c70c..0000000 --- a/src/test/resources/HelloWorldCFR.txt +++ /dev/null @@ -1,10 +0,0 @@ -/* - * Decompiled with CFR. - */ -package com.heliosdecompiler.transformerapi; - -public class HelloWorld { - public static void main(String[] args) { - System.out.println("Hello World!"); - } -} diff --git a/src/test/resources/HelloWorldFernflower.txt b/src/test/resources/HelloWorldFernflower.txt deleted file mode 100644 index fdd276b..0000000 --- a/src/test/resources/HelloWorldFernflower.txt +++ /dev/null @@ -1,7 +0,0 @@ -package com.heliosdecompiler.transformerapi; - -public class HelloWorld { - public static void main(String[] args) { - System.out.println("Hello World!"); - } -} diff --git a/src/test/resources/HelloWorldJADX.txt b/src/test/resources/HelloWorldJADX.txt deleted file mode 100644 index d908b0d..0000000 --- a/src/test/resources/HelloWorldJADX.txt +++ /dev/null @@ -1,8 +0,0 @@ -package com.heliosdecompiler.transformerapi; - -/* loaded from: com/heliosdecompiler/transformerapi/HelloWorld */ -public class HelloWorld { - public static void main(java.lang.String[] strArr) { - java.lang.System.out.println("Hello World!"); - } -} \ No newline at end of file diff --git a/src/test/resources/HelloWorldJDCoreV0.txt b/src/test/resources/HelloWorldJDCoreV0.txt deleted file mode 100644 index 248b28d..0000000 --- a/src/test/resources/HelloWorldJDCoreV0.txt +++ /dev/null @@ -1,9 +0,0 @@ -package com.heliosdecompiler.transformerapi; - -public class HelloWorld -{ - public static void main(String[] args) - { - System.out.println("Hello World!"); - } -} diff --git a/src/test/resources/HelloWorldJDCoreV1.txt b/src/test/resources/HelloWorldJDCoreV1.txt deleted file mode 100644 index e5e7a58..0000000 --- a/src/test/resources/HelloWorldJDCoreV1.txt +++ /dev/null @@ -1,7 +0,0 @@ -package com.heliosdecompiler.transformerapi; - -public class HelloWorld { - public static void main(String[] args) { - System.out.println("Hello World!"); - } -} diff --git a/src/test/resources/HelloWorldProcyon.txt b/src/test/resources/HelloWorldProcyon.txt deleted file mode 100644 index 8424717..0000000 --- a/src/test/resources/HelloWorldProcyon.txt +++ /dev/null @@ -1,8 +0,0 @@ -package com.heliosdecompiler.transformerapi; - -public class HelloWorld -{ - public static void main(final String[] args) { - System.out.println("Hello World!"); - } -} diff --git a/src/test/resources/HelloWorldVineflower.txt b/src/test/resources/HelloWorldVineflower.txt deleted file mode 100644 index fdd276b..0000000 --- a/src/test/resources/HelloWorldVineflower.txt +++ /dev/null @@ -1,7 +0,0 @@ -package com.heliosdecompiler.transformerapi; - -public class HelloWorld { - public static void main(String[] args) { - System.out.println("Hello World!"); - } -} diff --git a/src/test/resources/TestCompactCFR.txt b/src/test/resources/TestCompactCFR.txt new file mode 100644 index 0000000..b63a744 --- /dev/null +++ b/src/test/resources/TestCompactCFR.txt @@ -0,0 +1,161 @@ +/* + * Decompiled with CFR. + */ +package test; + +public abstract class TestCompact { + public void method1(boolean flag) { + this.log("Test.method1 start"); + if (flag) { + this.log("Test.method1 if"); + } else { + this.log("Test.method1 else"); + } + this.log("Test.method1 end"); + } + + public void method2() { + this.log("Test.method2 start"); + try { + this.log("Test.method2 try"); + } + catch (Exception e) { + this.log("Test.method2 catch"); + } + finally { + this.log("Test.method2 finally"); + } + this.log("Test.method2 end"); + } + + public void method3(int[] arr) { + this.log("Test.method3 start"); + for (int i = 0; i < arr.length; ++i) { + this.log("Test.method3 for"); + } + this.log("Test.method3 end"); + } + + public void method4(int i) { + this.log("Test.method4 start"); + switch (i) { + case 0: { + this.log("Test.method4 case 0"); + break; + } + case 1: { + this.log("Test.method4 case 1"); + break; + } + case 2: { + this.log("Test.method4 case 2"); + break; + } + case 3: { + this.log("Test.method4 case 3"); + break; + } + default: { + this.log("Test.method4 default"); + } + } + this.log("Test.method4 end"); + } + + public String method5(int i) { + this.log("Test.method5 start"); + String s = switch (i) { + case 0 -> "Test.method4 case 0"; + case 1 -> "Test.method4 case 1"; + case 2 -> "Test.method4 case 2"; + case 3 -> "Test.method4 case 3"; + default -> throw new IllegalArgumentException(); + }; + return "return:" + s; + } + + public void method5() { + this.log("Test.method5"); + } + + public void method6() { + this.log("Test.method6"); + } + + public abstract void log(String var1); + + class Inner4 { + public Inner4() { + TestCompact.this.log("Inner4 constructor"); + } + + public void method1() { + TestCompact.this.log("Inner4.method1"); + } + + public void method2() { + TestCompact.this.log("Inner4.method2"); + } + + public boolean equals(Object o) { + throw new UnsupportedOperationException("equals"); + } + + public int hashCode() { + throw new UnsupportedOperationException("hashCode"); + } + + public String toString() { + throw new UnsupportedOperationException("toString"); + } + } + + class Inner3 { + public Inner3() { + TestCompact.this.log("Inner3 constructor"); + } + + public void method1() { + new Thread(new Runnable(){ + + @Override + public void run() { + TestCompact.this.log("Inner3.method1"); + } + }).start(); + } + + public void method2() { + new Thread(() -> { + TestCompact.this.log("Inner3.method2a"); + TestCompact.this.log("Inner3.method2b"); + }).start(); + } + + public void method3() { + new Thread(() -> TestCompact.this.log("Inner3.method3")).start(); + } + } + + class Inner1 { + public Inner1() { + TestCompact.this.log("Inner1 constructor"); + } + + public void method1(boolean flag) { + TestCompact.this.log("Inner1.method1 start"); + while (flag) { + TestCompact.this.log("Inner1.method1 while"); + } + TestCompact.this.log("Inner1.method1 end"); + } + + public void method2(boolean flag) { + TestCompact.this.log("Inner1.method2 start"); + do { + TestCompact.this.log("Inner1.method2 do while"); + } while (flag); + TestCompact.this.log("Inner1.method2 end"); + } + } +} diff --git a/src/test/resources/TestCompactFernflower.txt b/src/test/resources/TestCompactFernflower.txt new file mode 100644 index 0000000..864ca36 --- /dev/null +++ b/src/test/resources/TestCompactFernflower.txt @@ -0,0 +1,153 @@ +package test; + +public abstract class TestCompact { + public void method1(boolean flag) { + this.log("Test.method1 start"); + if (flag) { + this.log("Test.method1 if"); + } else { + this.log("Test.method1 else"); + } + + this.log("Test.method1 end"); + } + + public void method2() { + this.log("Test.method2 start"); + + try { + this.log("Test.method2 try"); + } catch (Exception var5) { + this.log("Test.method2 catch"); + } finally { + this.log("Test.method2 finally"); + } + + this.log("Test.method2 end"); + } + + public void method3(int[] arr) { + this.log("Test.method3 start"); + + for(int i = 0; i < arr.length; ++i) { + this.log("Test.method3 for"); + } + + this.log("Test.method3 end"); + } + + public void method4(int i) { + this.log("Test.method4 start"); + switch (i) { + case 0 -> this.log("Test.method4 case 0"); + case 1 -> this.log("Test.method4 case 1"); + case 2 -> this.log("Test.method4 case 2"); + case 3 -> this.log("Test.method4 case 3"); + default -> this.log("Test.method4 default"); + } + + this.log("Test.method4 end"); + } + + public String method5(int i) { + this.log("Test.method5 start"); + String var10000; + switch (i) { + case 0 -> var10000 = "Test.method4 case 0"; + case 1 -> var10000 = "Test.method4 case 1"; + case 2 -> var10000 = "Test.method4 case 2"; + case 3 -> var10000 = "Test.method4 case 3"; + default -> throw new IllegalArgumentException(); + } + + String s = var10000; + return "return:" + s; + } + + public void method5() { + this.log("Test.method5"); + } + + public void method6() { + this.log("Test.method6"); + } + + public abstract void log(String var1); + + class Inner1 { + public Inner1() { + TestCompact.this.log("Inner1 constructor"); + } + + public void method1(boolean flag) { + TestCompact.this.log("Inner1.method1 start"); + + while(flag) { + TestCompact.this.log("Inner1.method1 while"); + } + + TestCompact.this.log("Inner1.method1 end"); + } + + public void method2(boolean flag) { + TestCompact.this.log("Inner1.method2 start"); + + do { + TestCompact.this.log("Inner1.method2 do while"); + } while(flag); + + TestCompact.this.log("Inner1.method2 end"); + } + } + + class Inner3 { + public Inner3() { + TestCompact.this.log("Inner3 constructor"); + } + + public void method1() { + (new Thread(new Runnable() { + public void run() { + TestCompact.this.log("Inner3.method1"); + } + })).start(); + } + + public void method2() { + (new Thread(() -> { + TestCompact.this.log("Inner3.method2a"); + TestCompact.this.log("Inner3.method2b"); + })).start(); + } + + public void method3() { + (new Thread(() -> TestCompact.this.log("Inner3.method3"))).start(); + } + } + + class Inner4 { + public Inner4() { + TestCompact.this.log("Inner4 constructor"); + } + + public void method1() { + TestCompact.this.log("Inner4.method1"); + } + + public void method2() { + TestCompact.this.log("Inner4.method2"); + } + + public boolean equals(Object o) { + throw new UnsupportedOperationException("equals"); + } + + public int hashCode() { + throw new UnsupportedOperationException("hashCode"); + } + + public String toString() { + throw new UnsupportedOperationException("toString"); + } + } +} diff --git a/src/test/resources/TestCompactJADX.txt b/src/test/resources/TestCompactJADX.txt new file mode 100644 index 0000000..11999e9 --- /dev/null +++ b/src/test/resources/TestCompactJADX.txt @@ -0,0 +1,94 @@ +package test; + +/* loaded from: test/TestCompact */ +public abstract class TestCompact { + public void method1(boolean z) { + log("Test.method1 start"); + if (z) { + log("Test.method1 if"); + } else { + log("Test.method1 else"); + } + log("Test.method1 end"); + } + + public void method2() { + log("Test.method2 start"); + try { + try { + log("Test.method2 try"); + log("Test.method2 finally"); + } catch (java.lang.Exception e) { + log("Test.method2 catch"); + log("Test.method2 finally"); + } + log("Test.method2 end"); + } catch (java.lang.Throwable th) { + log("Test.method2 finally"); + throw th; + } + } + + public void method3(int[] iArr) { + log("Test.method3 start"); + for (int i = 0; i < iArr.length; i++) { + log("Test.method3 for"); + } + log("Test.method3 end"); + } + + public void method4(int i) { + log("Test.method4 start"); + switch (i) { + case 0: + log("Test.method4 case 0"); + break; + case 1: + log("Test.method4 case 1"); + break; + case 2: + log("Test.method4 case 2"); + break; + case 3: + log("Test.method4 case 3"); + break; + default: + log("Test.method4 default"); + break; + } + log("Test.method4 end"); + } + + /* JADX INFO: Thrown type has an unknown type hierarchy: java.lang.IllegalArgumentException */ + public java.lang.String method5(int i) throws java.lang.IllegalArgumentException { + java.lang.String str; + log("Test.method5 start"); + switch (i) { + case 0: + str = "Test.method4 case 0"; + break; + case 1: + str = "Test.method4 case 1"; + break; + case 2: + str = "Test.method4 case 2"; + break; + case 3: + str = "Test.method4 case 3"; + break; + default: + throw new java.lang.IllegalArgumentException(); + } + return "return:" + str; + } + + public void method5() { + log("Test.method5"); + } + + public void method6() { + log("Test.method6"); + } + + public abstract void log(java.lang.String str); +} \ No newline at end of file diff --git a/src/test/resources/TestCompactJDCoreV0.txt b/src/test/resources/TestCompactJDCoreV0.txt new file mode 100644 index 0000000..29257bb --- /dev/null +++ b/src/test/resources/TestCompactJDCoreV0.txt @@ -0,0 +1,191 @@ +package test; + +public abstract class TestCompact +{ + public void method1(boolean flag) + { + log("Test.method1 start"); + if (flag) { + log("Test.method1 if"); + } else { + log("Test.method1 else"); + } + log("Test.method1 end"); + } + + public void method2() + { + log("Test.method2 start"); + try + { + log("Test.method2 try"); + } + catch (Exception e) + { + log("Test.method2 catch"); + } + finally + { + log("Test.method2 finally"); + } + log("Test.method2 end"); + } + + class Inner1 + { + public Inner1() + { + TestCompact.this.log("Inner1 constructor"); + } + + public void method1(boolean flag) + { + TestCompact.this.log("Inner1.method1 start"); + while (flag) { + TestCompact.this.log("Inner1.method1 while"); + } + TestCompact.this.log("Inner1.method1 end"); + } + + public void method2(boolean flag) + { + TestCompact.this.log("Inner1.method2 start"); + do + { + TestCompact.this.log("Inner1.method2 do while"); + } while (flag); + TestCompact.this.log("Inner1.method2 end"); + } + } + + public void method3(int[] arr) + { + log("Test.method3 start"); + for (int i = 0; i < arr.length; i++) { + log("Test.method3 for"); + } + log("Test.method3 end"); + } + + public void method4(int i) + { + log("Test.method4 start"); + switch (i) + { + case 0: + log("Test.method4 case 0"); + break; + case 1: + log("Test.method4 case 1"); + break; + case 2: + log("Test.method4 case 2"); + break; + case 3: + log("Test.method4 case 3"); + break; + default: + log("Test.method4 default"); + } + log("Test.method4 end"); + } + + public String method5(int i) + { + log("Test.method5 start"); + String s = switch (i) { + case 0 -> "Test.method4 case 0"; + case 1 -> "Test.method4 case 1"; + case 2 -> "Test.method4 case 2"; + case 3 -> "Test.method4 case 3"; + default -> throw new IllegalArgumentException(); + }; + return "return:" + s; + } + + class Inner3 + { + public Inner3() + { + TestCompact.this.log("Inner3 constructor"); + } + + public void method1() + { + new Thread(new Runnable() + { + @Override + public void run() + { + TestCompact.this.log("Inner3.method1"); + } + }).start(); + } + + public void method2() + { + new Thread( + + () -> + { + TestCompact.this.log("Inner3.method2a"); + TestCompact.this.log("Inner3.method2b"); + }).start(); + } + + public void method3() + { + new Thread( + + () -> TestCompact.this.log("Inner3.method3")).start(); + } + } + + class Inner4 + { + public Inner4() + { + TestCompact.this.log("Inner4 constructor"); + } + + public void method1() + { + TestCompact.this.log("Inner4.method1"); + } + + public void method2() + { + TestCompact.this.log("Inner4.method2"); + } + + @Override + public boolean equals(Object o) + { + throw new UnsupportedOperationException("equals"); + } + + @Override + public int hashCode() + { + throw new UnsupportedOperationException("hashCode"); + } + + @Override + public String toString() + { + throw new UnsupportedOperationException("toString"); + } + } + + public void method5() + { + log("Test.method5"); + } + + public void method6() + { + log("Test.method6"); + } + + public abstract void log(String paramString); +} diff --git a/src/test/resources/TestCompactJDCoreV1.txt b/src/test/resources/TestCompactJDCoreV1.txt new file mode 100644 index 0000000..71821d9 --- /dev/null +++ b/src/test/resources/TestCompactJDCoreV1.txt @@ -0,0 +1,150 @@ +package test; + +public abstract class TestCompact { + public void method1(boolean flag) { + log("Test.method1 start"); + if (flag) { + log("Test.method1 if"); + } else + log("Test.method1 else"); + log("Test.method1 end"); + } + + public void method2() { + log("Test.method2 start"); + try { + log("Test.method2 try"); + } catch (Exception e) { + log("Test.method2 catch"); + } finally { + log("Test.method2 finally"); + } + log("Test.method2 end"); + } + + class Inner1 { + public Inner1() { + TestCompact.this.log("Inner1 constructor"); + } + + public void method1(boolean flag) { + TestCompact.this.log("Inner1.method1 start"); + while (flag) + TestCompact.this.log("Inner1.method1 while"); + TestCompact.this.log("Inner1.method1 end"); + } + + public void method2(boolean flag) { + TestCompact.this.log("Inner1.method2 start"); + while (true) { + TestCompact.this.log("Inner1.method2 do while"); + if (!flag) { + TestCompact.this.log("Inner1.method2 end"); + return; + } + } + } + } + + public void method3(int[] arr) { + log("Test.method3 start"); + for (int i = 0; i < arr.length; i++) + log("Test.method3 for"); + log("Test.method3 end"); + } + + public void method4(int i) { + log("Test.method4 start"); + switch (i) { + case 0: + log("Test.method4 case 0"); + break; + case 1: + log("Test.method4 case 1"); + break; + case 2: + log("Test.method4 case 2"); + break; + case 3: + log("Test.method4 case 3"); + break; + default: + log("Test.method4 default"); + break; + } + log("Test.method4 end"); + } + + public String method5(int i) { + log("Test.method5 start"); + String s = switch (i) { + case 0 -> "Test.method4 case 0"; + case 1 -> "Test.method4 case 1"; + case 2 -> "Test.method4 case 2"; + case 3 -> "Test.method4 case 3"; + default -> throw new IllegalArgumentException(); + }; + return "return:" + s; + } + + class Inner3 { + public Inner3() { + TestCompact.this.log("Inner3 constructor"); + } + + public void method1() { + new Thread(new Runnable() { + public void run() { + TestCompact.this.log("Inner3.method1"); + } + }).start(); + } + + public void method2() { + new Thread(() -> { + TestCompact.this.log("Inner3.method2a"); + TestCompact.this.log("Inner3.method2b"); + }).start(); + } + + public void method3() { + new Thread(() -> TestCompact.this.log("Inner3.method3")).start(); + } + } + + class Inner4 { + public Inner4() { + TestCompact.this.log("Inner4 constructor"); + } + + public void method1() { + TestCompact.this.log("Inner4.method1"); + } + + public void method2() { + TestCompact.this.log("Inner4.method2"); + } + + public boolean equals(Object o) { + throw new UnsupportedOperationException("equals"); + } + + public int hashCode() { + throw new UnsupportedOperationException("hashCode"); + } + + public String toString() { + throw new UnsupportedOperationException("toString"); + } + } + + public void method5() { + log("Test.method5"); + } + + public void method6() { + log("Test.method6"); + } + + public abstract void log(String paramString); +} diff --git a/src/test/resources/TestCompactProcyon.txt b/src/test/resources/TestCompactProcyon.txt new file mode 100644 index 0000000..0c56f9a --- /dev/null +++ b/src/test/resources/TestCompactProcyon.txt @@ -0,0 +1,166 @@ +package test; + +public abstract class TestCompact +{ + public void method1(final boolean flag) { + this.log("Test.method1 start"); + if (flag) { + this.log("Test.method1 if"); + } + else { + this.log("Test.method1 else"); + } + this.log("Test.method1 end"); + } + + public void method2() { + this.log("Test.method2 start"); + try { + this.log("Test.method2 try"); + } + catch (final Exception e) { + this.log("Test.method2 catch"); + } + finally { + this.log("Test.method2 finally"); + } + this.log("Test.method2 end"); + } + + public void method3(final int[] arr) { + this.log("Test.method3 start"); + for (int i = 0; i < arr.length; ++i) { + this.log("Test.method3 for"); + } + this.log("Test.method3 end"); + } + + public void method4(final int i) { + this.log("Test.method4 start"); + switch (i) { + case 0: { + this.log("Test.method4 case 0"); + break; + } + case 1: { + this.log("Test.method4 case 1"); + break; + } + case 2: { + this.log("Test.method4 case 2"); + break; + } + case 3: { + this.log("Test.method4 case 3"); + break; + } + default: { + this.log("Test.method4 default"); + break; + } + } + this.log("Test.method4 end"); + } + + public String method5(final int i) { + this.log("Test.method5 start"); + final String s = switch (i) { + case 0 -> "Test.method4 case 0"; + case 1 -> "Test.method4 case 1"; + case 2 -> "Test.method4 case 2"; + case 3 -> "Test.method4 case 3"; + default -> throw new IllegalArgumentException(); + }; + return "return:" + s; + } + + public void method5() { + this.log("Test.method5"); + } + + public void method6() { + this.log("Test.method6"); + } + + public abstract void log(final String p0); + + class Inner1 + { + public Inner1() { + TestCompact.this.log("Inner1 constructor"); + } + + public void method1(final boolean flag) { + TestCompact.this.log("Inner1.method1 start"); + while (flag) { + TestCompact.this.log("Inner1.method1 while"); + } + TestCompact.this.log("Inner1.method1 end"); + } + + public void method2(final boolean flag) { + TestCompact.this.log("Inner1.method2 start"); + do { + TestCompact.this.log("Inner1.method2 do while"); + } while (flag); + TestCompact.this.log("Inner1.method2 end"); + } + } + + class Inner3 + { + public Inner3() { + TestCompact.this.log("Inner3 constructor"); + } + + public void method1() { + new Thread(new Runnable() { + @Override + public void run() { + TestCompact.this.log("Inner3.method1"); + } + }).start(); + } + + public void method2() { + new Thread(() -> { + TestCompact.this.log("Inner3.method2a"); + TestCompact.this.log("Inner3.method2b"); + }).start(); + } + + public void method3() { + new Thread(() -> TestCompact.this.log("Inner3.method3")).start(); + } + } + + class Inner4 + { + public Inner4() { + TestCompact.this.log("Inner4 constructor"); + } + + public void method1() { + TestCompact.this.log("Inner4.method1"); + } + + public void method2() { + TestCompact.this.log("Inner4.method2"); + } + + @Override + public boolean equals(final Object o) { + throw new UnsupportedOperationException("equals"); + } + + @Override + public int hashCode() { + throw new UnsupportedOperationException("hashCode"); + } + + @Override + public String toString() { + throw new UnsupportedOperationException("toString"); + } + } +} diff --git a/src/test/resources/TestCompactVineflower.txt b/src/test/resources/TestCompactVineflower.txt new file mode 100644 index 0000000..e0bf95d --- /dev/null +++ b/src/test/resources/TestCompactVineflower.txt @@ -0,0 +1,160 @@ +package test; + +public abstract class TestCompact { + public void method1(boolean flag) { + this.log("Test.method1 start"); + if (flag) { + this.log("Test.method1 if"); + } else { + this.log("Test.method1 else"); + } + + this.log("Test.method1 end"); + } + + public void method2() { + this.log("Test.method2 start"); + + try { + this.log("Test.method2 try"); + } catch (Exception var5) { + this.log("Test.method2 catch"); + } finally { + this.log("Test.method2 finally"); + } + + this.log("Test.method2 end"); + } + + public void method3(int[] arr) { + this.log("Test.method3 start"); + + for (int i = 0; i < arr.length; i++) { + this.log("Test.method3 for"); + } + + this.log("Test.method3 end"); + } + + public void method4(int i) { + this.log("Test.method4 start"); + switch (i) { + case 0: + this.log("Test.method4 case 0"); + break; + case 1: + this.log("Test.method4 case 1"); + break; + case 2: + this.log("Test.method4 case 2"); + break; + case 3: + this.log("Test.method4 case 3"); + break; + default: + this.log("Test.method4 default"); + } + + this.log("Test.method4 end"); + } + + public String method5(int i) { + this.log("Test.method5 start"); + + String s = switch (i) { + case 0 -> "Test.method4 case 0"; + case 1 -> "Test.method4 case 1"; + case 2 -> "Test.method4 case 2"; + case 3 -> "Test.method4 case 3"; + default -> throw new IllegalArgumentException(); + }; + return "return:" + s; + } + + public void method5() { + this.log("Test.method5"); + } + + public void method6() { + this.log("Test.method6"); + } + + public abstract void log(String var1); + + class Inner1 { + public Inner1() { + TestCompact.this.log("Inner1 constructor"); + } + + public void method1(boolean flag) { + TestCompact.this.log("Inner1.method1 start"); + + while (flag) { + TestCompact.this.log("Inner1.method1 while"); + } + + TestCompact.this.log("Inner1.method1 end"); + } + + public void method2(boolean flag) { + TestCompact.this.log("Inner1.method2 start"); + + do { + TestCompact.this.log("Inner1.method2 do while"); + } while (flag); + + TestCompact.this.log("Inner1.method2 end"); + } + } + + class Inner3 { + public Inner3() { + TestCompact.this.log("Inner3 constructor"); + } + + public void method1() { + new Thread(new Runnable() { + public void run() { + TestCompact.this.log("Inner3.method1"); + } + }).start(); + } + + public void method2() { + new Thread(() -> { + TestCompact.this.log("Inner3.method2a"); + TestCompact.this.log("Inner3.method2b"); + }).start(); + } + + public void method3() { + new Thread(() -> TestCompact.this.log("Inner3.method3")).start(); + } + } + + class Inner4 { + public Inner4() { + TestCompact.this.log("Inner4 constructor"); + } + + public void method1() { + TestCompact.this.log("Inner4.method1"); + } + + public void method2() { + TestCompact.this.log("Inner4.method2"); + } + + public boolean equals(Object o) { + throw new UnsupportedOperationException("equals"); + } + + public int hashCode() { + throw new UnsupportedOperationException("hashCode"); + } + + public String toString() { + throw new UnsupportedOperationException("toString"); + } + } +} From 0b968502b4e7bd4c3a89488c674c37edcd6a33ec Mon Sep 17 00:00:00 2001 From: nbauma109 Date: Thu, 1 Jan 2026 21:18:15 +0100 Subject: [PATCH 2/2] add test resource jar and update gitignore --- .gitignore | 7 ------- .../resources/test-compact-expand-inline.jar | Bin 0 -> 23494 bytes 2 files changed, 7 deletions(-) create mode 100644 src/test/resources/test-compact-expand-inline.jar diff --git a/.gitignore b/.gitignore index 590619d..4c56582 100644 --- a/.gitignore +++ b/.gitignore @@ -168,13 +168,6 @@ $RECYCLE.BIN/ # Mobile Tools for Java (J2ME) .mtj.tmp/ -# Package Files # -*.jar -*.war -*.ear -*.tar.gz -*.rar - # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml hs_err_pid* diff --git a/src/test/resources/test-compact-expand-inline.jar b/src/test/resources/test-compact-expand-inline.jar new file mode 100644 index 0000000000000000000000000000000000000000..cc9084af3e41eb1858c008ee391c4e4dc1cdd8c0 GIT binary patch literal 23494 zcmbrmb97~Yw)UHfZL?zAwv8Rzwr$%<1r^&yRh(38+o;&iP4(}bK7H=nr~97wW{jPG zvi2Tpj6C!C&iR?o+6vMjpr}BQkdQ!W_Muup|L_9^1PUZ8sv<}$DJMq%J^};;0;C`f z0r}?&;QzQx;eUKH>gN@If3vKhoTQkjvI?E7*p2MisEjl%-87suE!D)>WP=jJ9P`$` zBb}5ijil_fOF1ZX`fseG3`%o%t|uyvLkzS%4AN8}faSI0mE)Jc-M}5eFM9sZkN@-f zuN(0Gf89Oa=U<&ooSf-ZK7R?@+1MKxIg?1*+L|~r(ivGBI62uQjyfU>qK1Be2V(^@ z7z*{T4f>CW64r{YE0|cI4T4dkFS826poC>`%pNry!L&9@8KuAwbT8J86kXji1faGa z^OewVF8Z|ly}ezbbSpQy^drg>CiK9OU^N#(8s7wGRuk4RCOR5I>=TE2 z+quY+!@+q%AH&)b_339_J#-%1yRCWi@}Q&^uFG35rcPq+q?`!!fg2p?&t9(yJTpss z`eK9I7R66)v9UoloaC*?vYRfI-=>ECytQ##Q=9|tJIGo|hvvKzqh*d?OT#{|ob*m# zik-4|b4VPBwim~CRdZ{sQGZb>O36rY3t?7sunB>Q>r`zz@h6c9O&p?^d6D}S|&}>pp_P#>D!s#@_&^%vcQ3r-+ z_=i&7!bU^5sYC%^<~4E?Fr`A-_fFMV4KQLeon`os5Kxt!0E8oPK=yj8)I3#c zCpWX#K~~1}>+9Vu>=yAx3S*E43|IgsD%8A8vBvMjI60oza|n$y70L|n(k7^ZQ!be% z#WOiU4>ltJpnFRBFw8kkkXE)pLbj z#GiS4-sD%P4MG&Kh!Mh=I$~>9*cNJS4TQf(VrUO_NzxDufb?4a;HJDHk``jU#O8(h zR>|V=$fY!LA)Z*Pk-OqqAWq@DLoG(@Doi>l-uF|6Zpg!y9safSkUa1HMqiL!)SWY? ze&N1#!nhFfUX(`)_=$7QV?u9AScjC_S4j}HMEgAh%U?iea&u%zkRsb@LNd$ou(#HY zh+md;6l2KHy)Q}uI1R)R_Xlhz0rTsmQB*jL3sU2&KtR?L_vo|}M#&^?q%ao^&zqdbWlt#}HA)%j+!|bvQEn)~5<1U0?$y!d;Reta{*f+H`DmKaj z1dyF3J4V<+99#59BpopXTbLn2DkYnD1hm;b4`CSZP_#8PR&y6^+YUvl>+nEKvE%i# z$l>^QvSE`s3QV!yaAxOc+g;M}^@hk<0}?DE3}v0{==| zOPmxX-3BM3vZFe{)*xGpivxTzts!t}x|*)P;I)&SYEfCa2yr2HXEOb@`uA|zg^J>S z?_n*~0XlQ)_FrWSg;*H-29S2~mh+D0xO1eVjuxKo9_vwVM1*6b>fQOl7|^;(anwlZV76bJ%n@^E}8W)XJa#qke;gW#Pa}(He4(ulOJ$B_@uD&Dw z6v1AyzNx$F{<~~OnX-PTee0m1vNU|GU~^`Kz{E5;x^h1QCb2gr&W*$a$&xMHH#?8$~JSGSgK&2(cxx-GROxtvXmA zB{*tbG@G+bL+E*5#W5;MvP`>uQ0%U46zO~YJe?Su@V@76czKz8$OXdReg_?lA11ak zz~$_%M9wQeyRIjU^Ng)PXZO(qg%gr<>9lu9QLu(PWRb;8|JB!M50Bo%=Ny}@xp;+O zx#|_x3($U>y5Vh-`;|;>1CkUS(L<{CoCp0}ofrUxgKXNu;y0U zPEcs-P)}bD5id;dU`jdO5N7A@?9!i9Zz?&Mw~@*}^2Ul4HW>GPs7&xjp-i&9!X3v6 z(!F#$9Rn-6z>~A8pY4n3ou<+vxLYe;s0>IASkpy87Vc0NhE!N#N{f(f3laH>5Si5H zHLOa1uMhJ2NUhic`F;5##H)|G3cgQ+2Y~)7A)^12lm0IS#;DpT vN(sft^R|X2I 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 LeCKJIg0KD$