diff --git a/FernFlower-Patches/0004-Fix-output-discrepancies-to-produce-stable-output.patch b/FernFlower-Patches/0004-Fix-output-discrepancies-to-produce-stable-output.patch index 2ed01f04..6eb7cc6e 100644 --- a/FernFlower-Patches/0004-Fix-output-discrepancies-to-produce-stable-output.patch +++ b/FernFlower-Patches/0004-Fix-output-discrepancies-to-produce-stable-output.patch @@ -91,6 +91,28 @@ index 75d4d0937f1e39fe630b1318a4ad531de7fbd644..d0ae9a7c3b20de44cb202390cc0dfd4d if (content != null) { out.write(content.getBytes(StandardCharsets.UTF_8)); } +diff --git a/src/org/jetbrains/java/decompiler/main/extern/IFernflowerPreferences.java b/src/org/jetbrains/java/decompiler/main/extern/IFernflowerPreferences.java +index 5448e7900953da79b2bc01f99fd7e8f3080148e7..b509376a6dbc3780f7c14c631bf51b7fc24aa50d 100644 +--- a/src/org/jetbrains/java/decompiler/main/extern/IFernflowerPreferences.java ++++ b/src/org/jetbrains/java/decompiler/main/extern/IFernflowerPreferences.java +@@ -35,6 +35,8 @@ public interface IFernflowerPreferences { + String IGNORE_INVALID_BYTECODE = "iib"; + String VERIFY_ANONYMOUS_CLASSES = "vac"; + ++ String STANDARDIZE_FLOATING_POINT_NUMBERS = "sfn"; ++ + String LOG_LEVEL = "log"; + String MAX_PROCESSING_METHOD = "mpm"; + String RENAME_ENTITIES = "ren"; +@@ -81,6 +83,8 @@ public interface IFernflowerPreferences { + defaults.put(IGNORE_INVALID_BYTECODE, "0"); + defaults.put(VERIFY_ANONYMOUS_CLASSES, "0"); + ++ defaults.put(STANDARDIZE_FLOATING_POINT_NUMBERS, "1"); ++ + defaults.put(LOG_LEVEL, IFernflowerLogger.Severity.INFO.name()); + defaults.put(MAX_PROCESSING_METHOD, "0"); + defaults.put(RENAME_ENTITIES, "0"); diff --git a/src/org/jetbrains/java/decompiler/main/extern/IResultSaver.java b/src/org/jetbrains/java/decompiler/main/extern/IResultSaver.java index fad1ddcfb9d2e43720b4cd3acaa165ba86e94892..cf03900654e427bd435ba6dc2d5a0cec8c8708e4 100644 --- a/src/org/jetbrains/java/decompiler/main/extern/IResultSaver.java @@ -332,7 +354,7 @@ index 82ae0a25a20d2727f611d359e699d6666d1e0ae4..a86f0d2887c6c19cb1d911ec43830eb6 return res; diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/ConstExprent.java b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/ConstExprent.java -index caa160fdc4ff5954b0976b11d81177278ae79ab6..e6363319573d157f5878dfdd93f8e60b44facb64 100644 +index caa160fdc4ff5954b0976b11d81177278ae79ab6..39df4ddd7afa01bba116063323630e514679a01f 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/ConstExprent.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/ConstExprent.java @@ -216,7 +216,7 @@ public class ConstExprent extends Exprent { @@ -340,7 +362,7 @@ index caa160fdc4ff5954b0976b11d81177278ae79ab6..e6363319573d157f5878dfdd93f8e60b yield new TextBuffer("-1.0F / 0.0F"); } - yield new TextBuffer(value.toString()).append('F'); -+ yield new TextBuffer(trimZeros(value.toString())).append('F'); ++ yield new TextBuffer(trimFloat(Float.toString(floatVal), floatVal)).append('F'); } case CodeConstants.TYPE_DOUBLE -> { double doubleVal = (Double)value; @@ -360,24 +382,98 @@ index caa160fdc4ff5954b0976b11d81177278ae79ab6..e6363319573d157f5878dfdd93f8e60b + yield new TextBuffer("-1.0D / 0.0D"); } - yield new TextBuffer(value.toString()); -+ yield new TextBuffer(trimZeros(value.toString())).append('D'); ++ yield new TextBuffer(trimDouble(Double.toString(doubleVal), doubleVal)).append('D'); } case CodeConstants.TYPE_NULL -> new TextBuffer("null"); case CodeConstants.TYPE_OBJECT -> { -@@ -273,6 +273,18 @@ public class ConstExprent extends Exprent { +@@ -273,6 +273,92 @@ public class ConstExprent extends Exprent { }; } -+ // Different JVM implementations/version display Floats and Doubles with different number of trailing zeros. -+ // This trims them all down to only the necessary amount. -+ private static String trimZeros(String value) { -+ int i = value.length() - 1; -+ while (i >= 0 && value.charAt(i) == '0') { -+ i--; ++ // Different JVM implementations/version display Floats and Doubles with different String representations ++ // for the same thing. This trims them all down to only the necessary amount. ++ private static String trimFloat(String value, float start) { ++ // Includes NaN and simple numbers ++ if (value.length() <= 3 || !DecompilerContext.getOption(IFernflowerPreferences.STANDARDIZE_FLOATING_POINT_NUMBERS)) ++ return value; ++ ++ String exp = ""; ++ int eIdx = value.indexOf('E'); ++ if (eIdx != -1) { ++ exp = value.substring(eIdx); ++ value = value.substring(0, eIdx); ++ } ++ ++ // Cut off digits that don't affect the value ++ String temp = value; ++ int dotIdx = value.indexOf('.'); ++ do { ++ value = temp; ++ temp = value.substring(0, value.length() - 1); ++ } while (!temp.isEmpty() && !"-".equals(temp) && Float.parseFloat(temp + exp) == start); ++ ++ if (dotIdx != -1 && value.indexOf('.') == -1) { ++ value += ".0"; ++ } else if (dotIdx != -1) { ++ String integer = value.substring(0, dotIdx); ++ String decimal = value.substring(dotIdx + 1); ++ ++ String rounded = (Integer.parseInt(integer) + 1) + ".0" + exp; ++ if (Float.parseFloat(rounded) == start) ++ return rounded; ++ ++ long decimalVal = 1; ++ for (int i = 0; i < decimal.length() - 1; i++) { ++ decimalVal = (decimalVal - 1) * 10 + decimal.charAt(i) - '0' + 1; ++ rounded = integer + '.' + decimalVal + exp; ++ if (Float.parseFloat(rounded) == start) ++ return rounded; + } -+ if (value.charAt(i) == '.') -+ i++; -+ return value.substring(0, i + 1); ++ } ++ ++ return value + exp; ++ } ++ ++ private static String trimDouble(String value, double start) { ++ // Includes NaN and simple numbers ++ if (value.length() <= 3 || !DecompilerContext.getOption(IFernflowerPreferences.STANDARDIZE_FLOATING_POINT_NUMBERS)) ++ return value; ++ ++ String exp = ""; ++ int eIdx = value.indexOf('E'); ++ if (eIdx != -1) { ++ exp = value.substring(eIdx); ++ value = value.substring(0, eIdx); ++ } ++ ++ // Cut off digits that don't affect the value ++ String temp = value; ++ int dotIdx = value.indexOf('.'); ++ do { ++ value = temp; ++ temp = value.substring(0, value.length() - 1); ++ } while (!temp.isEmpty() && !"-".equals(temp) && Double.parseDouble(temp + exp) == start); ++ ++ if (dotIdx != -1 && value.indexOf('.') == -1) { ++ value += ".0"; ++ } else if (dotIdx != -1) { ++ String integer = value.substring(0, dotIdx); ++ String decimal = value.substring(dotIdx + 1); ++ ++ String rounded = (Long.parseLong(integer) + 1) + ".0" + exp; ++ if (Double.parseDouble(rounded) == start) ++ return rounded; ++ ++ long decimalVal = 1; ++ for (int i = 0; i < decimal.length() - 1; i++) { ++ decimalVal = (decimalVal - 1) * 10 + decimal.charAt(i) - '0' + 1; ++ rounded = integer + '.' + decimalVal + exp; ++ if (Double.parseDouble(rounded) == start) ++ return rounded; ++ } ++ } ++ ++ return value + exp; + } + private boolean inConstantVariable(String classSignature, String variableName) { diff --git a/FernFlower-Patches/0005-Convert-Exprent.bytecode-to-a-BitMap.patch b/FernFlower-Patches/0005-Convert-Exprent.bytecode-to-a-BitMap.patch index 8d42bf04..fb8047f0 100644 --- a/FernFlower-Patches/0005-Convert-Exprent.bytecode-to-a-BitMap.patch +++ b/FernFlower-Patches/0005-Convert-Exprent.bytecode-to-a-BitMap.patch @@ -480,7 +480,7 @@ index 13faa7fd16307e584d00bdf9f990e7cc7245babd..6cc60fd5314369cef21bd56c12e2af8e // getter and setter methods // ***************************************************************************** diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/ConstExprent.java b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/ConstExprent.java -index e6363319573d157f5878dfdd93f8e60b44facb64..29cb0533a353084f83e19b565db6c0e66ab418c1 100644 +index 39df4ddd7afa01bba116063323630e514679a01f..56745ac71bbff7cbf8353579cd09f7482206677f 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/ConstExprent.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/ConstExprent.java @@ -52,20 +52,20 @@ public class ConstExprent extends Exprent { @@ -508,7 +508,7 @@ index e6363319573d157f5878dfdd93f8e60b44facb64..29cb0533a353084f83e19b565db6c0e6 super(EXPRENT_CONST); this.constType = constType; this.value = value; -@@ -423,6 +423,11 @@ public class ConstExprent extends Exprent { +@@ -497,6 +497,11 @@ public class ConstExprent extends Exprent { return boolPermitted; } diff --git a/FernFlower-Patches/0009-Rework-of-Generics-system-for-better-output.patch b/FernFlower-Patches/0009-Rework-of-Generics-system-for-better-output.patch index 67eb4746..ddf3586a 100644 --- a/FernFlower-Patches/0009-Rework-of-Generics-system-for-better-output.patch +++ b/FernFlower-Patches/0009-Rework-of-Generics-system-for-better-output.patch @@ -367,27 +367,25 @@ index 692c1b622ef7e065c9c970cf0a5289f9ca8869f5..f8c413c7b7302b201a739310677d0103 private static IIdentifierRenamer loadHelper(String className, IFernflowerLogger logger) { diff --git a/src/org/jetbrains/java/decompiler/main/extern/IFernflowerPreferences.java b/src/org/jetbrains/java/decompiler/main/extern/IFernflowerPreferences.java -index 5448e7900953da79b2bc01f99fd7e8f3080148e7..bdd34f0382b06687ef7fb3237bbc96ac322bdd5c 100644 +index b509376a6dbc3780f7c14c631bf51b7fc24aa50d..79108dd8772dc9444d66e6ba0cdd7f56ca382fbd 100644 --- a/src/org/jetbrains/java/decompiler/main/extern/IFernflowerPreferences.java +++ b/src/org/jetbrains/java/decompiler/main/extern/IFernflowerPreferences.java -@@ -35,6 +35,8 @@ public interface IFernflowerPreferences { - String IGNORE_INVALID_BYTECODE = "iib"; +@@ -36,6 +36,7 @@ public interface IFernflowerPreferences { String VERIFY_ANONYMOUS_CLASSES = "vac"; + String STANDARDIZE_FLOATING_POINT_NUMBERS = "sfn"; + String INCLUDE_ENTIRE_CLASSPATH = "iec"; -+ + String LOG_LEVEL = "log"; String MAX_PROCESSING_METHOD = "mpm"; - String RENAME_ENTITIES = "ren"; -@@ -81,6 +83,8 @@ public interface IFernflowerPreferences { - defaults.put(IGNORE_INVALID_BYTECODE, "0"); +@@ -84,6 +85,7 @@ public interface IFernflowerPreferences { defaults.put(VERIFY_ANONYMOUS_CLASSES, "0"); + defaults.put(STANDARDIZE_FLOATING_POINT_NUMBERS, "1"); + defaults.put(INCLUDE_ENTIRE_CLASSPATH, "0"); -+ + defaults.put(LOG_LEVEL, IFernflowerLogger.Severity.INFO.name()); defaults.put(MAX_PROCESSING_METHOD, "0"); - defaults.put(RENAME_ENTITIES, "0"); diff --git a/src/org/jetbrains/java/decompiler/main/rels/ClassWrapper.java b/src/org/jetbrains/java/decompiler/main/rels/ClassWrapper.java index 33906d3a433e4421bbf41c6aed5ff566a69a904a..c1126a2b7559e2f8a69a54ee0b7db2ceda3d9776 100644 --- a/src/org/jetbrains/java/decompiler/main/rels/ClassWrapper.java diff --git a/FernFlower-Patches/0010-Improvements-to-var-and-var.patch b/FernFlower-Patches/0010-Improvements-to-var-and-var.patch index 5980330b..46d95a32 100644 --- a/FernFlower-Patches/0010-Improvements-to-var-and-var.patch +++ b/FernFlower-Patches/0010-Improvements-to-var-and-var.patch @@ -114,10 +114,10 @@ index 81b4c480810a2f74388a4626a4dc0c2bfc523365..f0f66146eb4ecad4ed1bbd41712cace8 } } diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/ConstExprent.java b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/ConstExprent.java -index 29cb0533a353084f83e19b565db6c0e66ab418c1..06025ab6d1c96e8bedb91b4efcbd2e00641c477e 100644 +index 56745ac71bbff7cbf8353579cd09f7482206677f..311fe8507fba664bd4b1e627f8ffbdb4c0c97cab 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/ConstExprent.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/ConstExprent.java -@@ -427,7 +427,12 @@ public class ConstExprent extends Exprent { +@@ -501,7 +501,12 @@ public class ConstExprent extends Exprent { public void getBytecodeRange(BitSet values) { measureBytecode(values); } diff --git a/FernFlower-Patches/0011-JAD-Style-variable-naming.patch b/FernFlower-Patches/0011-JAD-Style-variable-naming.patch index 8aef2047..df4721bf 100644 --- a/FernFlower-Patches/0011-JAD-Style-variable-naming.patch +++ b/FernFlower-Patches/0011-JAD-Style-variable-naming.patch @@ -262,10 +262,10 @@ index 0000000000000000000000000000000000000000..872ec764f11131d384e59f08c4aac955 + } +} diff --git a/src/org/jetbrains/java/decompiler/main/extern/IFernflowerPreferences.java b/src/org/jetbrains/java/decompiler/main/extern/IFernflowerPreferences.java -index bdd34f0382b06687ef7fb3237bbc96ac322bdd5c..9641d4ea515d943009e87fe180a9e8a2569e8b14 100644 +index 79108dd8772dc9444d66e6ba0cdd7f56ca382fbd..3cbbb19b4dd705f67d0b2450996f704a9e293168 100644 --- a/src/org/jetbrains/java/decompiler/main/extern/IFernflowerPreferences.java +++ b/src/org/jetbrains/java/decompiler/main/extern/IFernflowerPreferences.java -@@ -51,6 +51,9 @@ public interface IFernflowerPreferences { +@@ -52,6 +52,9 @@ public interface IFernflowerPreferences { String LINE_SEPARATOR_WIN = "\r\n"; String LINE_SEPARATOR_UNX = "\n"; @@ -275,7 +275,7 @@ index bdd34f0382b06687ef7fb3237bbc96ac322bdd5c..9641d4ea515d943009e87fe180a9e8a2 Map DEFAULTS = getDefaults(); static Map getDefaults() { -@@ -93,7 +96,9 @@ public interface IFernflowerPreferences { +@@ -95,7 +98,9 @@ public interface IFernflowerPreferences { defaults.put(BANNER, ""); defaults.put(UNIT_TEST_MODE, "0"); defaults.put(DUMP_ORIGINAL_LINES, "0"); diff --git a/FernFlower-Patches/0015-Add-new-command-line-argument-sef-SkipExtraFiles-To-.patch b/FernFlower-Patches/0015-Add-new-command-line-argument-sef-SkipExtraFiles-To-.patch index 019f39b5..b9a9f3f6 100644 --- a/FernFlower-Patches/0015-Add-new-command-line-argument-sef-SkipExtraFiles-To-.patch +++ b/FernFlower-Patches/0015-Add-new-command-line-argument-sef-SkipExtraFiles-To-.patch @@ -6,10 +6,10 @@ Subject: [PATCH] Add new command line argument -sef SkipExtraFiles: To skip diff --git a/src/org/jetbrains/java/decompiler/main/extern/IFernflowerPreferences.java b/src/org/jetbrains/java/decompiler/main/extern/IFernflowerPreferences.java -index 9641d4ea515d943009e87fe180a9e8a2569e8b14..8337607e067c1c7cdc803058eab4bfb0ba3c9d3c 100644 +index 3cbbb19b4dd705f67d0b2450996f704a9e293168..f5fb8fc913c71b38ab0bffb5479d1f49725469ff 100644 --- a/src/org/jetbrains/java/decompiler/main/extern/IFernflowerPreferences.java +++ b/src/org/jetbrains/java/decompiler/main/extern/IFernflowerPreferences.java -@@ -54,6 +54,8 @@ public interface IFernflowerPreferences { +@@ -55,6 +55,8 @@ public interface IFernflowerPreferences { String USE_JAD_VARNAMING = "jvn"; // Overwrites any Local Variable names with JAD style names String USE_JAD_PARAMETER_RENAMING = "jpr"; // Include parameter names in JAD naming @@ -18,7 +18,7 @@ index 9641d4ea515d943009e87fe180a9e8a2569e8b14..8337607e067c1c7cdc803058eab4bfb0 Map DEFAULTS = getDefaults(); static Map getDefaults() { -@@ -98,6 +100,7 @@ public interface IFernflowerPreferences { +@@ -100,6 +102,7 @@ public interface IFernflowerPreferences { defaults.put(DUMP_ORIGINAL_LINES, "0"); defaults.put(USE_JAD_VARNAMING, "0"); defaults.put(USE_JAD_PARAMETER_RENAMING, "0"); diff --git a/FernFlower-Patches/0022-Fix-shortname-imports-that-are-shadowed-by-super-cla.patch b/FernFlower-Patches/0022-Fix-shortname-imports-that-are-shadowed-by-super-cla.patch index 08a9842e..1158eb40 100644 --- a/FernFlower-Patches/0022-Fix-shortname-imports-that-are-shadowed-by-super-cla.patch +++ b/FernFlower-Patches/0022-Fix-shortname-imports-that-are-shadowed-by-super-cla.patch @@ -169,20 +169,20 @@ index 6b7d72b6f599aaf04f122ff38ca872f469c9727e..cdd93212560a15372002c4d927a9debc +} \ No newline at end of file diff --git a/src/org/jetbrains/java/decompiler/main/extern/IFernflowerPreferences.java b/src/org/jetbrains/java/decompiler/main/extern/IFernflowerPreferences.java -index 8337607e067c1c7cdc803058eab4bfb0ba3c9d3c..ee6f1c77f2267fed499ee60a12ef319d8fc95e9f 100644 +index f5fb8fc913c71b38ab0bffb5479d1f49725469ff..53349248a038cea0ef82cdc2138ca93e722d1d06 100644 --- a/src/org/jetbrains/java/decompiler/main/extern/IFernflowerPreferences.java +++ b/src/org/jetbrains/java/decompiler/main/extern/IFernflowerPreferences.java -@@ -36,6 +36,7 @@ public interface IFernflowerPreferences { - String VERIFY_ANONYMOUS_CLASSES = "vac"; +@@ -37,6 +37,7 @@ public interface IFernflowerPreferences { + String STANDARDIZE_FLOATING_POINT_NUMBERS = "sfn"; String INCLUDE_ENTIRE_CLASSPATH = "iec"; + String QUALIFY_INNER_CLASSES = "qin"; String LOG_LEVEL = "log"; String MAX_PROCESSING_METHOD = "mpm"; -@@ -89,6 +90,7 @@ public interface IFernflowerPreferences { - defaults.put(VERIFY_ANONYMOUS_CLASSES, "0"); +@@ -91,6 +92,7 @@ public interface IFernflowerPreferences { + defaults.put(STANDARDIZE_FLOATING_POINT_NUMBERS, "1"); defaults.put(INCLUDE_ENTIRE_CLASSPATH, "0"); + defaults.put(QUALIFY_INNER_CLASSES, "1"); diff --git a/FernFlower-Patches/0023-Give-nicer-output-for-float-and-double-literals.patch b/FernFlower-Patches/0023-Give-nicer-output-for-float-and-double-literals.patch index c5f335a8..ef7c1286 100644 --- a/FernFlower-Patches/0023-Give-nicer-output-for-float-and-double-literals.patch +++ b/FernFlower-Patches/0023-Give-nicer-output-for-float-and-double-literals.patch @@ -5,16 +5,19 @@ Subject: [PATCH] Give nicer output for float and double literals diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/ConstExprent.java b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/ConstExprent.java -index 06025ab6d1c96e8bedb91b4efcbd2e00641c477e..d6a96b7c613f8ac747149a443e996078613024a8 100644 +index 311fe8507fba664bd4b1e627f8ffbdb4c0c97cab..da281b179a137434b55171d69266a039c7c1f6f1 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/ConstExprent.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/ConstExprent.java -@@ -48,6 +48,69 @@ public class ConstExprent extends Exprent { +@@ -48,6 +48,81 @@ public class ConstExprent extends Exprent { ); private StructMember parent; + + private static final Map PI_DOUBLES = new HashMap<>(); + private static final Map PI_FLOATS = new HashMap<>(); ++ private static final Map FLOAT_CONSTANTS = new HashMap<>(); ++ private static final Map DOUBLE_CONSTANTS = new HashMap<>(); ++ + static { + final double PI_D = Math.PI; + final float PI_F = (float)Math.PI; @@ -73,12 +76,21 @@ index 06025ab6d1c96e8bedb91b4efcbd2e00641c477e..d6a96b7c613f8ac747149a443e996078 + PI_DOUBLES.put(180D / PI_D, new String[] { "(180D / ", ")" }); + PI_FLOATS.put(PI_F / 180F, new String[] { "(", " / 180F)" }); + PI_FLOATS.put(180F / PI_F, new String[] { "(180F / ", ")" }); ++ ++ FLOAT_CONSTANTS.put((float)Integer.MAX_VALUE, "(float)Integer.MAX_VALUE"); ++ FLOAT_CONSTANTS.put((float)Integer.MIN_VALUE, "(float)Integer.MIN_VALUE"); ++ FLOAT_CONSTANTS.put((float)Long.MAX_VALUE, "(float)Long.MAX_VALUE"); ++ FLOAT_CONSTANTS.put((float)Long.MIN_VALUE, "(float)Long.MIN_VALUE"); ++ DOUBLE_CONSTANTS.put((double)Integer.MAX_VALUE, "(double)Integer.MAX_VALUE"); ++ DOUBLE_CONSTANTS.put((double)Integer.MIN_VALUE, "(double)Integer.MIN_VALUE"); ++ DOUBLE_CONSTANTS.put((double)Long.MAX_VALUE, "(double)Long.MAX_VALUE"); ++ DOUBLE_CONSTANTS.put((double)Long.MIN_VALUE, "(double)Long.MIN_VALUE"); + } + private VarType constType; private final Object value; private final boolean boolPermitted; -@@ -185,39 +248,7 @@ public class ConstExprent extends Exprent { +@@ -185,39 +260,7 @@ public class ConstExprent extends Exprent { } yield new TextBuffer(value.toString()).append('L'); } @@ -113,13 +125,13 @@ index 06025ab6d1c96e8bedb91b4efcbd2e00641c477e..d6a96b7c613f8ac747149a443e996078 - else if (floatVal == Float.NEGATIVE_INFINITY) { - yield new TextBuffer("-1.0F / 0.0F"); - } -- yield new TextBuffer(trimZeros(value.toString())).append('F'); +- yield new TextBuffer(trimFloat(Float.toString(floatVal), floatVal)).append('F'); - } + case CodeConstants.TYPE_FLOAT -> createFloat(literal, (Float)value, tracer); case CodeConstants.TYPE_DOUBLE -> { double doubleVal = (Double)value; if (!literal) { -@@ -242,8 +273,31 @@ public class ConstExprent extends Exprent { +@@ -242,8 +285,21 @@ public class ConstExprent extends Exprent { else if (doubleVal == Math.E && !inConstantVariable(MATH_SIG, E)) { yield new FieldExprent(E, MATH_SIG, true, null, FieldDescriptor.DOUBLE_DESCRIPTOR, bytecode).toJava(0, tracer); } @@ -138,7 +150,20 @@ index 06025ab6d1c96e8bedb91b4efcbd2e00641c477e..d6a96b7c613f8ac747149a443e996078 + String[] parts = PI_DOUBLES.get(doubleVal); + yield getPiDouble(tracer).enclose(parts[0], parts[1]); + } ++ else if (DOUBLE_CONSTANTS.containsKey(doubleVal)) { ++ yield new TextBuffer(DOUBLE_CONSTANTS.get(doubleVal)); + } + } + else if (Double.isNaN(doubleVal)) { +@@ -255,7 +311,26 @@ public class ConstExprent extends Exprent { + else if (doubleVal == Double.NEGATIVE_INFINITY) { + yield new TextBuffer("-1.0D / 0.0D"); + } +- yield new TextBuffer(trimDouble(Double.toString(doubleVal), doubleVal)).append('D'); + ++ TextBuffer doubleBuffer = new TextBuffer(trimDouble(Double.toString(doubleVal), doubleVal)).append('D'); ++ ++ if (!literal) { + // Check for cases where a float literal has been upcasted to a double. + // (for instance, double d = .01F results in 0.009999999776482582D without this) + float nearestFloatVal = (float)doubleVal; @@ -146,14 +171,19 @@ index 06025ab6d1c96e8bedb91b4efcbd2e00641c477e..d6a96b7c613f8ac747149a443e996078 + // Value can be represented precisely as both a float and a double. + // Now check if the string representation as a float is nicer/shorter. + // If they're the same, there's no point in the cast and such (e.g. don't decompile 1.0D as (double)1.0F). -+ if (Float.toString(nearestFloatVal).length() < Double.toString(doubleVal).length()) { ++ TextBuffer floatBuffer = createFloat(literal, nearestFloatVal, tracer); ++ if (floatBuffer.length() != doubleBuffer.length()) { + // Include a cast to prevent using the wrong method call in ambiguous cases. -+ yield createFloat(literal, nearestFloatVal, tracer).prepend("(double)"); ++ yield floatBuffer.prepend("(double)"); + } - } - } - else if (Double.isNaN(doubleVal)) { -@@ -273,6 +327,69 @@ public class ConstExprent extends Exprent { ++ } ++ } ++ ++ yield doubleBuffer; + } + case CodeConstants.TYPE_NULL -> new TextBuffer("null"); + case CodeConstants.TYPE_OBJECT -> { +@@ -273,6 +348,73 @@ public class ConstExprent extends Exprent { }; } @@ -195,6 +225,9 @@ index 06025ab6d1c96e8bedb91b4efcbd2e00641c477e..d6a96b7c613f8ac747149a443e996078 + String[] parts = PI_FLOATS.get(floatVal); + return getPiFloat(tracer).enclose(parts[0], parts[1]); + } ++ else if (FLOAT_CONSTANTS.containsKey(floatVal)) { ++ return new TextBuffer(FLOAT_CONSTANTS.get(floatVal)); ++ } + } + else { + // Check for special values that can't be used directly in code @@ -209,7 +242,7 @@ index 06025ab6d1c96e8bedb91b4efcbd2e00641c477e..d6a96b7c613f8ac747149a443e996078 + return new TextBuffer("-1.0F / 0.0F"); + } + } -+ return new TextBuffer(trimZeros(Float.toString(floatVal))).append('F'); ++ return new TextBuffer(trimFloat(Float.toString(floatVal), floatVal)).append('F'); + } + + private TextBuffer getPiDouble(BytecodeMappingTracer tracer) { @@ -220,6 +253,7 @@ index 06025ab6d1c96e8bedb91b4efcbd2e00641c477e..d6a96b7c613f8ac747149a443e996078 + // java.lang.Math doesn't have a float version of pi, unfortunately + return getPiDouble(tracer).prepend("(float)"); + } - // Different JVM implementations/version display Floats and Doubles with different number of trailing zeros. - // This trims them all down to only the necessary amount. - private static String trimZeros(String value) { ++ + // Different JVM implementations/version display Floats and Doubles with different String representations + // for the same thing. This trims them all down to only the necessary amount. + private static String trimFloat(String value, float start) { diff --git a/FernFlower-Patches/0028-Improve-inferred-generic-types.patch b/FernFlower-Patches/0028-Improve-inferred-generic-types.patch index 674a850b..adcffd2d 100644 --- a/FernFlower-Patches/0028-Improve-inferred-generic-types.patch +++ b/FernFlower-Patches/0028-Improve-inferred-generic-types.patch @@ -5,19 +5,19 @@ Subject: [PATCH] Improve inferred generic types diff --git a/src/org/jetbrains/java/decompiler/main/extern/IFernflowerPreferences.java b/src/org/jetbrains/java/decompiler/main/extern/IFernflowerPreferences.java -index ee6f1c77f2267fed499ee60a12ef319d8fc95e9f..9bad04ab4c0cee5afc2623722674e929058062f0 100644 +index 53349248a038cea0ef82cdc2138ca93e722d1d06..a25566f0e6ba9a4f67c6412fc379874ffca92c21 100644 --- a/src/org/jetbrains/java/decompiler/main/extern/IFernflowerPreferences.java +++ b/src/org/jetbrains/java/decompiler/main/extern/IFernflowerPreferences.java -@@ -37,6 +37,7 @@ public interface IFernflowerPreferences { - +@@ -38,6 +38,7 @@ public interface IFernflowerPreferences { + String STANDARDIZE_FLOATING_POINT_NUMBERS = "sfn"; String INCLUDE_ENTIRE_CLASSPATH = "iec"; String QUALIFY_INNER_CLASSES = "qin"; + String EXPLICIT_GENERIC_ARGUMENTS = "ega"; String LOG_LEVEL = "log"; String MAX_PROCESSING_METHOD = "mpm"; -@@ -91,6 +92,7 @@ public interface IFernflowerPreferences { - +@@ -93,6 +94,7 @@ public interface IFernflowerPreferences { + defaults.put(STANDARDIZE_FLOATING_POINT_NUMBERS, "1"); defaults.put(INCLUDE_ENTIRE_CLASSPATH, "0"); defaults.put(QUALIFY_INNER_CLASSES, "1"); + defaults.put(EXPLICIT_GENERIC_ARGUMENTS, "0"); @@ -47,7 +47,7 @@ index 88b429ca3bc60303f9075eab36e279f9c58f4520..b03bcfc45ba7d58bcfc92612460c7f3d public int getExprentUse() { return array.getExprentUse() & index.getExprentUse() & Exprent.MULTIPLE_USES; diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/ConstExprent.java b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/ConstExprent.java -index d6a96b7c613f8ac747149a443e996078613024a8..aa922882d5abd2395921bdea4173305810d88335 100644 +index da281b179a137434b55171d69266a039c7c1f6f1..6526b901bc08d5b3a21f0ee3ea31661d86d23799 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/ConstExprent.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/ConstExprent.java @@ -4,6 +4,7 @@ package org.jetbrains.java.decompiler.modules.decompiler.exps; @@ -58,7 +58,7 @@ index d6a96b7c613f8ac747149a443e996078613024a8..aa922882d5abd2395921bdea41733058 import org.jetbrains.java.decompiler.main.collectors.BytecodeMappingTracer; import org.jetbrains.java.decompiler.main.extern.IFernflowerPreferences; import org.jetbrains.java.decompiler.modules.decompiler.ExprProcessor; -@@ -134,6 +135,12 @@ public class ConstExprent extends Exprent { +@@ -146,6 +147,12 @@ public class ConstExprent extends Exprent { this.value = value; this.boolPermitted = boolPermitted; addBytecodeOffsets(bytecodeOffsets); diff --git a/FernFlower-Patches/0031-Simple-lambda-syntax-support-isl-0-to-disable.patch b/FernFlower-Patches/0031-Simple-lambda-syntax-support-isl-0-to-disable.patch index c2a39de9..0cfd6472 100644 --- a/FernFlower-Patches/0031-Simple-lambda-syntax-support-isl-0-to-disable.patch +++ b/FernFlower-Patches/0031-Simple-lambda-syntax-support-isl-0-to-disable.patch @@ -120,10 +120,10 @@ index 6f2f8419d41a240c6d1428be0b0ca9258f058127..d9c338ff9189953329a0812250fb4946 } finally { diff --git a/src/org/jetbrains/java/decompiler/main/extern/IFernflowerPreferences.java b/src/org/jetbrains/java/decompiler/main/extern/IFernflowerPreferences.java -index 9bad04ab4c0cee5afc2623722674e929058062f0..1e1d3bd20fe462b6df4dad18a4dea2b611376298 100644 +index a25566f0e6ba9a4f67c6412fc379874ffca92c21..f5e95e65a807e335ce33a589348e11ad1dbbf5fe 100644 --- a/src/org/jetbrains/java/decompiler/main/extern/IFernflowerPreferences.java +++ b/src/org/jetbrains/java/decompiler/main/extern/IFernflowerPreferences.java -@@ -38,6 +38,7 @@ public interface IFernflowerPreferences { +@@ -39,6 +39,7 @@ public interface IFernflowerPreferences { String INCLUDE_ENTIRE_CLASSPATH = "iec"; String QUALIFY_INNER_CLASSES = "qin"; String EXPLICIT_GENERIC_ARGUMENTS = "ega"; @@ -131,7 +131,7 @@ index 9bad04ab4c0cee5afc2623722674e929058062f0..1e1d3bd20fe462b6df4dad18a4dea2b6 String LOG_LEVEL = "log"; String MAX_PROCESSING_METHOD = "mpm"; -@@ -93,6 +94,7 @@ public interface IFernflowerPreferences { +@@ -95,6 +96,7 @@ public interface IFernflowerPreferences { defaults.put(INCLUDE_ENTIRE_CLASSPATH, "0"); defaults.put(QUALIFY_INNER_CLASSES, "1"); defaults.put(EXPLICIT_GENERIC_ARGUMENTS, "0"); diff --git a/FernFlower-Patches/0038-Make-decomp-threaded.patch b/FernFlower-Patches/0038-Make-decomp-threaded.patch index 55c24925..2b9d615f 100644 --- a/FernFlower-Patches/0038-Make-decomp-threaded.patch +++ b/FernFlower-Patches/0038-Make-decomp-threaded.patch @@ -651,10 +651,10 @@ index c9ece039b0d986c1d84b62426a65e6780ddc80e1..3ca43800b47e1d26a1dc036f21cb6e6e public void endReadingClass() { } diff --git a/src/org/jetbrains/java/decompiler/main/extern/IFernflowerPreferences.java b/src/org/jetbrains/java/decompiler/main/extern/IFernflowerPreferences.java -index 1e1d3bd20fe462b6df4dad18a4dea2b611376298..e9aa42e6801916d0acad2541d88b8ad780d60d8e 100644 +index f5e95e65a807e335ce33a589348e11ad1dbbf5fe..19ba388f94dfd41c9a544ea58295ef6f69141738 100644 --- a/src/org/jetbrains/java/decompiler/main/extern/IFernflowerPreferences.java +++ b/src/org/jetbrains/java/decompiler/main/extern/IFernflowerPreferences.java -@@ -39,6 +39,7 @@ public interface IFernflowerPreferences { +@@ -40,6 +40,7 @@ public interface IFernflowerPreferences { String QUALIFY_INNER_CLASSES = "qin"; String EXPLICIT_GENERIC_ARGUMENTS = "ega"; String INLINE_SIMPLE_LAMBDAS = "isl"; @@ -662,7 +662,7 @@ index 1e1d3bd20fe462b6df4dad18a4dea2b611376298..e9aa42e6801916d0acad2541d88b8ad7 String LOG_LEVEL = "log"; String MAX_PROCESSING_METHOD = "mpm"; -@@ -95,6 +96,7 @@ public interface IFernflowerPreferences { +@@ -97,6 +98,7 @@ public interface IFernflowerPreferences { defaults.put(QUALIFY_INNER_CLASSES, "1"); defaults.put(EXPLICIT_GENERIC_ARGUMENTS, "0"); defaults.put(INLINE_SIMPLE_LAMBDAS, "1"); diff --git a/FernFlower-Patches/0039-Expose-line-mapping-information-in-archive-mode.patch b/FernFlower-Patches/0039-Expose-line-mapping-information-in-archive-mode.patch index 791f9708..4501e39d 100644 --- a/FernFlower-Patches/0039-Expose-line-mapping-information-in-archive-mode.patch +++ b/FernFlower-Patches/0039-Expose-line-mapping-information-in-archive-mode.patch @@ -136,10 +136,10 @@ index 98fe00844f7b4d5bbdcef09e379bb8e634a96dff..114b7ab0681c661c5486e20f42993402 } catch (IOException e) { DecompilerContext.getLogger().writeMessage("Cannot write entry " + entryName + " to " + file, e); diff --git a/src/org/jetbrains/java/decompiler/main/extern/IFernflowerPreferences.java b/src/org/jetbrains/java/decompiler/main/extern/IFernflowerPreferences.java -index e9aa42e6801916d0acad2541d88b8ad780d60d8e..16b7767ac7488d78b34b7fe0113867fd3283d2a0 100644 +index 19ba388f94dfd41c9a544ea58295ef6f69141738..2a5d4e6285a08d313ff3ba97ec07d1765d5db923 100644 --- a/src/org/jetbrains/java/decompiler/main/extern/IFernflowerPreferences.java +++ b/src/org/jetbrains/java/decompiler/main/extern/IFernflowerPreferences.java -@@ -60,6 +60,8 @@ public interface IFernflowerPreferences { +@@ -61,6 +61,8 @@ public interface IFernflowerPreferences { String SKIP_EXTRA_FILES = "sef"; @@ -148,7 +148,7 @@ index e9aa42e6801916d0acad2541d88b8ad780d60d8e..16b7767ac7488d78b34b7fe0113867fd Map DEFAULTS = getDefaults(); static Map getDefaults() { -@@ -109,6 +111,7 @@ public interface IFernflowerPreferences { +@@ -111,6 +113,7 @@ public interface IFernflowerPreferences { defaults.put(USE_JAD_VARNAMING, "0"); defaults.put(USE_JAD_PARAMETER_RENAMING, "0"); defaults.put(SKIP_EXTRA_FILES, "0"); diff --git a/FernFlower-Patches/0045-Reduce-allocations-in-getAllExprents.patch b/FernFlower-Patches/0045-Reduce-allocations-in-getAllExprents.patch index b706f180..dd16b525 100644 --- a/FernFlower-Patches/0045-Reduce-allocations-in-getAllExprents.patch +++ b/FernFlower-Patches/0045-Reduce-allocations-in-getAllExprents.patch @@ -68,10 +68,10 @@ index c713a4055dfc5aa05143a6cd856c5bd98e05c8c1..a67a38179233f983107222a963a3c766 lst.add(right); return lst; diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/ConstExprent.java b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/ConstExprent.java -index aa922882d5abd2395921bdea4173305810d88335..bd2f432a1bed30237c71f9c483ee8942c67d989b 100644 +index 6526b901bc08d5b3a21f0ee3ea31661d86d23799..8cac6350d5053b9f0b66030ca848cd9675106ba8 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/ConstExprent.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/ConstExprent.java -@@ -187,8 +187,8 @@ public class ConstExprent extends Exprent { +@@ -199,8 +199,8 @@ public class ConstExprent extends Exprent { } @Override