diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 12233a8ebb..c34e3df451 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -4,7 +4,7 @@ jobs: build: strategy: matrix: - java: [11, 17, 19] + java: [17, 21] runs-on: ubuntu-22.04 container: image: eclipse-temurin:${{ matrix.java }} diff --git a/build.gradle b/build.gradle index 07d2958634..319d94191b 100644 --- a/build.gradle +++ b/build.gradle @@ -25,12 +25,12 @@ allprojects { group = 'org.vineflower' compileJava { - sourceCompatibility = '11' - targetCompatibility = '11' + sourceCompatibility = '17' + targetCompatibility = '17' } java.toolchain { - languageVersion = JavaLanguageVersion.of(11) + languageVersion = JavaLanguageVersion.of(17) } repositories { @@ -56,7 +56,7 @@ allprojects { group = 'org.vineflower' archivesBaseName = 'vineflower' -version = '1.10.0' +version = '1.11.0' def ENV = System.getenv() version = version + (ENV.GITHUB_ACTIONS ? "" : "+local") diff --git a/plugins/kotlin/testData/results/pkg/TestTailrecFunctions.dec b/plugins/kotlin/testData/results/pkg/TestTailrecFunctions.dec index 39e7eeff61..4335d2ebed 100644 --- a/plugins/kotlin/testData/results/pkg/TestTailrecFunctions.dec +++ b/plugins/kotlin/testData/results/pkg/TestTailrecFunctions.dec @@ -75,9 +75,9 @@ class TestTailrecFunctions { var var12: Long = acc; while (var10 != 0L) {// 44 - if (var10 % (long)2 == 0L) {// 45 + if (var10 % 2 == 0L) {// 45 var var21: Long = var8 * var8; - var var23: Long = var10 / (long)2; + var var23: Long = var10 / 2; var7 = var7; var8 = var21; var10 = var23; @@ -117,13 +117,13 @@ class TestTailrecFunctions { break; } - if (var8 % (long)2 != 0L) {// 51 + if (var8 % 2 != 0L) {// 51 var10000 = var6 * var5.fastPow(var6, var8 - 1L);// 52 break; } var var15: Long = var6 * var6; - var var17: Long = var8 / (long)2; + var var17: Long = var8 / 2; var5 = var5; var6 = var15; var8 = var17; diff --git a/plugins/variable-renaming/src/main/java/org/vineflower/variablerenaming/JADNameProvider.java b/plugins/variable-renaming/src/main/java/org/vineflower/variablerenaming/JADNameProvider.java index 408e31b3d1..2d5c3b100b 100644 --- a/plugins/variable-renaming/src/main/java/org/vineflower/variablerenaming/JADNameProvider.java +++ b/plugins/variable-renaming/src/main/java/org/vineflower/variablerenaming/JADNameProvider.java @@ -27,7 +27,6 @@ import org.jetbrains.java.decompiler.code.CodeConstants; import org.jetbrains.java.decompiler.main.DecompilerContext; -import org.jetbrains.java.decompiler.main.extern.IFernflowerPreferences; import org.jetbrains.java.decompiler.main.extern.IVariableNameProvider; import org.jetbrains.java.decompiler.main.extern.IVariableNamingFactory; import org.jetbrains.java.decompiler.modules.decompiler.ExprProcessor; @@ -35,7 +34,6 @@ import org.jetbrains.java.decompiler.struct.StructMethod; import org.jetbrains.java.decompiler.struct.gen.MethodDescriptor; import org.jetbrains.java.decompiler.struct.gen.VarType; -import org.jetbrains.java.decompiler.util.Pair; public class JADNameProvider implements IVariableNameProvider { private HashMap last; @@ -103,7 +101,7 @@ public Holder(int t1, boolean skip_zero, List names) { } @Override - public Map rename(Map> entries) { + public Map renameVariables(Map entries) { int params = 0; if ((this.method.getAccessFlags() & CodeConstants.ACC_STATIC) != CodeConstants.ACC_STATIC) { params++; @@ -119,7 +117,7 @@ public Map rename(Map result = new LinkedHashMap<>(); for (VarVersionPair ver : keys) { - String type = cleanType(entries.get(ver).b); + String type = cleanType(entries.get(ver).typeName()); if ("this".equals(type)) { continue; } diff --git a/plugins/variable-renaming/src/main/java/org/vineflower/variablerenaming/SimpleNameProvider.java b/plugins/variable-renaming/src/main/java/org/vineflower/variablerenaming/SimpleNameProvider.java new file mode 100644 index 0000000000..3bd73da6ab --- /dev/null +++ b/plugins/variable-renaming/src/main/java/org/vineflower/variablerenaming/SimpleNameProvider.java @@ -0,0 +1,93 @@ +package org.vineflower.variablerenaming; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import org.jetbrains.java.decompiler.code.CodeConstants; +import org.jetbrains.java.decompiler.main.DecompilerContext; +import org.jetbrains.java.decompiler.main.extern.IVariableNameProvider; +import org.jetbrains.java.decompiler.main.extern.IVariableNamingFactory; +import org.jetbrains.java.decompiler.modules.decompiler.vars.VarVersionPair; +import org.jetbrains.java.decompiler.struct.StructMethod; +import org.jetbrains.java.decompiler.struct.gen.MethodDescriptor; +import org.jetbrains.java.decompiler.struct.gen.VarType; + +public class SimpleNameProvider implements IVariableNameProvider { + private final boolean renameParameters; + private final StructMethod method; + private final Map usedNames = new HashMap<>(); + private final Map parameters = new HashMap<>(); + + public SimpleNameProvider(boolean renameParameters, StructMethod method) { + this.renameParameters = renameParameters; + this.method = method; + } + + @Override + public Map renameVariables(Map entries) { + int params = 0; + if ((this.method.getAccessFlags() & CodeConstants.ACC_STATIC) != CodeConstants.ACC_STATIC) { + params++; + } + + MethodDescriptor md = MethodDescriptor.parseDescriptor(this.method.getDescriptor()); + for (VarType param : md.params) { + params += param.stackSize; + } + + List keys = new ArrayList<>(entries.keySet()); + Collections.sort(keys, (o1, o2) -> (o1.var != o2.var) ? o1.var - o2.var : o1.version - o2.version); + + Map result = new LinkedHashMap<>(); + for (VarVersionPair ver : keys) { + String origName = entries.get(ver).lvt().getName(); + if (origName == null) { + origName = "lv"; + } + final String origNameFinal = origName; + if (ver.var >= params) { + this.method.getLocalVariableAttr().getMapNames(); + result.put(ver, getNewName(origNameFinal)); + } else if (renameParameters) { + result.put(ver, this.parameters.computeIfAbsent(ver.var, k -> getNewName(origNameFinal))); + } + } + + return result; + } + + private String getNewName(String name) { + int timesUsed = this.usedNames.compute(name, (k, v) -> v == null ? 1 : v + 1); + if (timesUsed == 1) { + return name; + } + return name + (timesUsed - 2); + } + + @Override + public String renameParameter(int flags, VarType type, String name, int index) { + if (!this.renameParameters) { + return IVariableNameProvider.super.renameParameter(flags, type, name, index); + } + return this.parameters.computeIfAbsent(index, k -> getNewName(name)); + } + + @Override + public void addParentContext(IVariableNameProvider renamer) { + if (renamer instanceof SimpleNameProvider s) { + s.usedNames.forEach((k, v) -> this.usedNames.merge(k, v, Integer::sum)); + } + } + + public static class SimpleNameProviderFactory implements IVariableNamingFactory { + + @Override + public IVariableNameProvider createFactory(StructMethod structMethod) { + return new SimpleNameProvider( + DecompilerContext.getOption(VariableRenamingOptions.RENAME_PARAMETERS), structMethod); + } + } +} diff --git a/plugins/variable-renaming/src/main/java/org/vineflower/variablerenaming/TinyNameProvider.java b/plugins/variable-renaming/src/main/java/org/vineflower/variablerenaming/TinyNameProvider.java index dd59747082..3d7f464ffe 100644 --- a/plugins/variable-renaming/src/main/java/org/vineflower/variablerenaming/TinyNameProvider.java +++ b/plugins/variable-renaming/src/main/java/org/vineflower/variablerenaming/TinyNameProvider.java @@ -2,7 +2,6 @@ import org.jetbrains.java.decompiler.code.CodeConstants; import org.jetbrains.java.decompiler.main.DecompilerContext; -import org.jetbrains.java.decompiler.main.collectors.ImportCollector; import org.jetbrains.java.decompiler.main.extern.IVariableNameProvider; import org.jetbrains.java.decompiler.main.extern.IVariableNamingFactory; import org.jetbrains.java.decompiler.modules.decompiler.ExprProcessor; @@ -29,7 +28,7 @@ public TinyNameProvider(boolean renameParameters, StructMethod method) { } @Override - public Map rename(Map> entries) { + public Map renameVariables(Map entries) { int params = 0; if ((this.method.getAccessFlags() & CodeConstants.ACC_STATIC) != CodeConstants.ACC_STATIC) { params++; @@ -45,12 +44,12 @@ public Map rename(Map result = new LinkedHashMap<>(); for (VarVersionPair ver : keys) { - String type = cleanType(entries.get(ver).b); + String type = cleanType(entries.get(ver).typeName()); if (ver.var >= params) { - result.put(ver, getNewName(Pair.of(entries.get(ver).a, type))); + result.put(ver, getNewName(Pair.of(entries.get(ver).type(), type))); } else if (renameParameters) { - result.put(ver, this.parameters.computeIfAbsent(ver.var, k -> getNewName(Pair.of(entries.get(ver).a, type)))); + result.put(ver, this.parameters.computeIfAbsent(ver.var, k -> getNewName(Pair.of(entries.get(ver).type(), type)))); } } diff --git a/plugins/variable-renaming/src/main/java/org/vineflower/variablerenaming/VariableRenamingPlugin.java b/plugins/variable-renaming/src/main/java/org/vineflower/variablerenaming/VariableRenamingPlugin.java index 185d44990f..954b809af7 100644 --- a/plugins/variable-renaming/src/main/java/org/vineflower/variablerenaming/VariableRenamingPlugin.java +++ b/plugins/variable-renaming/src/main/java/org/vineflower/variablerenaming/VariableRenamingPlugin.java @@ -41,5 +41,6 @@ public String description() { static { Renamers.registerProvider("jad", new JADNameProvider.JADNameProviderFactory()); Renamers.registerProvider("tiny", new TinyNameProvider.TinyNameProviderFactory()); + Renamers.registerProvider("fix_clashing_lvt", new SimpleNameProvider.SimpleNameProviderFactory()); } } diff --git a/plugins/variable-renaming/src/test/java/org/vineflower/variablerenaming/VariableRenamingTest.java b/plugins/variable-renaming/src/test/java/org/vineflower/variablerenaming/VariableRenamingTest.java index ab969a6907..9e8118912d 100644 --- a/plugins/variable-renaming/src/test/java/org/vineflower/variablerenaming/VariableRenamingTest.java +++ b/plugins/variable-renaming/src/test/java/org/vineflower/variablerenaming/VariableRenamingTest.java @@ -13,6 +13,7 @@ protected void registerAll() { register(JAVA_8, "TestJADNaming"); // TODO: loop part fails registerRaw(CUSTOM, "TestJadLvtCollision"); // created by placing a class in java8 sources and remapping its param using tinyremapper + register(JAVA_8, "TestJADLocalClasses"); }, IFernflowerPreferences.BYTECODE_SOURCE_MAPPING, "1", IFernflowerPreferences.DUMP_ORIGINAL_LINES, "1", IFernflowerPreferences.DUMP_EXCEPTION_ON_ERROR, "0", diff --git a/plugins/variable-renaming/testData/results/pkg/TestJADLocalClasses.dec b/plugins/variable-renaming/testData/results/pkg/TestJADLocalClasses.dec new file mode 100644 index 0000000000..117c32ede0 --- /dev/null +++ b/plugins/variable-renaming/testData/results/pkg/TestJADLocalClasses.dec @@ -0,0 +1,38 @@ +package pkg; + +public class TestJADLocalClasses { + public void function() { + int i = 0;// 5 + + class Test { + Test() { + int j = 0;// 8 + }// 9 + } + + }// 11 +} + +class 'pkg/TestJADLocalClasses' { + method 'function ()V' { + 0 4 + 1 4 + 2 12 + } +} + +class 'pkg/TestJADLocalClasses$1Test' { + method ' (Lpkg/TestJADLocalClasses;)V' { + 9 8 + a 8 + b 9 + } +} + +Lines mapping: +5 <-> 5 +8 <-> 9 +9 <-> 10 +11 <-> 13 +Not mapped: +7 diff --git a/plugins/variable-renaming/testData/src/java8/pkg/TestJADLocalClasses.java b/plugins/variable-renaming/testData/src/java8/pkg/TestJADLocalClasses.java new file mode 100644 index 0000000000..baa49e221b --- /dev/null +++ b/plugins/variable-renaming/testData/src/java8/pkg/TestJADLocalClasses.java @@ -0,0 +1,12 @@ +package pkg; + +public class TestJADLocalClasses { + public void function() { + int a = 0; + class Test { + Test() { + int b = 0; + } + } + } +} diff --git a/src/org/jetbrains/java/decompiler/code/BytecodeVersion.java b/src/org/jetbrains/java/decompiler/code/BytecodeVersion.java index ba919b14c3..e0ba94718c 100644 --- a/src/org/jetbrains/java/decompiler/code/BytecodeVersion.java +++ b/src/org/jetbrains/java/decompiler/code/BytecodeVersion.java @@ -42,7 +42,7 @@ public boolean hasSwitchExpressions() { } public boolean hasSwitchPatternMatch() { - return previewFrom(MAJOR_17); + return previewReleased(MAJOR_17, MAJOR_21); } public boolean hasSealedClasses() { @@ -112,4 +112,8 @@ public int hashCode() { public static final int MAJOR_15 = 59; public static final int MAJOR_16 = 60; public static final int MAJOR_17 = 61; + public static final int MAJOR_18 = 62; + public static final int MAJOR_19 = 63; + public static final int MAJOR_20 = 64; + public static final int MAJOR_21 = 65; } diff --git a/src/org/jetbrains/java/decompiler/main/ClassWriter.java b/src/org/jetbrains/java/decompiler/main/ClassWriter.java index 22e9ca34eb..8fdcc90d16 100644 --- a/src/org/jetbrains/java/decompiler/main/ClassWriter.java +++ b/src/org/jetbrains/java/decompiler/main/ClassWriter.java @@ -1208,7 +1208,7 @@ else if (methodWrapper.varproc.getVarFinal(new VarVersionPair(index, 0)) == VarT String clashingName = methodWrapper.varproc.getClashingName(new VarVersionPair(index, 0)); if (clashingName != null) { parameterName = clashingName; - } else if (methodParameters != null && i < methodParameters.size()) { + } else if (methodParameters != null && i < methodParameters.size() && methodParameters.get(i).myName != null) { parameterName = methodParameters.get(i).myName; } else { parameterName = methodWrapper.varproc.getVarName(new VarVersionPair(index, 0)); diff --git a/src/org/jetbrains/java/decompiler/main/ClassesProcessor.java b/src/org/jetbrains/java/decompiler/main/ClassesProcessor.java index 287ce0f5cd..1fc3c0a1f1 100644 --- a/src/org/jetbrains/java/decompiler/main/ClassesProcessor.java +++ b/src/org/jetbrains/java/decompiler/main/ClassesProcessor.java @@ -36,6 +36,8 @@ import java.util.*; import java.util.Map.Entry; import java.util.concurrent.ConcurrentHashMap; +import java.util.regex.Matcher; +import java.util.regex.Pattern; public class ClassesProcessor implements CodeConstants { public static final int AVERAGE_CLASS_SIZE = 16 * 1024; @@ -94,8 +96,17 @@ public void loadClasses(IIdentifierRenamer renamer) { boolean bDecompileInner = DecompilerContext.getOption(IFernflowerPreferences.DECOMPILE_INNER); boolean verifyAnonymousClasses = DecompilerContext.getOption(IFernflowerPreferences.VERIFY_ANONYMOUS_CLASSES); + Matcher excludedMatcher = null; + String excludedRegex = DecompilerContext.getProperty(IFernflowerPreferences.EXCLUDED_CLASSES).toString(); + if (!excludedRegex.isEmpty()) { + excludedMatcher = Pattern.compile(excludedRegex).matcher(""); + } + // create class nodes for (StructClass cl : context.getOwnClasses()) { + if (excludedMatcher != null && excludedMatcher.reset(cl.qualifiedName).matches()) { + continue; + } if (!mapRootClasses.containsKey(cl.qualifiedName)) { if (bDecompileInner) { StructInnerClassesAttribute inner = cl.getAttribute(StructGeneralAttribute.ATTRIBUTE_INNER_CLASSES); @@ -563,9 +574,8 @@ private static void destroyWrappers(ClassNode node) { node.classStruct.releaseResources(); node.classStruct.getMethods().forEach(m -> m.clearVariableNamer()); - for (ClassNode nd : node.nested) { - destroyWrappers(nd); - } + // Don't destroy inner node wrappers, they may still be needed to process constructor + // invocations etc. from other classes. } public Map getMapRootClasses() { diff --git a/src/org/jetbrains/java/decompiler/main/IdentityRenamerFactory.java b/src/org/jetbrains/java/decompiler/main/IdentityRenamerFactory.java index d49b0ed8ff..adc2aeb8fb 100644 --- a/src/org/jetbrains/java/decompiler/main/IdentityRenamerFactory.java +++ b/src/org/jetbrains/java/decompiler/main/IdentityRenamerFactory.java @@ -21,8 +21,6 @@ import org.jetbrains.java.decompiler.main.extern.IVariableNamingFactory; import org.jetbrains.java.decompiler.modules.decompiler.vars.VarVersionPair; import org.jetbrains.java.decompiler.struct.StructMethod; -import org.jetbrains.java.decompiler.struct.gen.VarType; -import org.jetbrains.java.decompiler.util.Pair; public class IdentityRenamerFactory implements IVariableNamingFactory, IVariableNameProvider { @Override @@ -31,7 +29,7 @@ public IVariableNameProvider createFactory(StructMethod method) { } @Override - public Map rename(Map> variables) { + public Map renameVariables(Map variables) { return null; } diff --git a/src/org/jetbrains/java/decompiler/main/extern/IFernflowerPreferences.java b/src/org/jetbrains/java/decompiler/main/extern/IFernflowerPreferences.java index b2f4b2acd0..e674a7c31b 100644 --- a/src/org/jetbrains/java/decompiler/main/extern/IFernflowerPreferences.java +++ b/src/org/jetbrains/java/decompiler/main/extern/IFernflowerPreferences.java @@ -382,6 +382,11 @@ public interface IFernflowerPreferences { @ShortName("mcs") String MARK_CORRESPONDING_SYNTHETICS = "mark-corresponding-synthetics"; + @Name("Excluded Classes") + @Description("Exclude classes from decompilation if their fully qualified names match the specified regular expression.") + @Type(Type.STRING) + String EXCLUDED_CLASSES = "excluded-classes"; + Map DEFAULTS = getDefaults(); static Map getDefaults() { @@ -452,6 +457,7 @@ static Map getDefaults() { defaults.put(DUMP_TEXT_TOKENS, "0"); defaults.put(REMOVE_IMPORTS, "0"); defaults.put(MARK_CORRESPONDING_SYNTHETICS, "0"); + defaults.put(EXCLUDED_CLASSES, ""); return Collections.unmodifiableMap(defaults); } @@ -475,7 +481,7 @@ static Map getDefaults() { public @interface Description { String value(); } - + @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.FIELD) public @interface DynamicDefaultValue { @@ -504,7 +510,7 @@ static Map getDefaults() { @Target(ElementType.FIELD) public @interface Type { String value(); - + String BOOLEAN = "bool"; String INTEGER = "int"; String STRING = "string"; diff --git a/src/org/jetbrains/java/decompiler/main/extern/IVariableNameProvider.java b/src/org/jetbrains/java/decompiler/main/extern/IVariableNameProvider.java index d0aee739ba..0aa8c8a053 100644 --- a/src/org/jetbrains/java/decompiler/main/extern/IVariableNameProvider.java +++ b/src/org/jetbrains/java/decompiler/main/extern/IVariableNameProvider.java @@ -17,13 +17,38 @@ import java.util.Map; +import java.util.stream.Collectors; import org.jetbrains.java.decompiler.code.CodeConstants; import org.jetbrains.java.decompiler.modules.decompiler.vars.VarVersionPair; +import org.jetbrains.java.decompiler.struct.attr.StructLocalVariableTableAttribute; import org.jetbrains.java.decompiler.struct.gen.VarType; import org.jetbrains.java.decompiler.util.Pair; public interface IVariableNameProvider { - Map rename(Map> variables); + interface VariableNamingData { + VarType type(); + String typeName(); + StructLocalVariableTableAttribute.LocalVariable lvt(); + } + + default Map renameVariables(Map variables) { + return this.rename(variables.entrySet().stream().collect(Collectors.toMap( + Map.Entry::getKey, + e -> Pair.of(e.getValue().type(), e.getValue().typeName()) + ))); + } + + /** + * Renames the variables. + * + * @param variables variables + * @return map of variable pairs to new names + * @deprecated implement {@link #renameVariables(Map)} instead. this method exists for backwards ABI compatibility + */ + @Deprecated + default Map rename(Map> variables) { + throw new UnsupportedOperationException(); + } default String renameAbstractParameter(String name, int index) { return name; @@ -36,5 +61,6 @@ default String renameParameter(int flags, VarType type, String name, int index) return name; } + public void addParentContext(IVariableNameProvider renamer); } diff --git a/src/org/jetbrains/java/decompiler/main/rels/NestedClassProcessor.java b/src/org/jetbrains/java/decompiler/main/rels/NestedClassProcessor.java index 739e78c61c..6670dc6921 100644 --- a/src/org/jetbrains/java/decompiler/main/rels/NestedClassProcessor.java +++ b/src/org/jetbrains/java/decompiler/main/rels/NestedClassProcessor.java @@ -807,7 +807,7 @@ private static String getEnclosingVarField(StructClass cl, MethodWrapper method, StructMethodParametersAttribute attr = method.methodStruct.getAttribute(StructGeneralAttribute.ATTRIBUTE_METHOD_PARAMETERS); List entries = attr.getEntries(); - if (outerIdx < entries.size() && (entries.get(outerIdx).myAccessFlags & CodeConstants.ACC_MANDATED) == CodeConstants.ACC_MANDATED) { + if (outerIdx < entries.size() && (entries.get(outerIdx).myAccessFlags & (CodeConstants.ACC_MANDATED | CodeConstants.ACC_SYNTHETIC)) != 0) { String name = method.varproc.getVarName(var); VarType type = method.varproc.getVarType(var); diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/SecondaryFunctionsHelper.java b/src/org/jetbrains/java/decompiler/modules/decompiler/SecondaryFunctionsHelper.java index 142cee1ea6..b9056afa06 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/SecondaryFunctionsHelper.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/SecondaryFunctionsHelper.java @@ -12,6 +12,7 @@ import org.jetbrains.java.decompiler.modules.decompiler.vars.VarProcessor; import org.jetbrains.java.decompiler.modules.decompiler.vars.VarVersionPair; import org.jetbrains.java.decompiler.struct.gen.CodeType; +import org.jetbrains.java.decompiler.struct.gen.TypeFamily; import org.jetbrains.java.decompiler.struct.gen.VarType; import java.util.*; @@ -402,6 +403,57 @@ private static Exprent identifySecondaryFunctions(Exprent exprent, boolean state return new FunctionExprent(FunctionType.TERNARY, Arrays.asList( head, new ConstExprent(VarType.VARTYPE_INT, 0, null), iff), fexpr.bytecode); + case I2B: + case I2C: + case I2S: + if (lstOperands.get(0) instanceof FunctionExprent) { + FunctionExprent innerFunction = (FunctionExprent) lstOperands.get(0); + VarType castType = innerFunction.getFuncType().castType; + if (castType == VarType.VARTYPE_INT) { + // longs, floats and doubles are converted to ints before being converted to bytes, shorts or chars + innerFunction.setNeedsCast(false); + return ret; + } + } + // fallthrough + case I2L: + case I2F: + case I2D: + case L2F: + case L2D: + case F2D: + VarType exprType = lstOperands.get(0).getExprType(); + VarType castType = fexpr.getSimpleCastType(); + + // Simplify widening cast + if (castType.typeFamily == TypeFamily.INTEGER) { + if (castType.isStrictSuperset(exprType)) { + fexpr.setNeedsCast(false); + return ret; + } + } else if (castType.typeFamily.isGreater(exprType.typeFamily)) { + fexpr.setNeedsCast(false); + return ret; + } + break; + case DIV: + Exprent left = lstOperands.get(0); + boolean leftImplicitCast = left instanceof FunctionExprent && ((FunctionExprent) left).getSimpleCastType() != null && !((FunctionExprent) left).doesCast(); + Exprent right = lstOperands.get(1); + boolean rightImplicitCast = right instanceof FunctionExprent && ((FunctionExprent) right).getSimpleCastType() != null && !((FunctionExprent) right).doesCast(); + + if (leftImplicitCast && rightImplicitCast && right.getExprType() == left.getExprType()) { + // Only a single cast is needed explicitly + ((FunctionExprent) left).setNeedsCast(true); + } + break; + case SHL: + case SHR: + case USHR: + Exprent op = lstOperands.get(0); + if (op instanceof FunctionExprent && ((FunctionExprent) op).getSimpleCastType() != null && !((FunctionExprent) op).doesCast()) { + ((FunctionExprent) op).setNeedsCast(true); + } } break; case ASSIGNMENT: // check for conditional assignment @@ -464,6 +516,15 @@ private static Exprent identifySecondaryFunctions(Exprent exprent, boolean state } break; case INVOCATION: + InvocationExprent invocationExpr = (InvocationExprent) exprent; + if (invocationExpr.isBoxingCall()) { + Exprent param = invocationExpr.getLstParameters().get(0); + // Keep casts of boxed exprents + if (param instanceof FunctionExprent && ((FunctionExprent) param).getSimpleCastType() != null && !((FunctionExprent) param).doesCast()) { + ((FunctionExprent) param).setNeedsCast(true); + } + } + if (!statement_level) { // simplify if exprent is a real expression. The opposite case is pretty absurd, can still happen however (and happened at least once). Exprent retexpr = ConcatenationHelper.contractStringConcat(exprent); if (!exprent.equals(retexpr)) { diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/SwitchExpressionHelper.java b/src/org/jetbrains/java/decompiler/modules/decompiler/SwitchExpressionHelper.java index d035a3f4d0..72b6e2e2fa 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/SwitchExpressionHelper.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/SwitchExpressionHelper.java @@ -309,10 +309,9 @@ private static Map> mapAssignments(List exprents = breakJump.getExprents(); if (exprents != null && !exprents.isEmpty()) { - if (exprents.size() == 1 && exprents.get(0) instanceof ExitExprent) { - ExitExprent exit = ((ExitExprent) exprents.get(0)); + if (exprents.size() > 0 && exprents.get(exprents.size() - 1) instanceof ExitExprent exit) { - // Special case throws + // Last exprent throws instead of storing a value if (exit.getExitType() == ExitExprent.Type.THROW) { map.put(breakJump, null); continue; diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/SwitchPatternMatchProcessor.java b/src/org/jetbrains/java/decompiler/modules/decompiler/SwitchPatternMatchProcessor.java index 35acab384a..3f526e824f 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/SwitchPatternMatchProcessor.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/SwitchPatternMatchProcessor.java @@ -398,6 +398,6 @@ private static boolean isSwitchPatternMatch(SwitchHeadExprent head) { } public static boolean hasPatternMatch(RootStatement root) { - return root.mt.getBytecodeVersion().hasSwitchPatternMatch() && DecompilerContext.getOption(IFernflowerPreferences.DECOMPILE_PREVIEW); + return root.mt.getBytecodeVersion().hasSwitchPatternMatch() && DecompilerContext.getOption(IFernflowerPreferences.PATTERN_MATCHING); } } diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/TryWithResourcesProcessor.java b/src/org/jetbrains/java/decompiler/modules/decompiler/TryWithResourcesProcessor.java index 84cbd2fa9c..2dd9daa0d0 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/TryWithResourcesProcessor.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/TryWithResourcesProcessor.java @@ -7,8 +7,11 @@ import org.jetbrains.java.decompiler.struct.gen.VarType; import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; import java.util.LinkedHashSet; import java.util.List; +import java.util.Map; import java.util.Set; import java.util.stream.Collectors; @@ -348,14 +351,22 @@ public static void findEdgesLeaving(Statement curr, Statement check, Set edges, boolean allowExit) { + findEdgesLeaving(curr, check, edges, allowExit, new HashMap<>()); + } + + private static void findEdgesLeaving(Statement curr, Statement check, Set edges, boolean allowExit, Map> found) { for (StatEdge edge : curr.getAllSuccessorEdges()) { if (!check.containsStatement(edge.getDestination()) && (allowExit || !(edge.getDestination() instanceof DummyExitStatement))) { - edges.add(edge); + // Check if the edge is either explicit or isn't implicit to an already found edge + if (edge.explicit || found.entrySet().stream().allMatch(e -> !e.getKey().containsStatement(curr) || !e.getValue().contains(edge.getDestination()))) { + edges.add(edge); + found.computeIfAbsent(curr, stat -> new HashSet<>()).add(edge.getDestination()); + } } } for (Statement stat : curr.getStats()) { - findEdgesLeaving(stat, check, edges, allowExit); + findEdgesLeaving(stat, check, edges, allowExit, found); } } diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/ValidationHelper.java b/src/org/jetbrains/java/decompiler/modules/decompiler/ValidationHelper.java index 7b61bac2b6..50a7cafa35 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/ValidationHelper.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/ValidationHelper.java @@ -357,6 +357,26 @@ public static void validateDGraph(DirectGraph graph, RootStatement root) { } } } + + // ensure all exprents are unique + Map, DirectNode> allExprents = new HashMap<>(); + + for (var node : graph.nodes) { + for (var exprent : node.exprents) { + for (var subExprent : exprent.getAllExprents(true, true)) { + ID key = new ID<>(subExprent); + if (allExprents.containsKey(key)) { + throw new IllegalStateException( + "Duplicated exprent: " + subExprent + " (Sub exprent of: " + exprent + ") in dgraph. " + + "Appears in both node " + node.id + " and node " + allExprents.get(key).id + "!" + ); + } else { + allExprents.put(key, node); + } + } + } + } + } catch (Throwable e) { DotExporter.errorToDotFile(graph, root.mt, "erroring_dgraph"); throw e; @@ -507,4 +527,28 @@ public static void validateVarVersionsGraph( throw new IllegalStateException("Highly cyclic varversions graph!"); } } + + + static private class ID { + private final T obj; + + + private ID(T obj) { + this.obj = obj; + } + + @Override + public int hashCode() { + return System.identityHashCode(this.obj); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + ID id = (ID) o; + return obj == id.obj; + } + } } diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/FunctionExprent.java b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/FunctionExprent.java index 43135b8997..788a98da35 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/FunctionExprent.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/FunctionExprent.java @@ -3,7 +3,6 @@ */ package org.jetbrains.java.decompiler.modules.decompiler.exps; -import org.jetbrains.java.decompiler.code.CodeConstants; import org.jetbrains.java.decompiler.main.DecompilerContext; import org.jetbrains.java.decompiler.main.plugins.PluginImplementationException; import org.jetbrains.java.decompiler.modules.decompiler.ExprProcessor; @@ -663,9 +662,12 @@ else if (left instanceof ConstExprent) { inv.forceUnboxing(true); } } - return buf.append(wrapOperandString(lstOperands.get(0), true, indent)) - .prepend("(" + ExprProcessor.getTypeName(funcType.castType) + ")") - .addTypeNameToken(funcType.castType, 1); + + if (!needsCast) { + return buf.append(lstOperands.get(0).toJava(indent)); + } + + return buf.append(ExprProcessor.getTypeName(funcType.castType)).encloseWithParens().append(wrapOperandString(lstOperands.get(0), true, indent)); } // return ""; @@ -695,7 +697,7 @@ public void unwrapBox() { @Override public int getPrecedence() { - if (funcType == FunctionType.CAST && !doesCast()) { + if ((funcType == FunctionType.CAST || funcType.castType != null) && !doesCast()) { return lstOperands.get(0).getPrecedence(); } diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/InvocationExprent.java b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/InvocationExprent.java index edea96b18b..541d6a4744 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/InvocationExprent.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/InvocationExprent.java @@ -600,7 +600,7 @@ else if (paramType.type == CodeType.GENVAR && !paramType.equals(argtype) && argt } newRet = newRet.remap(genericsMap); - if (newRet == null) { + if (newRet == null && bounds.get(ret) != null && bounds.get(ret).size() > 0) { newRet = bounds.get(ret).get(0).remap(genericsMap); } @@ -949,8 +949,6 @@ private static void appendBootstrapArgument(TextBuffer buf, PooledConstant arg) } public TextBuffer appendParamList(int indent) { - TextBuffer buf = new TextBuffer(); - buf.pushNewlineGroup(indent, 1); List mask = null; boolean isEnum = false; if (functype == Type.INIT) { @@ -1105,9 +1103,14 @@ else if (inv.isUnboxingCall() && !inv.shouldForceUnboxing()) { } + TextBuffer buf = new TextBuffer(); + boolean firstParameter = true; - buf.appendPossibleNewline(); - buf.pushNewlineGroup(indent, 0); + if (!lstParameters.isEmpty()) { + buf.pushNewlineGroup(indent, 1); + buf.appendPossibleNewline(); + buf.pushNewlineGroup(indent, 0); + } for (int i = start; i < lstParameters.size(); i++) { if (mask == null || mask.get(i) == null) { @@ -1161,9 +1164,11 @@ else if (desc != null && desc.getSignature() != null && genericArgs.size() != 0) } } - buf.popNewlineGroup(); - buf.appendPossibleNewline("", true); - buf.popNewlineGroup(); + if (!lstParameters.isEmpty()) { + buf.popNewlineGroup(); + buf.appendPossibleNewline("", true); + buf.popNewlineGroup(); + } return buf; } @@ -1333,7 +1338,9 @@ private List getMatchedDescriptors() { private boolean matches(VarType[] left, VarType[] right) { if (left.length == right.length) { for (int i = 0; i < left.length; i++) { - if (left[i].typeFamily != right[i].typeFamily) { + TypeFamily leftFamily = left[i].typeFamily; + TypeFamily rightFamily = right[i].typeFamily; + if (leftFamily != rightFamily && !(leftFamily.isNumeric() && rightFamily.isNumeric())) { return false; } @@ -1401,6 +1408,10 @@ private BitSet getAmbiguousParameters(List matches) { boolean exact = true; for (int i = 0; i < md.params.length; i++) { Exprent exp = lstParameters.get(i); + if (exp instanceof FunctionExprent && ((FunctionExprent) exp).getSimpleCastType() != null) { + ((FunctionExprent) exp).setNeedsCast(true); + } + // Check if the current parameters and method descriptor are of the same type, or if the descriptor's type is a superset of the parameter's type. // This check ensures that parameters that can be safely passed don't have an unneeded cast on them, such as System.out.println((int)5);. // TODO: The root cause of the above issue seems to be threading related- When debugging line by line it doesn't cast, but when running normally it does. More digging needs to be done to figure out why this happens. diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/NewExprent.java b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/NewExprent.java index f729806bea..44053eb734 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/NewExprent.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/NewExprent.java @@ -9,6 +9,7 @@ import org.jetbrains.java.decompiler.main.extern.IFernflowerPreferences; import org.jetbrains.java.decompiler.main.rels.ClassWrapper; import org.jetbrains.java.decompiler.main.rels.MethodWrapper; +import org.jetbrains.java.decompiler.modules.decompiler.DecHelper; import org.jetbrains.java.decompiler.modules.decompiler.ExprProcessor; import org.jetbrains.java.decompiler.modules.decompiler.StatEdge; import org.jetbrains.java.decompiler.modules.decompiler.sforms.SFormsConstructor; @@ -307,7 +308,7 @@ public Exprent copy() { NewExprent ret = new NewExprent(newType, lst, bytecode); ret.setConstructor(constructor == null ? null : (InvocationExprent)constructor.copy()); - ret.setLstArrayElements(lstArrayElements); + ret.setLstArrayElements(DecHelper.copyExprentList(lstArrayElements)); ret.setDirectArrayInit(directArrayInit); ret.setAnonymous(anonymous); ret.setEnumConst(enumConst); diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/SwitchExprent.java b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/SwitchExprent.java index aca49427da..b3a051cf20 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/SwitchExprent.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/SwitchExprent.java @@ -215,7 +215,8 @@ private static boolean isSyntheticThrowEdge(StatEdge edge){ Exprent targetExpr = targetExprs.get(0); return targetExpr instanceof ExitExprent && ((ExitExprent) targetExpr).getExitType() == ExitExprent.Type.THROW - && ((ExitExprent) targetExpr).getValue().getExprType().value.equals("java/lang/IncompatibleClassChangeError"); + && (((ExitExprent) targetExpr).getValue().getExprType().value.equals("java/lang/IncompatibleClassChangeError") + || ((ExitExprent) targetExpr).getValue().getExprType().value.equals("java/lang/MatchException")); } return false; } diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/vars/VarDefinitionHelper.java b/src/org/jetbrains/java/decompiler/modules/decompiler/vars/VarDefinitionHelper.java index e751bf0af5..4e94606896 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/vars/VarDefinitionHelper.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/vars/VarDefinitionHelper.java @@ -6,6 +6,7 @@ import org.jetbrains.java.decompiler.main.DecompilerContext; import org.jetbrains.java.decompiler.main.collectors.VarNamesCollector; import org.jetbrains.java.decompiler.main.extern.IFernflowerPreferences; +import org.jetbrains.java.decompiler.main.extern.IVariableNameProvider; import org.jetbrains.java.decompiler.main.rels.MethodWrapper; import org.jetbrains.java.decompiler.modules.decompiler.ExprProcessor; import org.jetbrains.java.decompiler.modules.decompiler.ValidationHelper; @@ -17,6 +18,7 @@ import org.jetbrains.java.decompiler.struct.StructClass; import org.jetbrains.java.decompiler.struct.StructMethod; import org.jetbrains.java.decompiler.struct.attr.StructGeneralAttribute; +import org.jetbrains.java.decompiler.struct.attr.StructLocalVariableTableAttribute; import org.jetbrains.java.decompiler.struct.attr.StructLocalVariableTableAttribute.LocalVariable; import org.jetbrains.java.decompiler.struct.attr.StructMethodParametersAttribute; import org.jetbrains.java.decompiler.struct.gen.CodeType; @@ -25,7 +27,7 @@ import org.jetbrains.java.decompiler.struct.gen.VarType; import org.jetbrains.java.decompiler.struct.gen.generics.GenericType; import org.jetbrains.java.decompiler.util.ArrayHelper; -import org.jetbrains.java.decompiler.util.Pair; +import org.jetbrains.java.decompiler.util.InterpreterUtil; import org.jetbrains.java.decompiler.util.StatementIterator; import java.util.*; @@ -996,6 +998,12 @@ private VarType getMergedType(VarType fromMin, VarType toMin, VarType fromMax, V } } + record VariableNamingDataImpl( + VarType type, + String typeName, + StructLocalVariableTableAttribute.LocalVariable lvt + ) implements IVariableNameProvider.VariableNamingData {} + private void propogateLVTs(Statement stat) { MethodDescriptor md = MethodDescriptor.parseDescriptor(mt.getDescriptor()); Map types = new LinkedHashMap<>(); @@ -1021,25 +1029,18 @@ private void propogateLVTs(Statement stat) { findTypes(stat, types); - Map> typeNames = new LinkedHashMap<>(); + Map typeNames = new LinkedHashMap<>(); for (Entry e : types.entrySet()) { - typeNames.put(e.getKey(), Pair.of(e.getValue().getType(), e.getValue().getCast())); + typeNames.put(e.getKey(), new VariableNamingDataImpl(e.getValue().getType(), e.getValue().getCast(), e.getValue().getLVT())); } - Map renames = this.mt.getVariableNamer().rename(typeNames); + Map renames = this.mt.getVariableNamer().renameVariables(typeNames); + + Set methods = new HashSet<>(); // Stuff the parent context into enclosed child methods StatementIterator.iterate(root, (exprent) -> { - List methods = new ArrayList<>(); - if (exprent instanceof VarExprent) { - VarExprent var = (VarExprent)exprent; - if (var.isClassDef()) { - ClassNode child = DecompilerContext.getClassProcessor().getMapRootClasses().get(var.getVarType().value); - if (child != null) - methods.addAll(child.classStruct.getMethods()); - } - } - else if (exprent instanceof NewExprent) { + if (exprent instanceof NewExprent) { NewExprent _new = (NewExprent)exprent; if (_new.isAnonymous()) { //TODO: Check for Lambda here? ClassNode child = DecompilerContext.getClassProcessor().getMapRootClasses().get(_new.getNewType().value); @@ -1056,13 +1057,21 @@ else if (exprent instanceof NewExprent) { } } } - - for (StructMethod meth : methods) { - meth.getVariableNamer().addParentContext(VarDefinitionHelper.this.mt.getVariableNamer()); - } return 0; }); + // Local classes aren't added into the method body yet + String thisKey = InterpreterUtil.makeUniqueKey(mt.getName(), mt.getDescriptor()); + for (ClassNode nested : DecompilerContext.getClassProcessor().getMapRootClasses().get(mt.getClassQualifiedName()).nested) { + if (nested.type == ClassNode.Type.LOCAL && thisKey.equals(nested.enclosingMethod)) { + methods.addAll(nested.classStruct.getMethods()); + } + } + + for (StructMethod meth : methods) { + meth.getVariableNamer().addParentContext(VarDefinitionHelper.this.mt.getVariableNamer()); + } + Map lvts = new HashMap<>(); for (Entry e : types.entrySet()) { diff --git a/src/org/jetbrains/java/decompiler/struct/ContextUnit.java b/src/org/jetbrains/java/decompiler/struct/ContextUnit.java index 5ddb6029ee..b1fd3b753b 100644 --- a/src/org/jetbrains/java/decompiler/struct/ContextUnit.java +++ b/src/org/jetbrains/java/decompiler/struct/ContextUnit.java @@ -18,10 +18,12 @@ import java.util.LinkedList; import java.util.List; import java.util.concurrent.*; +import java.util.concurrent.atomic.AtomicInteger; import java.util.function.Function; import java.util.stream.Collectors; public class ContextUnit { + private static AtomicInteger THREAD_ID = new AtomicInteger(0); private final IContextSource source; private final boolean own; private final boolean root; @@ -140,9 +142,12 @@ public void save(final Function loader) throws IOException } //Whooo threads! - final List> futures = new LinkedList<>(); - final int threads = Integer.parseInt((String) DecompilerContext.getProperty(IFernflowerPreferences.THREADS)); - final ExecutorService workerExec = Executors.newFixedThreadPool(threads > 0 ? threads : Runtime.getRuntime().availableProcessors()); + List> futures = new ArrayList<>(); + int threads = Integer.parseInt((String) DecompilerContext.getProperty(IFernflowerPreferences.THREADS)); + if (threads <= 0) { + threads = Runtime.getRuntime().availableProcessors(); + } + ForkJoinPool pool = new ForkJoinPool(threads, namingScheme(), null, true); final DecompilerContext rootContext = DecompilerContext.getCurrentContext(); final List toDump = new ArrayList<>(classEntries.size()); @@ -157,7 +162,7 @@ public void save(final Function loader) throws IOException // pre-process for (final ClassContext classCtx : toDump) { - futures.add(workerExec.submit(() -> { + futures.add(pool.submit(() -> { setContext(rootContext); classCtx.ctx = DecompilerContext.getCurrentContext(); try { @@ -182,7 +187,7 @@ public void save(final Function loader) throws IOException continue; } - futures.add(workerExec.submit(() -> { + futures.add(pool.submit(() -> { DecompilerContext.setCurrentContext(classCtx.ctx); classCtx.classContent = decompiledData.getClassContent(classCtx.cl); if (DecompilerContext.getOption(IFernflowerPreferences.BYTECODE_SOURCE_MAPPING)) { @@ -193,7 +198,8 @@ public void save(final Function loader) throws IOException waitForAll(futures); futures.clear(); - workerExec.shutdown(); + pool.shutdown(); + THREAD_ID.set(0); // write to file for (final ClassContext cls : toDump) { @@ -205,6 +211,15 @@ public void save(final Function loader) throws IOException sink.close(); } + private static ForkJoinPool.ForkJoinWorkerThreadFactory namingScheme() { + return pool -> { + ForkJoinWorkerThread thread = new ForkJoinWorkerThread(pool) {}; + thread.setName("Vineflower-DecompilerThread-" + THREAD_ID.getAndIncrement()); + + return thread; + }; + } + public void setContext(DecompilerContext rootContext) { DecompilerContext current = DecompilerContext.getCurrentContext(); if (current == null) { @@ -221,7 +236,9 @@ public void setContext(DecompilerContext rootContext) { } private static void waitForAll(final List> futures) { - for (Future future : futures) { + for (int i = futures.size() - 1; i >= 0; i--) { + Future future = futures.get(i); + try { future.get(); } catch (ExecutionException e) { diff --git a/src/org/jetbrains/java/decompiler/struct/gen/TypeFamily.java b/src/org/jetbrains/java/decompiler/struct/gen/TypeFamily.java index 2006596f51..e7929c32cc 100644 --- a/src/org/jetbrains/java/decompiler/struct/gen/TypeFamily.java +++ b/src/org/jetbrains/java/decompiler/struct/gen/TypeFamily.java @@ -5,12 +5,26 @@ public enum TypeFamily { UNKNOWN, BOOLEAN, - INTEGER, - FLOAT, - LONG, - DOUBLE, + INTEGER(true), + FLOAT(true), + LONG(true), + DOUBLE(true), OBJECT; + private final boolean numeric; + + TypeFamily() { + this(false); + } + + TypeFamily(boolean numeric) { + this.numeric = numeric; + } + + public boolean isNumeric() { + return numeric; + } + // TODO: document what these mean, and try to remove! Doesn't make sense to have these public boolean isGreater(@NotNull TypeFamily other) { diff --git a/src/org/jetbrains/java/decompiler/util/TextBuffer.java b/src/org/jetbrains/java/decompiler/util/TextBuffer.java index 7fe20cd28a..7861d753a4 100644 --- a/src/org/jetbrains/java/decompiler/util/TextBuffer.java +++ b/src/org/jetbrains/java/decompiler/util/TextBuffer.java @@ -433,10 +433,13 @@ private void reformatGroup(NewlineGroup group, List offsetMapping, int // add extra indent after newlines if (pos + offset + myLineSeparator.length() < myStringBuilder.length() && myStringBuilder.substring(pos + offset, pos + offset + myLineSeparator.length()).equals(myLineSeparator)) { - for (int i = 0; i < extraIndent; i++) { - myStringBuilder.insert(pos + offset + myLineSeparator.length(), myIndent); + // not for blank lines + if (!(pos + offset + myLineSeparator.length() * 2 < myStringBuilder.length()) || !myStringBuilder.substring(pos + offset + myLineSeparator.length(), pos + offset + myLineSeparator.length() * 2).equals(myLineSeparator)) { + for (int i = 0; i < extraIndent; i++) { + myStringBuilder.insert(pos + offset + myLineSeparator.length(), myIndent); + } + offset += myIndent.length() * extraIndent; } - offset += myIndent.length() * extraIndent; } // do multiple passes in an inner loop, as there could be arbitrarily many with the same offset diff --git a/test/org/jetbrains/java/decompiler/SingleClassesTest.java b/test/org/jetbrains/java/decompiler/SingleClassesTest.java index a81d6cec22..abfaac27ff 100644 --- a/test/org/jetbrains/java/decompiler/SingleClassesTest.java +++ b/test/org/jetbrains/java/decompiler/SingleClassesTest.java @@ -253,7 +253,6 @@ private void registerDefault() { register(JAVA_16, "TestRecordAnno"); register(JAVA_16, "TestRecordBig"); register(JAVA_16, "TestRecordGenericSuperclass"); - // TODO: The (double) in front of the (int) should be removed register(JAVA_8, "TestMultiCast"); // TODO: some tests don't have proper if else chains register(JAVA_8, "TestComplexIfElseChain"); @@ -325,6 +324,7 @@ private void registerDefault() { register(JAVA_8, "TestLongMethodDeclaration"); register(JAVA_8, "TestLongMethodInvocation"); register(JAVA_8, "TestBinaryOperationWrapping"); + register(JAVA_8, "TestBlankLinesSpaces"); register(JAVA_8, "TestLoopBreak"); register(JAVA_8, "TestLoopBreak2"); register(JAVA_8, "TestSimpleWhile"); @@ -389,6 +389,7 @@ private void registerDefault() { register(JAVA_16, "TestReturnSwitchExpression2"); register(JAVA_16, "TestReturnSwitchExpression3"); register(JAVA_16, "TestReturnSwitchExpression4"); + register(JAVA_16, "TestReturnSwitchExpression5"); register(JAVA_16, "TestSwitchExprString1"); register(JAVA_16, "TestConstructorSwitchExpression1"); @@ -619,7 +620,7 @@ private void registerDefault() { // TODO: order of additions is wrong. Addition over floats isn't associative. // Derived from IDEA-291735 register(JAVA_8, "TestFloatOrderOfOperations"); - // TODO: many unnecessary casts, and not simplifying to `+=` + // TODO: not simplifying to `+=` register(JAVA_8, "TestMixedCompoundAssignment"); register(JAVA_8, "TestForeachVardef"); register(JAVA_8, "TestGenericStaticCall"); @@ -633,7 +634,6 @@ private void registerDefault() { register(JAVA_8, "TestTryCatchNested"); register(JAVA_8, "TestSwitchTernary"); register(JAVA_8, "TestBooleanExpressions"); - // TODO: cast not created, incorrect register(JAVA_8, "TestObjectBitwise"); register(JAVA_17, "TestSealedFinal", "SealedInterface"); register(JAVA_17, "TestSealedRecord", "SealedInterface"); @@ -692,10 +692,15 @@ private void registerDefault() { register(JAVA_21_PREVIEW, "TestCustomProcessor"); register(JAVA_16, "TestMissingLambdaBody"); register(JAVA_21_PREVIEW, "TestUnnamedVar1"); + register(JAVA_8, "TestNumberCasts"); + // TODO: Disambiguate only the required parameters + register(JAVA_8, "TestNumberDisambiguation"); register(JAVA_8, "TestDanglingBoxingCall"); - register(JAVA_21, "TestSwitchOnEnumJ21"); + register(JAVA_21, "TestSwitchOnEnumJ21", "ext/TestEnum2"); register(JAVA_21, "TestInnerClassesJ21"); + register(JAVA_21, "TestInnerClasses2J21"); register(JAVA_8, "TestInnerClassesJ8"); + register(JAVA_8, "TestSwitchInTry"); } private void registerEntireClassPath() { diff --git a/testData/results/pkg/TestAssignmentSwitchExpression3.dec b/testData/results/pkg/TestAssignmentSwitchExpression3.dec index 489a68cb39..72f0c7bd5f 100644 --- a/testData/results/pkg/TestAssignmentSwitchExpression3.dec +++ b/testData/results/pkg/TestAssignmentSwitchExpression3.dec @@ -7,11 +7,11 @@ public class TestAssignmentSwitchExpression3 { Random random = switch (x) {// 7 case -5, -4, -3, -2, -1 -> { int seed = x >> 2;// 14 - yield new Random((long)seed);// 15 + yield new Random(seed);// 15 } default -> throw new IllegalStateException("Unexpected value: " + x);// 17 case 1, 2, 3, 4, 5 -> { - long seed = System.currentTimeMillis() - (long)(x * 1000);// 9 + long seed = System.currentTimeMillis() - x * 1000;// 9 yield new Random(seed);// 10 } case 6, 7, 8, 9, 10 -> new Random(); diff --git a/testData/results/pkg/TestBlankLinesSpaces.dec b/testData/results/pkg/TestBlankLinesSpaces.dec new file mode 100644 index 0000000000..c716ca4bc9 --- /dev/null +++ b/testData/results/pkg/TestBlankLinesSpaces.dec @@ -0,0 +1,90 @@ +package pkg; + +import java.util.Random; + +public class TestBlankLinesSpaces { + private static final String STRING = longMethodName00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000(); + + private static String longMethodName00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000() { + return null;// 9 + } + + static void takeLambda00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000( + Runnable r + ) { + }// 24 + + static { + takeLambda00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000(// 13 + () -> { + for (int i = 0; i < 10; i++) {// 14 + System.out.println(i);// 15 + } + + if (new Random().nextBoolean()) {// 17 + System.out.println(true);// 18 + } + }// 20 + ); + }// 21 +} + +class 'pkg/TestBlankLinesSpaces' { + method 'longMethodName00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 ()Ljava/lang/String;' { + 0 8 + 1 8 + } + + method 'takeLambda00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 (Ljava/lang/Runnable;)V' { + 0 14 + } + + method ' ()V' { + b 17 + c 17 + d 17 + e 28 + } + + method 'lambda$static$0 ()V' { + 0 19 + 1 19 + 2 19 + 3 19 + 4 19 + 5 19 + 8 20 + 9 20 + a 20 + b 20 + c 20 + d 20 + e 20 + f 19 + 10 19 + 11 19 + 1c 23 + 1d 23 + 1e 23 + 1f 23 + 22 24 + 23 24 + 24 24 + 25 24 + 26 24 + 29 26 + } +} + +Lines mapping: +9 <-> 9 +13 <-> 18 +14 <-> 20 +15 <-> 21 +17 <-> 24 +18 <-> 25 +20 <-> 27 +21 <-> 29 +24 <-> 15 +Not mapped: +6 diff --git a/testData/results/pkg/TestCaseClasses.dec b/testData/results/pkg/TestCaseClasses.dec index 5615f4586a..dd969f55a3 100644 --- a/testData/results/pkg/TestCaseClasses.dec +++ b/testData/results/pkg/TestCaseClasses.dec @@ -39,21 +39,7 @@ public class Option1 implements TestCaseClasses, Product, Serializable { } public boolean equals(final Object x$0) { - if (this != x$0) { - boolean var10000; - if (x$0 instanceof Option1) { - Option1 var3 = (Option1)x$0; - var10000 = this.value() == var3.value() && var3.canEqual(this); - } else { - var10000 = false; - } - - if (!var10000) { - return false; - } - } - - return true; + return this == x$0 || (x$0 instanceof Option1 var3 ? this.value() == var3.value() && var3.canEqual(this) : false); } public String toString() { @@ -185,151 +171,144 @@ class 'pkg/Option1' { 0 35 1 35 2 35 - 5 37 - 7 37 - 8 37 - 9 37 - a 37 - b 37 - e 38 - f 38 - 10 38 - 11 38 - 12 38 - 13 39 - 14 39 - 15 39 - 16 39 - 17 39 - 18 39 - 19 39 - 1a 39 - 1b 39 - 1e 39 - 1f 39 - 20 39 - 21 39 - 22 39 - 23 39 - 2e 41 - 32 44 - 35 49 - 39 45 - 3a 45 + 5 35 + 7 35 + 8 35 + 9 35 + a 35 + b 35 + 12 35 + 13 35 + 14 35 + 15 35 + 16 35 + 17 35 + 18 35 + 19 35 + 1a 35 + 1b 35 + 1e 35 + 1f 35 + 20 35 + 21 35 + 22 35 + 23 35 + 32 35 + 3a 35 } method 'toString ()Ljava/lang/String;' { - 0 53 - 1 53 - 2 53 - 3 53 - 4 53 - 5 53 - 6 53 - 7 53 + 0 39 + 1 39 + 2 39 + 3 39 + 4 39 + 5 39 + 6 39 + 7 39 } method 'canEqual (Ljava/lang/Object;)Z' { - 0 57 - 1 57 - 2 57 - 3 57 - 4 57 + 0 43 + 1 43 + 2 43 + 3 43 + 4 43 } method 'productArity ()I' { - 0 61 - 1 61 + 0 47 + 1 47 } method 'productPrefix ()Ljava/lang/String;' { - 0 65 - 1 65 - 2 65 + 0 51 + 1 51 + 2 51 } method 'productElement (I)Ljava/lang/Object;' { - 0 69 - 2 69 - 3 69 - 4 69 - 7 70 - 8 70 - 9 70 - a 70 - b 70 - c 70 - d 70 - e 70 - f 70 - 10 70 - 11 70 - 12 70 - 13 70 - 14 70 - 15 70 - 16 70 - 17 70 - 18 70 - 19 70 - 1a 70 - 1b 70 - 1c 70 - 1d 70 - 1e 70 - 1f 70 + 0 55 + 2 55 + 3 55 + 4 55 + 7 56 + 8 56 + 9 56 + a 56 + b 56 + c 56 + d 56 + e 56 + f 56 + 10 56 + 11 56 + 12 56 + 13 56 + 14 56 + 15 56 + 16 56 + 17 56 + 18 56 + 19 56 + 1a 56 + 1b 56 + 1c 56 + 1d 56 + 1e 56 + 1f 56 } method 'productElementName (I)Ljava/lang/String;' { - 0 77 - 2 77 - 3 77 - 4 77 - 7 78 - 8 78 - 9 78 - e 80 - f 80 - 10 80 - 11 80 - 12 80 - 13 80 - 14 80 - 18 80 + 0 63 + 2 63 + 3 63 + 4 63 + 7 64 + 8 64 + 9 64 + e 66 + f 66 + 10 66 + 11 66 + 12 66 + 13 66 + 14 66 + 18 66 } method 'value ()I' { - 0 85 - 1 85 - 2 85 - 3 85 - 4 85 + 0 71 + 1 71 + 2 71 + 3 71 + 4 71 } method 'copy (I)Lpkg/Option1;' { - 4 89 - 8 89 + 4 75 + 8 75 } method 'copy$default$1 ()I' { - 0 93 - 1 93 - 2 93 - 3 93 - 4 93 + 0 79 + 1 79 + 2 79 + 3 79 + 4 79 } method '_1 ()I' { - 0 97 - 1 97 - 2 97 - 3 97 - 4 97 + 0 83 + 1 83 + 2 83 + 3 83 + 4 83 } } Lines mapping: -5 <-> 98 +5 <-> 84 // Decompiled companion from pkg/Option1$ package pkg; @@ -453,21 +432,7 @@ public class Option2 implements TestCaseClasses, Product, Serializable { } public boolean equals(final Object x$0) { - if (this != x$0) { - boolean var10000; - if (x$0 instanceof Option2) { - Option2 var3 = (Option2)x$0; - var10000 = this.x() == var3.x() && this.y() == var3.y() && this.z() == var3.z() && var3.canEqual(this); - } else { - var10000 = false; - } - - if (!var10000) { - return false; - } - } - - return true; + return this == x$0 || (x$0 instanceof Option2 var3 ? this.x() == var3.x() && this.y() == var3.y() && this.z() == var3.z() && var3.canEqual(this) : false); } public String toString() { @@ -487,22 +452,12 @@ public class Option2 implements TestCaseClasses, Product, Serializable { } public Object productElement(final int n) { - double var10000; - switch (n) { - case 0: - var10000 = this._1(); - break; - case 1: - var10000 = this._2(); - break; - case 2: - var10000 = this._3(); - break; - default: - throw new IndexOutOfBoundsException(BoxesRunTime.boxToInteger(n).toString()); - } - - return BoxesRunTime.boxToDouble(var10000); + return BoxesRunTime.boxToDouble(switch (n) { + case 0 -> this._1(); + case 1 -> this._2(); + case 2 -> this._3(); + default -> throw new IndexOutOfBoundsException(BoxesRunTime.boxToInteger(n).toString()); + }); } public String productElementName(final int n) { @@ -680,229 +635,219 @@ class 'pkg/Option2' { 0 41 1 41 2 41 - 5 43 - 7 43 - 8 43 - 9 43 - a 43 - b 43 - e 44 - f 44 - 10 44 - 11 44 - 12 44 - 13 45 - 14 45 - 15 45 - 16 45 - 17 45 - 18 45 - 19 45 - 1a 45 - 1b 45 - 1c 45 - 1f 45 - 20 45 - 21 45 - 22 45 - 23 45 - 24 45 - 25 45 - 26 45 - 27 45 - 28 45 - 2b 45 - 2c 45 - 2d 45 - 2e 45 - 2f 45 - 30 45 - 31 45 - 32 45 - 33 45 - 34 45 - 37 45 - 38 45 - 39 45 - 3a 45 - 3b 45 - 3c 45 - 47 47 - 4b 50 - 4e 55 - 52 51 - 53 51 + 5 41 + 7 41 + 8 41 + 9 41 + a 41 + b 41 + 12 41 + 13 41 + 14 41 + 15 41 + 16 41 + 17 41 + 18 41 + 19 41 + 1a 41 + 1b 41 + 1c 41 + 1f 41 + 20 41 + 21 41 + 22 41 + 23 41 + 24 41 + 25 41 + 26 41 + 27 41 + 28 41 + 2b 41 + 2c 41 + 2d 41 + 2e 41 + 2f 41 + 30 41 + 31 41 + 32 41 + 33 41 + 34 41 + 37 41 + 38 41 + 39 41 + 3a 41 + 3b 41 + 3c 41 + 4b 41 + 53 41 } method 'toString ()Ljava/lang/String;' { - 0 59 - 1 59 - 2 59 - 3 59 - 4 59 - 5 59 - 6 59 - 7 59 + 0 45 + 1 45 + 2 45 + 3 45 + 4 45 + 5 45 + 6 45 + 7 45 } method 'canEqual (Ljava/lang/Object;)Z' { - 0 63 - 1 63 - 2 63 - 3 63 - 4 63 + 0 49 + 1 49 + 2 49 + 3 49 + 4 49 } method 'productArity ()I' { - 0 67 - 1 67 + 0 53 + 1 53 } method 'productPrefix ()Ljava/lang/String;' { - 0 71 - 1 71 - 2 71 + 0 57 + 1 57 + 2 57 } method 'productElement (I)Ljava/lang/Object;' { - 0 76 - 2 76 - 3 76 - 1c 78 - 1d 78 - 1e 78 - 1f 78 - 20 79 - 23 81 - 24 81 - 25 81 - 26 81 - 27 82 - 2a 84 - 2b 84 - 2c 84 - 2d 84 - 2e 85 - 35 87 - 36 87 - 37 87 - 38 87 - 39 87 - 3a 87 - 3b 87 - 3f 87 - 41 90 - 42 90 - 43 90 - 44 90 + 0 61 + 2 61 + 3 61 + 1c 62 + 1d 62 + 1e 62 + 1f 62 + 23 63 + 24 63 + 25 63 + 26 63 + 2a 64 + 2b 64 + 2c 64 + 2d 64 + 35 65 + 36 65 + 37 65 + 38 65 + 39 65 + 3a 65 + 3b 65 + 3f 65 + 41 61 + 42 61 + 43 61 + 44 61 } method 'productElementName (I)Ljava/lang/String;' { - 0 94 - 2 94 - 3 94 - 1c 96 - 1d 96 - 1e 96 - 1f 98 - 20 98 - 21 98 - 22 100 - 23 100 - 24 100 - 29 102 - 2a 102 - 2b 102 - 2c 102 - 2d 102 - 2e 102 - 2f 102 - 33 102 + 0 70 + 2 70 + 3 70 + 1c 72 + 1d 72 + 1e 72 + 1f 74 + 20 74 + 21 74 + 22 76 + 23 76 + 24 76 + 29 78 + 2a 78 + 2b 78 + 2c 78 + 2d 78 + 2e 78 + 2f 78 + 33 78 } method 'x ()D' { - 0 107 - 1 107 - 2 107 - 3 107 - 4 107 + 0 83 + 1 83 + 2 83 + 3 83 + 4 83 } method 'y ()D' { - 0 111 - 1 111 - 2 111 - 3 111 - 4 111 + 0 87 + 1 87 + 2 87 + 3 87 + 4 87 } method 'z ()D' { - 0 115 - 1 115 - 2 115 - 3 115 - 4 115 + 0 91 + 1 91 + 2 91 + 3 91 + 4 91 } method 'copy (DDD)Lpkg/Option2;' { - 4 119 - 5 119 - 6 119 - 7 119 - b 119 + 4 95 + 5 95 + 6 95 + 7 95 + b 95 } method 'copy$default$1 ()D' { - 0 123 - 1 123 - 2 123 - 3 123 - 4 123 + 0 99 + 1 99 + 2 99 + 3 99 + 4 99 } method 'copy$default$2 ()D' { - 0 127 - 1 127 - 2 127 - 3 127 - 4 127 + 0 103 + 1 103 + 2 103 + 3 103 + 4 103 } method 'copy$default$3 ()D' { - 0 131 - 1 131 - 2 131 - 3 131 - 4 131 + 0 107 + 1 107 + 2 107 + 3 107 + 4 107 } method '_1 ()D' { - 0 135 - 1 135 - 2 135 - 3 135 - 4 135 + 0 111 + 1 111 + 2 111 + 3 111 + 4 111 } method '_2 ()D' { - 0 139 - 1 139 - 2 139 - 3 139 - 4 139 + 0 115 + 1 115 + 2 115 + 3 115 + 4 115 } method '_3 ()D' { - 0 143 - 1 143 - 2 143 - 3 143 - 4 143 + 0 119 + 1 119 + 2 119 + 3 119 + 4 119 } } Lines mapping: -6 <-> 144 +6 <-> 120 // Decompiled companion from pkg/Option2$ package pkg; @@ -1046,10 +991,9 @@ public class Option3 implements TestCaseClasses, Product, Serializable { public boolean equals(final Object x$0) { if (this != x$0) { boolean var5; - if (!(x$0 instanceof Option3)) { + if (!(x$0 instanceof Option3 var3)) { var5 = false; } else { - Option3 var3 = (Option3)x$0; List var10000 = this.value(); List var4 = var3.value(); var5 = (var10000 == null ? var4 == null : var10000.equals(var4)) && var3.canEqual(this); @@ -1176,144 +1120,140 @@ class 'pkg/Option3' { 9 34 a 34 b 34 - e 37 - f 37 - 10 37 - 11 37 - 12 37 - 13 38 - 14 38 - 15 38 - 16 38 - 17 39 - 18 39 - 19 39 - 1a 39 - 1b 39 - 1c 39 - 1e 40 - 22 40 - 23 40 - 24 40 - 2a 40 - 2b 40 - 2c 40 - 2d 40 - 2e 40 - 2f 40 - 32 40 - 33 40 - 34 40 - 35 40 - 36 40 - 37 40 + 12 34 + 13 37 + 14 37 + 15 37 + 16 37 + 17 38 + 18 38 + 19 38 + 1a 38 + 1b 38 + 1c 38 + 1e 39 + 22 39 + 23 39 + 24 39 + 2a 39 + 2b 39 + 2c 39 + 2d 39 + 2e 39 + 2f 39 + 32 39 + 33 39 + 34 39 + 35 39 + 36 39 + 37 39 42 35 - 46 43 - 49 48 - 4d 44 - 4e 44 + 46 42 + 49 47 + 4d 43 + 4e 43 } method 'toString ()Ljava/lang/String;' { - 0 52 - 1 52 - 2 52 - 3 52 - 4 52 - 5 52 - 6 52 - 7 52 + 0 51 + 1 51 + 2 51 + 3 51 + 4 51 + 5 51 + 6 51 + 7 51 } method 'canEqual (Ljava/lang/Object;)Z' { - 0 56 - 1 56 - 2 56 - 3 56 - 4 56 + 0 55 + 1 55 + 2 55 + 3 55 + 4 55 } method 'productArity ()I' { - 0 60 - 1 60 + 0 59 + 1 59 } method 'productPrefix ()Ljava/lang/String;' { - 0 64 - 1 64 - 2 64 + 0 63 + 1 63 + 2 63 } method 'productElement (I)Ljava/lang/Object;' { - 0 68 - 2 68 - 3 68 - 4 68 - 7 69 - 8 69 - 9 69 - a 69 - b 69 - 10 71 - 11 71 - 12 71 - 13 71 - 14 71 - 15 71 - 16 71 - 1a 71 + 0 67 + 2 67 + 3 67 + 4 67 + 7 68 + 8 68 + 9 68 + a 68 + b 68 + 10 70 + 11 70 + 12 70 + 13 70 + 14 70 + 15 70 + 16 70 + 1a 70 } method 'productElementName (I)Ljava/lang/String;' { - 0 76 - 2 76 - 3 76 - 4 76 - 7 77 - 8 77 - 9 77 - e 79 - f 79 - 10 79 - 11 79 - 12 79 - 13 79 - 14 79 - 18 79 + 0 75 + 2 75 + 3 75 + 4 75 + 7 76 + 8 76 + 9 76 + e 78 + f 78 + 10 78 + 11 78 + 12 78 + 13 78 + 14 78 + 18 78 } method 'value ()Lscala/collection/immutable/List;' { - 0 84 - 1 84 - 2 84 - 3 84 - 4 84 + 0 83 + 1 83 + 2 83 + 3 83 + 4 83 } method 'copy (Lscala/collection/immutable/List;)Lpkg/Option3;' { - 4 88 - 8 88 + 4 87 + 8 87 } method 'copy$default$1 ()Lscala/collection/immutable/List;' { - 0 92 - 1 92 - 2 92 - 3 92 - 4 92 + 0 91 + 1 91 + 2 91 + 3 91 + 4 91 } method '_1 ()Lscala/collection/immutable/List;' { - 0 96 - 1 96 - 2 96 - 3 96 - 4 96 + 0 95 + 1 95 + 2 95 + 3 95 + 4 95 } } Lines mapping: -7 <-> 97 +7 <-> 96 // Decompiled companion from pkg/Option3$ package pkg; diff --git a/testData/results/pkg/TestClassVar.dec b/testData/results/pkg/TestClassVar.dec index 7756a767d7..475c7228c4 100644 --- a/testData/results/pkg/TestClassVar.dec +++ b/testData/results/pkg/TestClassVar.dec @@ -17,7 +17,7 @@ public class TestClassVar { }// 37 public Long testFieldSSAU1() { - return new Long((long)(this.field_int++));// 40 + return new Long(this.field_int++);// 40 } public void testComplexPropagation() { diff --git a/testData/results/pkg/TestDebugSymbols.dec b/testData/results/pkg/TestDebugSymbols.dec index 1300ffd36f..dcbc8997eb 100644 --- a/testData/results/pkg/TestDebugSymbols.dec +++ b/testData/results/pkg/TestDebugSymbols.dec @@ -5,7 +5,7 @@ class TestDebugSymbols { String text = "text";// 21 long prolonged = 42L;// 22 float decimated = (float)prolonged / 10.0F;// 23 - double doubled = (double)(2.0F * decimated);// 24 + double doubled = 2.0F * decimated;// 24 return (text + ":" + prolonged + ":" + decimated + ":" + doubled).length();// 25 } } diff --git a/testData/results/pkg/TestDefiniteAssignment.dec b/testData/results/pkg/TestDefiniteAssignment.dec index 614f039688..02fc48d261 100644 --- a/testData/results/pkg/TestDefiniteAssignment.dec +++ b/testData/results/pkg/TestDefiniteAssignment.dec @@ -56,9 +56,7 @@ public class TestDefiniteAssignment { double cFake = 0.01;// 48 System.out.println(cFake);// 49 - if ((double)n < 1.0 - (double)n && (cFake = (double)(n + 5)) > cFake * cFake - cFake / 2.0// 53 - ? !((double)n > cFake) - : !((double)n < 5.0 - (cFake = (double)n))) { + if (n < 1.0 - n && (cFake = n + 5) > cFake * cFake - cFake / 2.0 ? !(n > cFake) : !(n < 5.0 - (cFake = n))) {// 53 cFake += 5.0;// 57 } else { System.out.println(cFake);// 54 @@ -67,7 +65,7 @@ public class TestDefiniteAssignment { System.out.println(cFake);// 59 double d; - if ((d = (double)n) > 0.0) {// 63 + if ((d = n) > 0.0) {// 63 System.out.println(d);// 64 } }// 67 @@ -299,207 +297,207 @@ class 'pkg/TestDefiniteAssignment' { 67 58 68 58 69 58 - 6c 60 - 6d 60 - 6e 60 - 6f 60 - 70 60 - 71 60 - 72 60 - 74 60 - 75 60 - 76 60 - 77 60 - 78 60 - 7e 59 - 7f 59 - 80 59 - 81 59 - 82 59 - 83 59 - 86 63 - 87 63 - 88 63 - 89 63 - 8a 63 - 8b 63 - 8c 63 - 8d 63 - 90 64 - 91 64 - 92 64 - 94 64 - 95 64 - 9b 61 - 9c 61 - 9d 61 - 9f 61 - a0 61 - a1 67 - a2 67 - a3 67 - a4 67 - a5 67 - a6 67 - a7 67 - a8 67 - a9 69 - aa 69 - ac 69 - ad 69 - ae 69 - af 69 - b0 69 - bb 69 - be 70 - bf 70 - c0 70 - c1 70 - c2 70 - c3 70 - c6 72 + 6c 58 + 6d 58 + 6e 58 + 6f 58 + 70 58 + 71 58 + 72 58 + 74 58 + 75 58 + 76 58 + 77 58 + 78 58 + 7e 58 + 7f 58 + 80 58 + 81 58 + 82 58 + 83 58 + 86 61 + 87 61 + 88 61 + 89 61 + 8a 61 + 8b 61 + 8c 61 + 8d 61 + 90 62 + 91 62 + 92 62 + 94 62 + 95 62 + 9b 59 + 9c 59 + 9d 59 + 9f 59 + a0 59 + a1 65 + a2 65 + a3 65 + a4 65 + a5 65 + a6 65 + a7 65 + a8 65 + a9 67 + aa 67 + ac 67 + ad 67 + ae 67 + af 67 + b0 67 + bb 67 + be 68 + bf 68 + c0 68 + c1 68 + c2 68 + c3 68 + c6 70 } method 'testBooleanNormalness (I)V' { - 0 75 - 1 75 - 2 75 - 3 75 - 4 77 - 5 77 - 6 77 - 9 77 - a 77 - b 77 - d 77 - e 77 - 12 77 - 15 77 - 16 77 - 19 78 - 1a 78 - 1b 78 - 1c 78 - 1d 78 - 1e 78 - 21 81 - 22 81 - 23 81 - 24 82 - 25 82 - 26 82 - 27 82 - 28 82 - 29 82 - 2a 82 - 2b 83 + 0 73 + 1 73 + 2 73 + 3 73 + 4 75 + 5 75 + 6 75 + 9 75 + a 75 + b 75 + d 75 + e 75 + 12 75 + 15 75 + 16 75 + 19 76 + 1a 76 + 1b 76 + 1c 76 + 1d 76 + 1e 76 + 21 79 + 22 79 + 23 79 + 24 80 + 25 80 + 26 80 + 27 80 + 28 80 + 29 80 + 2a 80 + 2b 81 } method 'testBooleanNormalnessInline (I)V' { - 0 86 - 1 86 - 2 86 - 3 86 - 4 88 - 5 88 - 6 88 - 9 88 - a 88 - b 88 - d 88 - e 88 - 12 88 - 15 88 - 16 88 - 1e 88 - 1f 88 - 20 88 - 22 89 - 23 89 - 24 89 - 25 90 - 26 90 - 27 90 - 28 90 - 29 90 - 2a 90 - 2b 90 - 2c 91 + 0 84 + 1 84 + 2 84 + 3 84 + 4 86 + 5 86 + 6 86 + 9 86 + a 86 + b 86 + d 86 + e 86 + 12 86 + 15 86 + 16 86 + 1e 86 + 1f 86 + 20 86 + 22 87 + 23 87 + 24 87 + 25 88 + 26 88 + 27 88 + 28 88 + 29 88 + 2a 88 + 2b 88 + 2c 89 } method 'nestedTernaries (III)V' { - 0 96 - 1 96 - 4 97 - 5 97 - 6 97 - 9 101 - b 101 - c 101 - d 102 - 13 106 - 15 106 - 16 106 - 17 107 - 1a 107 - 1b 107 - 1c 107 - 1f 112 - 20 112 - 21 112 - 22 112 - 23 112 - 24 112 - 27 120 - 28 120 - 2b 121 - 2c 121 - 2d 121 - 30 125 - 32 125 - 33 125 - 34 126 - 3a 130 - 3c 130 - 3d 130 - 3e 131 - 41 131 - 42 131 - 43 131 - 46 136 - 47 136 - 48 136 - 49 136 - 4a 136 - 4d 136 - 4e 136 - 4f 136 - 51 136 - 52 136 - 53 136 - 54 136 - 5a 142 - 5c 142 - 5d 142 - 5e 143 - 60 143 - 61 143 - 62 144 - 65 149 - 66 149 - 67 149 - 68 149 - 69 149 - 6a 149 - 6d 152 - 6e 152 - 6f 152 - 70 152 - 71 152 - 72 152 - 73 152 - 74 152 - 75 153 + 0 94 + 1 94 + 4 95 + 5 95 + 6 95 + 9 99 + b 99 + c 99 + d 100 + 13 104 + 15 104 + 16 104 + 17 105 + 1a 105 + 1b 105 + 1c 105 + 1f 110 + 20 110 + 21 110 + 22 110 + 23 110 + 24 110 + 27 118 + 28 118 + 2b 119 + 2c 119 + 2d 119 + 30 123 + 32 123 + 33 123 + 34 124 + 3a 128 + 3c 128 + 3d 128 + 3e 129 + 41 129 + 42 129 + 43 129 + 46 134 + 47 134 + 48 134 + 49 134 + 4a 134 + 4d 134 + 4e 134 + 4f 134 + 51 134 + 52 134 + 53 134 + 54 134 + 5a 140 + 5c 140 + 5d 140 + 5e 141 + 60 141 + 61 141 + 62 142 + 65 147 + 66 147 + 67 147 + 68 147 + 69 147 + 6a 147 + 6d 150 + 6e 150 + 6f 150 + 70 150 + 71 150 + 72 150 + 73 150 + 74 150 + 75 151 } } @@ -526,27 +524,27 @@ Lines mapping: 48 <-> 57 49 <-> 58 53 <-> 59 -54 <-> 64 -55 <-> 65 -57 <-> 62 -59 <-> 68 -63 <-> 70 -64 <-> 71 -67 <-> 73 -71 <-> 76 -72 <-> 78 -73 <-> 79 -75 <-> 82 -76 <-> 83 -77 <-> 84 -81 <-> 87 -82 <-> 89 -83 <-> 90 -84 <-> 91 -85 <-> 92 -89 <-> 97 -90 <-> 113 -94 <-> 121 -97 <-> 150 -99 <-> 153 -100 <-> 154 +54 <-> 62 +55 <-> 63 +57 <-> 60 +59 <-> 66 +63 <-> 68 +64 <-> 69 +67 <-> 71 +71 <-> 74 +72 <-> 76 +73 <-> 77 +75 <-> 80 +76 <-> 81 +77 <-> 82 +81 <-> 85 +82 <-> 87 +83 <-> 88 +84 <-> 89 +85 <-> 90 +89 <-> 95 +90 <-> 111 +94 <-> 119 +97 <-> 148 +99 <-> 151 +100 <-> 152 diff --git a/testData/results/pkg/TestDoublePopAfterJump.dec b/testData/results/pkg/TestDoublePopAfterJump.dec index ee88d99f74..f08d915cdc 100644 --- a/testData/results/pkg/TestDoublePopAfterJump.dec +++ b/testData/results/pkg/TestDoublePopAfterJump.dec @@ -14,7 +14,7 @@ public final class TestDoublePopAfterJump { var10001 = var10004; } - return (double)var10001 / (double)var10000;// 44 45 46 + return (double)var10001 / var10000;// 44 45 46 } public static final void fizzBuzz() { diff --git a/testData/results/pkg/TestInnerClasses2J21.dec b/testData/results/pkg/TestInnerClasses2J21.dec new file mode 100644 index 0000000000..4cbd42fef5 --- /dev/null +++ b/testData/results/pkg/TestInnerClasses2J21.dec @@ -0,0 +1,43 @@ +package pkg; + +public class TestInnerClasses2J21 { + private void test() { + new TestInnerClasses2J21.Inner().new Inner2(true, true);// 5 + }// 6 + + private class Inner { + private class Inner2 { + private Inner2(boolean nonFinal, final boolean finalB) { + TestInnerClasses2J21.this.test();// 11 + }// 12 + } + } +} + +class 'pkg/TestInnerClasses2J21' { + method 'test ()V' { + c 4 + d 4 + 12 5 + } +} + +class 'pkg/TestInnerClasses2J21$Inner$Inner2' { + method ' (Lpkg/TestInnerClasses2J21$Inner;ZZ)V' { + 5 10 + 6 10 + 7 10 + 8 10 + 9 10 + a 10 + b 11 + } +} + +Lines mapping: +5 <-> 5 +6 <-> 6 +11 <-> 11 +12 <-> 12 +Not mapped: +10 \ No newline at end of file diff --git a/testData/results/pkg/TestInnerClassesJ21.dec b/testData/results/pkg/TestInnerClassesJ21.dec index 98eebf7bde..8ffaffbfa9 100644 --- a/testData/results/pkg/TestInnerClassesJ21.dec +++ b/testData/results/pkg/TestInnerClassesJ21.dec @@ -10,7 +10,7 @@ public class TestInnerClassesJ21 { private final long z; private final String v; - public TestInner(int param2, long param3, String param5) { + public TestInner(int x, long z, String v) { this.x = x;// 11 this.z = z;// 12 this.v = v;// 13 diff --git a/testData/results/pkg/TestKotlinEnumWhen.dec b/testData/results/pkg/TestKotlinEnumWhen.dec index f66da1dbcc..297fd24016 100644 --- a/testData/results/pkg/TestKotlinEnumWhen.dec +++ b/testData/results/pkg/TestKotlinEnumWhen.dec @@ -30,22 +30,12 @@ public enum TestKotlinEnumWhen { }// 12 public final void testExpression() { - String var10000; - switch (this) {// 16 - case FIRST: - var10000 = "first!";// 17 - break; - case SECOND: - var10000 = "second!";// 18 - break; - case THIRD: - var10000 = "third!";// 19 - break; - default: - throw new NoWhenBranchMatchedException(); - } - - String var1 = var10000; + String var1 = switch (this) {// 16 + case FIRST -> "first!";// 17 + case SECOND -> "second!";// 18 + case THIRD -> "third!";// 19 + default -> throw new NoWhenBranchMatchedException(); + }; System.out.println(var1);// 15 }// 22 @@ -154,215 +144,212 @@ class 'pkg/TestKotlinEnumWhen' { } method 'testExpression ()V' { - 0 33 - 8 33 - 9 33 - 24 35 - 25 35 - 26 36 - 29 38 - 2a 38 - 2b 39 - 2e 41 - 2f 41 - 30 42 - 3a 44 - 3b 47 + 0 32 + 8 32 + 9 32 + 24 33 + 25 33 + 29 34 + 2a 34 + 2e 35 + 2f 35 + 3a 36 + 3b 32 + 3c 38 + 3d 38 + 3e 38 + 3f 38 + 40 38 + 41 38 + 42 38 + 43 39 + } + + method 'testAnotherEnum ()V' { + 0 42 + 1 42 + 2 42 + 3 42 + 7 43 + b 43 + c 43 + 28 45 + 29 45 + 2a 45 + 2b 45 + 2c 45 + 2d 45 + 2e 45 + 2f 45 + 30 45 + 32 45 + 33 45 + 34 45 + 35 46 + 38 48 + 39 48 + 3a 48 + 3b 48 3c 48 3d 48 3e 48 3f 48 40 48 - 41 48 42 48 - 43 49 - } - - method 'testAnotherEnum ()V' { - 0 52 - 1 52 - 2 52 - 3 52 - 7 53 - b 53 - c 53 - 28 55 - 29 55 - 2a 55 - 2b 55 - 2c 55 - 2d 55 - 2e 55 - 2f 55 - 30 55 - 32 55 - 33 55 - 34 55 - 35 56 - 38 58 - 39 58 - 3a 58 - 3b 58 - 3c 58 - 3d 58 - 3e 58 - 3f 58 - 40 58 - 42 58 - 43 58 - 44 58 - 45 59 - 48 61 - 49 61 - 4a 61 - 4b 61 - 4c 61 - 4d 61 - 4e 61 - 4f 61 - 50 61 - 52 61 - 55 63 + 43 48 + 44 48 + 45 49 + 48 51 + 49 51 + 4a 51 + 4b 51 + 4c 51 + 4d 51 + 4e 51 + 4f 51 + 50 51 + 52 51 + 55 53 } method 'testConsecutive ()V' { - 0 66 - 8 66 - 9 66 - 24 68 - 25 68 - 26 68 - 27 68 - 28 68 - 2a 68 - 2b 68 - 2c 68 - 2d 69 - 30 71 - 31 71 - 32 71 - 33 71 - 34 71 - 36 71 - 37 71 - 38 71 - 39 72 - 3c 74 - 3d 74 - 3e 74 - 3f 74 - 40 74 - 42 74 - 45 77 - 4d 77 - 4e 77 - 68 79 - 69 79 - 6a 79 - 6b 79 - 6c 79 - 6e 79 - 6f 79 - 70 79 - 71 80 - 74 82 - 75 82 - 76 82 - 77 82 - 78 82 - 7a 82 - 7b 82 - 7c 82 - 7d 83 - 80 85 - 81 85 - 82 85 - 83 85 - 84 85 - 86 85 - 89 87 + 0 56 + 8 56 + 9 56 + 24 58 + 25 58 + 26 58 + 27 58 + 28 58 + 2a 58 + 2b 58 + 2c 58 + 2d 59 + 30 61 + 31 61 + 32 61 + 33 61 + 34 61 + 36 61 + 37 61 + 38 61 + 39 62 + 3c 64 + 3d 64 + 3e 64 + 3f 64 + 40 64 + 42 64 + 45 67 + 4d 67 + 4e 67 + 68 69 + 69 69 + 6a 69 + 6b 69 + 6c 69 + 6e 69 + 6f 69 + 70 69 + 71 70 + 74 72 + 75 72 + 76 72 + 77 72 + 78 72 + 7a 72 + 7b 72 + 7c 72 + 7d 73 + 80 75 + 81 75 + 82 75 + 83 75 + 84 75 + 86 75 + 89 77 } method 'testConsecutiveMixed ()V' { - 0 90 - 1 90 - 2 90 - 3 90 - 7 91 - b 91 - c 91 - 28 93 - 29 93 - 2a 93 - 2b 93 - 2c 93 - 2d 93 - 2e 93 - 2f 93 - 30 93 - 32 93 - 33 93 - 34 93 - 35 94 - 38 96 - 39 96 - 3a 96 - 3b 96 - 3c 96 - 3d 96 - 3e 96 - 3f 96 - 40 96 - 42 96 - 43 96 - 44 96 - 45 97 - 48 99 - 49 99 - 4a 99 - 4b 99 - 4c 99 - 4d 99 - 4e 99 - 4f 99 - 50 99 - 52 99 - 55 102 - 5d 102 - 5e 102 - 78 104 - 79 104 - 7a 104 - 7b 104 - 7c 104 - 7e 104 - 7f 104 - 80 104 - 81 105 - 84 107 - 85 107 - 86 107 - 87 107 - 88 107 - 8a 107 - 8b 107 - 8c 107 - 8d 108 - 90 110 - 91 110 - 92 110 - 93 110 - 94 110 - 96 110 - 99 112 + 0 80 + 1 80 + 2 80 + 3 80 + 7 81 + b 81 + c 81 + 28 83 + 29 83 + 2a 83 + 2b 83 + 2c 83 + 2d 83 + 2e 83 + 2f 83 + 30 83 + 32 83 + 33 83 + 34 83 + 35 84 + 38 86 + 39 86 + 3a 86 + 3b 86 + 3c 86 + 3d 86 + 3e 86 + 3f 86 + 40 86 + 42 86 + 43 86 + 44 86 + 45 87 + 48 89 + 49 89 + 4a 89 + 4b 89 + 4c 89 + 4d 89 + 4e 89 + 4f 89 + 50 89 + 52 89 + 55 92 + 5d 92 + 5e 92 + 78 94 + 79 94 + 7a 94 + 7b 94 + 7c 94 + 7e 94 + 7f 94 + 80 94 + 81 95 + 84 97 + 85 97 + 86 97 + 87 97 + 88 97 + 8a 97 + 8b 97 + 8c 97 + 8d 98 + 90 100 + 91 100 + 92 100 + 93 100 + 94 100 + 96 100 + 99 102 } method 'testAnotherEnum$getLevel ()Lkotlin/DeprecationLevel;' { - 7 115 + 7 105 } method 'testConsecutiveMixed$getLevel-0 ()Lkotlin/DeprecationLevel;' { - 7 119 + 7 109 } } @@ -372,34 +359,34 @@ Lines mapping: 9 <-> 25 10 <-> 28 12 <-> 30 -15 <-> 49 -16 <-> 34 -17 <-> 36 -18 <-> 39 -19 <-> 42 -22 <-> 50 -26 <-> 116 -28 <-> 53 -29 <-> 56 -30 <-> 59 -31 <-> 62 -33 <-> 64 -36 <-> 67 -37 <-> 69 -38 <-> 72 -39 <-> 75 -42 <-> 78 -43 <-> 80 -44 <-> 83 -45 <-> 86 -47 <-> 88 -51 <-> 120 -53 <-> 91 -54 <-> 94 -55 <-> 97 -56 <-> 100 -59 <-> 103 -60 <-> 105 -61 <-> 108 -62 <-> 111 -64 <-> 113 +15 <-> 39 +16 <-> 33 +17 <-> 34 +18 <-> 35 +19 <-> 36 +22 <-> 40 +26 <-> 106 +28 <-> 43 +29 <-> 46 +30 <-> 49 +31 <-> 52 +33 <-> 54 +36 <-> 57 +37 <-> 59 +38 <-> 62 +39 <-> 65 +42 <-> 68 +43 <-> 70 +44 <-> 73 +45 <-> 76 +47 <-> 78 +51 <-> 110 +53 <-> 81 +54 <-> 84 +55 <-> 87 +56 <-> 90 +59 <-> 93 +60 <-> 95 +61 <-> 98 +62 <-> 101 +64 <-> 103 diff --git a/testData/results/pkg/TestLocalsNames.dec b/testData/results/pkg/TestLocalsNames.dec index d54d30db1f..1a30a11df3 100644 --- a/testData/results/pkg/TestLocalsNames.dec +++ b/testData/results/pkg/TestLocalsNames.dec @@ -15,7 +15,7 @@ public class TestLocalsNames { } long elapsed = System.currentTimeMillis() - start;// 31 - System.out.println("took " + elapsed + "ms (" + elapsed / (long)files.length + "ms per dir)");// 32 + System.out.println("took " + elapsed + "ms (" + elapsed / files.length + "ms per dir)");// 32 } }// 34 } diff --git a/testData/results/pkg/TestMethodHandles.dec b/testData/results/pkg/TestMethodHandles.dec index 0484c05591..1706ff1f9f 100644 --- a/testData/results/pkg/TestMethodHandles.dec +++ b/testData/results/pkg/TestMethodHandles.dec @@ -12,33 +12,33 @@ public class TestMethodHandles { public void test1() throws Throwable { MethodHandle abs = LOOKUP.findStatic(Math.class, "abs", MethodType.methodType(long.class, long.class));// 10 int a = -5;// 11 - long b = (long)abs.invokeExact((long)a);// 12 + long b = (long)abs.invokeExact(a);// 12 System.out.println(b);// 13 }// 14 public int test2() throws Throwable { MethodHandle abs = LOOKUP.findStatic(Math.class, "abs", MethodType.methodType(long.class, long.class));// 17 int a = -5;// 18 - return (int)(long)abs.invokeExact((long)a);// 19 + return (int)(long)abs.invokeExact(a);// 19 } public void test3() throws Throwable { MethodHandle abs = LOOKUP.findStatic(Math.class, "abs", MethodType.methodType(long.class, long.class));// 23 int a = -5;// 24 - long b = (long)abs.invoke((long)a);// 25 + long b = (long)abs.invoke(a);// 25 System.out.println(b);// 26 }// 27 public int test4() throws Throwable { MethodHandle abs = LOOKUP.findStatic(Math.class, "abs", MethodType.methodType(long.class, long.class));// 30 int a = -5;// 31 - return (int)(long)abs.invoke((long)a);// 32 + return (int)(long)abs.invoke(a);// 32 } public void test5() throws Throwable { MethodHandle println = LOOKUP.findVirtual(PrintStream.class, "println", MethodType.methodType(void.class, long.class));// 36 int a = -5;// 37 - println.invokeExact(System.out, (long)a);// 38 + println.invokeExact(System.out, a);// 38 }// 39 } diff --git a/testData/results/pkg/TestMixedCompoundAssignment.dec b/testData/results/pkg/TestMixedCompoundAssignment.dec index 14008b4b08..dc21681687 100644 --- a/testData/results/pkg/TestMixedCompoundAssignment.dec +++ b/testData/results/pkg/TestMixedCompoundAssignment.dec @@ -2,53 +2,53 @@ package pkg; public class TestMixedCompoundAssignment { public int testSimpleIntFloat(int i, float j) { - i = (int)((float)i + j);// 5 - i = (int)((float)i - j);// 6 - i = (int)((float)i * j);// 7 - return (int)((float)i / j);// 8 10 + i = (int)(i + j);// 5 + i = (int)(i - j);// 6 + i = (int)(i * j);// 7 + return (int)(i / j);// 8 10 } public int testSimpleIntLong(int i, long j) { - i = (int)((long)i + j);// 14 - i = (int)((long)i - j);// 15 - i = (int)((long)i * j);// 16 - i = (int)((long)i / j);// 17 - i = (int)((long)i & j);// 18 - i = (int)((long)i | j);// 19 - i = (int)((long)i ^ j);// 20 + i = (int)(i + j);// 14 + i = (int)(i - j);// 15 + i = (int)(i * j);// 16 + i = (int)(i / j);// 17 + i = (int)(i & j);// 18 + i = (int)(i | j);// 19 + i = (int)(i ^ j);// 20 i >>= (int)j;// 21 i <<= (int)j;// 22 return i >>> (int)j;// 23 25 } public double testSimpleDoubleLong(double i, long j) { - i += (double)j;// 29 - i -= (double)j;// 30 - i *= (double)j;// 31 - return i / (double)j;// 32 34 + i += j;// 29 + i -= j;// 30 + i *= j;// 31 + return i / j;// 32 34 } public int testNestedIntLongDouble(int i, long j, double k) { long var9; - i = (int)((long)i + (var9 = (long)((double)j + k)));// 38 - i = (int)((long)i - (j = (long)((double)var9 - k)));// 39 + i = (int)(i + (var9 = (long)(j + k)));// 38 + i = (int)(i - (j = (long)(var9 - k)));// 39 long var11; - i = (int)((long)i * (var11 = (long)((double)j * k)));// 40 - return (int)((long)i / (long)((double)var11 / k));// 41 44 + i = (int)(i * (var11 = (long)(j * k)));// 40 + return (int)(i / (long)(var11 / k));// 41 44 } public long testNestedLongIntLong(long i, int j, long k) { int var15; - i += (long)(var15 = (int)((long)j + k));// 48 - i -= (long)(j = (int)((long)var15 - k));// 49 + i += var15 = (int)(j + k);// 48 + i -= j = (int)(var15 - k);// 49 int var17; - i *= (long)(var17 = (int)((long)j * k));// 50 - i /= (long)(j = (int)((long)var17 / k));// 51 + i *= var17 = (int)(j * k);// 50 + i /= j = (int)(var17 / k);// 51 int var19; - i &= (long)(var19 = (int)((long)j & k));// 52 - i |= (long)(j = (int)((long)var19 | k));// 53 + i &= var19 = (int)(j & k);// 52 + i |= j = (int)(var19 | k);// 53 int var21; - i ^= (long)(var21 = (int)((long)j ^ k));// 54 + i ^= var21 = (int)(j ^ k);// 54 i >>= j = var21 >> (int)k;// 55 int var23; i <<= var23 = j << (int)k;// 56 @@ -57,25 +57,25 @@ public class TestMixedCompoundAssignment { public void testArrayIntDouble(int[] holder, int i, double inc) { for (int j = 0; j < i; j++) {// 64 - holder[j] = (int)((double)holder[j] + inc);// 65 + holder[j] = (int)(holder[j] + inc);// 65 } }// 67 public void testArrayIntLong(int[] holder, int i, long inc) { for (int j = 0; j < i; j++) {// 70 - holder[j] = (int)((long)holder[j] + inc);// 71 + holder[j] = (int)(holder[j] + inc);// 71 } }// 73 public void testArrayDoubleInt(double[] holder, int i, int inc) { for (int j = 0; j < i; j++) {// 76 - holder[j] += (double)inc;// 77 + holder[j] += inc;// 77 } }// 79 public void testNestedArrayByteFloatLongDouble(byte[] outer, float[] holder, long[] inner, int i, double inc) { for (int j = 0; j < i; j++) {// 82 - outer[i + ~j] = (byte)((int)((float)outer[i + ~j] + (holder[j] -= (float)(inner[j * 3 % i] = (long)((double)inner[j * 3 % i] + inc)))));// 83 + outer[i + ~j] = (byte)(outer[i + ~j] + (holder[j] -= (float)(inner[j * 3 % i] = (long)(inner[j * 3 % i] + inc))));// 83 } }// 85 } diff --git a/testData/results/pkg/TestMultiCast.dec b/testData/results/pkg/TestMultiCast.dec index 42a0868055..37c4f4980f 100644 --- a/testData/results/pkg/TestMultiCast.dec +++ b/testData/results/pkg/TestMultiCast.dec @@ -2,7 +2,7 @@ package pkg; public class TestMultiCast { public void test(double arg1, double arg2) { - useNumbers((double)((int)arg1), (double)((int)arg2));// 5 + useNumbers((int)arg1, (int)arg2);// 5 }// 6 private static void useNumbers(double arg1, double arg2) { diff --git a/testData/results/pkg/TestMultipleStaticBlocks.dec b/testData/results/pkg/TestMultipleStaticBlocks.dec index 02242d41c0..c8fa547c75 100644 --- a/testData/results/pkg/TestMultipleStaticBlocks.dec +++ b/testData/results/pkg/TestMultipleStaticBlocks.dec @@ -4,12 +4,12 @@ public class TestMultipleStaticBlocks { private static int i; static { - byte value = (byte)((int)(Math.random() * 8.0));// 7 + byte value = (byte)(Math.random() * 8.0);// 7 if (value > 4) {// 8 i = 1;// 9 } - value = (byte)((short)((int)(Math.random() * 8.0)));// 14 + value = (byte)((short)(Math.random() * 8.0));// 14 if (value > 4) {// 15 i = 2;// 16 } diff --git a/testData/results/pkg/TestNumberCasts.dec b/testData/results/pkg/TestNumberCasts.dec new file mode 100644 index 0000000000..ed9dd15a90 --- /dev/null +++ b/testData/results/pkg/TestNumberCasts.dec @@ -0,0 +1,367 @@ +package pkg; + +public class TestNumberCasts { + private static void b(byte b) { + }// 5 + + private static void s(short s) { + }// 8 + + private static void i(int i) { + }// 11 + + private static void l(long l) { + }// 14 + + private static void f(float f) { + }// 17 + + private static void d(double d) { + }// 20 + + public void test() { + byte b = 127;// 23 + b(b);// 24 + s(b);// 25 + i(b);// 26 + l(b);// 27 + f(b);// 28 + d(b);// 29 + short s = 32767;// 31 + b((byte)s);// 32 + s(s);// 33 + i(s);// 34 + l(s);// 35 + f(s);// 36 + d(s);// 37 + int i = 2147483647;// 39 + b((byte)i);// 40 + s((short)i);// 41 + i(i);// 42 + l(i);// 43 + f(i);// 44 + d(i);// 45 + long l = 9223372036854775807L;// 47 + b((byte)l);// 48 + s((short)l);// 49 + i((int)l);// 50 + l(l);// 51 + f((float)l);// 52 + d(l);// 53 + float f = 3.4028235E38F;// 55 + b((byte)f);// 56 + s((short)f);// 57 + i((int)f);// 58 + l((long)f);// 59 + f(f);// 60 + d(f);// 61 + double d = 1.7976931348623157E308;// 63 + b((byte)d);// 64 + s((short)d);// 65 + i((int)d);// 66 + l((long)d);// 67 + f((float)d);// 68 + d(d);// 69 + }// 70 +} + +class 'pkg/TestNumberCasts' { + method 'b (B)V' { + 0 4 + } + + method 's (S)V' { + 0 7 + } + + method 'i (I)V' { + 0 10 + } + + method 'l (J)V' { + 0 13 + } + + method 'f (F)V' { + 0 16 + } + + method 'd (D)V' { + 0 19 + } + + method 'test ()V' { + 0 22 + 1 22 + 2 22 + 3 23 + 4 23 + 5 23 + 6 23 + 7 24 + 8 24 + 9 24 + a 24 + b 24 + c 25 + d 25 + e 25 + f 25 + 10 26 + 11 26 + 12 26 + 13 26 + 14 26 + 15 27 + 16 27 + 17 27 + 18 27 + 19 27 + 1a 28 + 1b 28 + 1c 28 + 1d 28 + 1e 28 + 1f 29 + 20 29 + 21 29 + 22 29 + 23 30 + 24 30 + 25 30 + 26 30 + 27 30 + 28 31 + 29 31 + 2a 31 + 2b 31 + 2c 32 + 2d 32 + 2e 32 + 2f 32 + 30 33 + 31 33 + 32 33 + 33 33 + 34 33 + 35 34 + 36 34 + 37 34 + 38 34 + 39 34 + 3a 35 + 3b 35 + 3c 35 + 3d 35 + 3e 35 + 3f 36 + 40 36 + 41 36 + 42 37 + 43 37 + 44 37 + 45 37 + 46 37 + 47 38 + 48 38 + 49 38 + 4a 38 + 4b 38 + 4c 39 + 4d 39 + 4e 39 + 4f 39 + 50 40 + 51 40 + 52 40 + 53 40 + 54 40 + 55 41 + 56 41 + 57 41 + 58 41 + 59 41 + 5a 42 + 5b 42 + 5c 42 + 5d 42 + 5e 42 + 5f 43 + 60 43 + 61 43 + 62 43 + 63 43 + 64 44 + 65 44 + 66 44 + 67 44 + 68 44 + 69 44 + 6a 44 + 6b 45 + 6c 45 + 6d 45 + 6e 45 + 6f 45 + 70 45 + 71 45 + 72 46 + 73 46 + 74 46 + 75 46 + 76 46 + 77 46 + 78 47 + 79 47 + 7a 47 + 7b 47 + 7c 47 + 7d 48 + 7e 48 + 7f 48 + 80 48 + 81 48 + 82 48 + 83 49 + 84 49 + 85 49 + 86 49 + 87 49 + 88 49 + 89 50 + 8a 50 + 8b 50 + 8c 50 + 8d 51 + 8e 51 + 8f 51 + 90 51 + 91 51 + 92 51 + 93 51 + 94 52 + 95 52 + 96 52 + 97 52 + 98 52 + 99 52 + 9a 52 + 9b 53 + 9c 53 + 9d 53 + 9e 53 + 9f 53 + a0 53 + a1 54 + a2 54 + a3 54 + a4 54 + a5 54 + a6 54 + a7 55 + a8 55 + a9 55 + aa 55 + ab 55 + ac 56 + ad 56 + ae 56 + af 56 + b0 56 + b1 56 + b2 57 + b3 57 + b4 57 + b5 57 + b6 57 + b7 58 + b8 58 + b9 58 + ba 58 + bb 58 + bc 58 + bd 58 + be 59 + bf 59 + c0 59 + c1 59 + c2 59 + c3 59 + c4 59 + c5 60 + c6 60 + c7 60 + c8 60 + c9 60 + ca 60 + cb 61 + cc 61 + cd 61 + ce 61 + cf 61 + d0 61 + d1 62 + d2 62 + d3 62 + d4 62 + d5 62 + d6 62 + d7 63 + d8 63 + d9 63 + da 63 + db 63 + dc 64 + } +} + +Lines mapping: +5 <-> 5 +8 <-> 8 +11 <-> 11 +14 <-> 14 +17 <-> 17 +20 <-> 20 +23 <-> 23 +24 <-> 24 +25 <-> 25 +26 <-> 26 +27 <-> 27 +28 <-> 28 +29 <-> 29 +31 <-> 30 +32 <-> 31 +33 <-> 32 +34 <-> 33 +35 <-> 34 +36 <-> 35 +37 <-> 36 +39 <-> 37 +40 <-> 38 +41 <-> 39 +42 <-> 40 +43 <-> 41 +44 <-> 42 +45 <-> 43 +47 <-> 44 +48 <-> 45 +49 <-> 46 +50 <-> 47 +51 <-> 48 +52 <-> 49 +53 <-> 50 +55 <-> 51 +56 <-> 52 +57 <-> 53 +58 <-> 54 +59 <-> 55 +60 <-> 56 +61 <-> 57 +63 <-> 58 +64 <-> 59 +65 <-> 60 +66 <-> 61 +67 <-> 62 +68 <-> 63 +69 <-> 64 +70 <-> 65 diff --git a/testData/results/pkg/TestNumberDisambiguation.dec b/testData/results/pkg/TestNumberDisambiguation.dec new file mode 100644 index 0000000000..26613185c1 --- /dev/null +++ b/testData/results/pkg/TestNumberDisambiguation.dec @@ -0,0 +1,384 @@ +package pkg; + +public class TestNumberDisambiguation { + public void foo(byte b) { + }// 5 + + public void foo(short s) { + }// 8 + + public void foo(char c) { + }// 11 + + public void foo(int i) { + }// 14 + + public void foo(long l) { + }// 17 + + public void foo(float f) { + }// 20 + + public void foo(double d) { + }// 23 + + public void bar(byte a, byte b) { + }// 26 + + public void bar(short a, short b) { + }// 29 + + public void bar(char a, char b) { + }// 32 + + public void bar(int a, int b) { + }// 35 + + public void bar(long a, long b) { + }// 38 + + public void bar(float a, float b) { + }// 41 + + public void bar(double a, double b) { + }// 44 + + public void baz(int a, byte b, byte c) { + }// 47 + + public void baz(int a, short b, short c) { + }// 50 + + public void baz(int a, char b, char c) { + }// 53 + + public void baz(int a, int b, int c) { + }// 56 + + public void baz(int a, long b, long c) { + }// 59 + + public void baz(int a, float b, float c) { + }// 62 + + public void baz(int a, double b, double c) { + }// 65 + + public void test() { + int i = 24;// 68 + this.foo((byte)i);// 69 + this.foo((short)i);// 70 + this.foo((char)i);// 71 + this.foo(i);// 72 + this.foo((long)i);// 73 + this.foo((float)i);// 74 + this.foo((double)i);// 75 + this.bar((byte)0, (byte)i);// 77 + this.bar((short)0, (short)i);// 78 + this.bar('\u0000', (char)i);// 79 + this.bar(0, i);// 80 + this.bar(0L, (long)i);// 81 + this.bar(0.0F, (float)i);// 82 + this.bar(0.0, (double)i);// 83 + this.baz(0, (byte)127, (byte)i);// 85 + this.baz(0, (short)32767, (short)i);// 86 + this.baz(0, '\uffff', (char)i);// 87 + this.baz(0, 2147483647, i);// 88 + this.baz(0, 9223372036854775807L, (long)i);// 89 + this.baz(0, 3.4028235E38F, (float)i);// 90 + this.baz(0, 1.7976931348623157E308, (double)i);// 91 + }// 92 +} + +class 'pkg/TestNumberDisambiguation' { + method 'foo (B)V' { + 0 4 + } + + method 'foo (S)V' { + 0 7 + } + + method 'foo (C)V' { + 0 10 + } + + method 'foo (I)V' { + 0 13 + } + + method 'foo (J)V' { + 0 16 + } + + method 'foo (F)V' { + 0 19 + } + + method 'foo (D)V' { + 0 22 + } + + method 'bar (BB)V' { + 0 25 + } + + method 'bar (SS)V' { + 0 28 + } + + method 'bar (CC)V' { + 0 31 + } + + method 'bar (II)V' { + 0 34 + } + + method 'bar (JJ)V' { + 0 37 + } + + method 'bar (FF)V' { + 0 40 + } + + method 'bar (DD)V' { + 0 43 + } + + method 'baz (IBB)V' { + 0 46 + } + + method 'baz (ISS)V' { + 0 49 + } + + method 'baz (ICC)V' { + 0 52 + } + + method 'baz (III)V' { + 0 55 + } + + method 'baz (IJJ)V' { + 0 58 + } + + method 'baz (IFF)V' { + 0 61 + } + + method 'baz (IDD)V' { + 0 64 + } + + method 'test ()V' { + 0 67 + 1 67 + 2 67 + 3 68 + 4 68 + 5 68 + 6 68 + 7 68 + 8 68 + 9 69 + a 69 + b 69 + c 69 + d 69 + e 69 + f 70 + 10 70 + 11 70 + 12 70 + 13 70 + 14 70 + 15 71 + 16 71 + 17 71 + 18 71 + 19 71 + 1a 72 + 1b 72 + 1c 72 + 1d 72 + 1e 72 + 1f 72 + 20 73 + 21 73 + 22 73 + 23 73 + 24 73 + 25 73 + 26 74 + 27 74 + 28 74 + 29 74 + 2a 74 + 2b 74 + 2c 75 + 2d 75 + 2e 75 + 2f 75 + 30 75 + 31 75 + 32 75 + 33 76 + 34 76 + 35 76 + 36 76 + 37 76 + 38 76 + 39 76 + 3a 77 + 3b 77 + 3c 77 + 3d 77 + 3e 77 + 3f 77 + 40 77 + 41 78 + 42 78 + 43 78 + 44 78 + 45 78 + 46 78 + 47 79 + 48 79 + 49 79 + 4a 79 + 4b 79 + 4c 79 + 4d 79 + 4e 80 + 4f 80 + 50 80 + 51 80 + 52 80 + 53 80 + 54 80 + 55 81 + 56 81 + 57 81 + 58 81 + 59 81 + 5a 81 + 5b 81 + 5c 82 + 5d 82 + 5e 82 + 5f 82 + 60 82 + 61 82 + 62 82 + 63 82 + 64 82 + 65 83 + 66 83 + 67 83 + 68 83 + 69 83 + 6a 83 + 6b 83 + 6c 83 + 6d 83 + 6e 83 + 6f 84 + 70 84 + 71 84 + 72 84 + 73 84 + 74 84 + 75 84 + 76 84 + 77 84 + 78 85 + 79 85 + 7a 85 + 7b 85 + 7c 85 + 7d 85 + 7e 85 + 7f 85 + 80 86 + 81 86 + 82 86 + 83 86 + 84 86 + 85 86 + 86 86 + 87 86 + 88 86 + 89 86 + 8a 87 + 8b 87 + 8c 87 + 8d 87 + 8e 87 + 8f 87 + 90 87 + 91 87 + 92 87 + 93 88 + 94 88 + 95 88 + 96 88 + 97 88 + 98 88 + 99 88 + 9a 88 + 9b 88 + 9c 88 + 9d 89 + } +} + +Lines mapping: +5 <-> 5 +8 <-> 8 +11 <-> 11 +14 <-> 14 +17 <-> 17 +20 <-> 20 +23 <-> 23 +26 <-> 26 +29 <-> 29 +32 <-> 32 +35 <-> 35 +38 <-> 38 +41 <-> 41 +44 <-> 44 +47 <-> 47 +50 <-> 50 +53 <-> 53 +56 <-> 56 +59 <-> 59 +62 <-> 62 +65 <-> 65 +68 <-> 68 +69 <-> 69 +70 <-> 70 +71 <-> 71 +72 <-> 72 +73 <-> 73 +74 <-> 74 +75 <-> 75 +77 <-> 76 +78 <-> 77 +79 <-> 78 +80 <-> 79 +81 <-> 80 +82 <-> 81 +83 <-> 82 +85 <-> 83 +86 <-> 84 +87 <-> 85 +88 <-> 86 +89 <-> 87 +90 <-> 88 +91 <-> 89 +92 <-> 90 diff --git a/testData/results/pkg/TestObjectBitwise.dec b/testData/results/pkg/TestObjectBitwise.dec index 9792f57f5b..82ce7049c0 100644 --- a/testData/results/pkg/TestObjectBitwise.dec +++ b/testData/results/pkg/TestObjectBitwise.dec @@ -4,27 +4,27 @@ public abstract class TestObjectBitwise { abstract T get(); public boolean test(int i) { - return ((Long)this.obj() & (long)i) == 0L;// 7 + return ((Long)this.obj() & i) == 0L;// 7 } public boolean testn(int i) { - return ((Long)this.num() & (long)i) == 0L;// 11 + return ((Long)this.num() & i) == 0L;// 11 } public boolean testg(int i) { - return ((Long)this.get() & (long)i) == 0L;// 15 + return ((Long)this.get() & i) == 0L;// 15 } public boolean test1(int i) { - return ((Long)this.obj() | (long)i) == 0L;// 50 + return ((Long)this.obj() | i) == 0L;// 50 } public boolean test3(int i) { - return (Long)this.obj() + (long)i == 0L;// 54 + return (Long)this.obj() + i == 0L;// 54 } public boolean test4(int i) { - return (Long)this.obj() % (long)i == 0L;// 58 + return (Long)this.obj() % i == 0L;// 58 } public Object obj() { @@ -43,17 +43,17 @@ public abstract class TestObjectBitwise { } public boolean testg_inner(int i) { - return (this.get() & (long)i) == 0L;// 27 + return (this.get() & i) == 0L;// 27 } public boolean testg_inner2(int i) { long l = this.get();// 31 - return (l & (long)i) == 0L;// 32 + return (l & i) == 0L;// 32 } public boolean testg_inner3(int i) { long l = this.other.get();// 36 - return (l & (long)i) == 0L;// 37 + return (l & i) == 0L;// 37 } public boolean testg_inner4(int i) { @@ -61,7 +61,7 @@ public abstract class TestObjectBitwise { long l2 = (Long)this.other.num();// 42 long l3 = (Long)this.obj();// 43 long l4 = (Long)this.num();// 44 - return (l & (long)i & l2 & l3 & l4) == 0L;// 45 + return (l & i & l2 & l3 & l4) == 0L;// 45 } } } diff --git a/testData/results/pkg/TestRecordPattern3.dec b/testData/results/pkg/TestRecordPattern3.dec index 529e04b395..ba8bbcb6c3 100644 --- a/testData/results/pkg/TestRecordPattern3.dec +++ b/testData/results/pkg/TestRecordPattern3.dec @@ -27,7 +27,7 @@ public class TestRecordPattern3 { double dd = Double.valueOf(var32); boolean var33 = $proxy$bool(bundle); boolean bool = Boolean.valueOf(var33); - System.out.println(a + var21 + var22 + ((double)((long)(i1 + i2 + i3 + i4) + l1 + l2 + (long)c1 + (long)c2 + (long)bb) + dd) + bool);// 11 + System.out.println(a + var21 + var22 + (i1 + i2 + i3 + i4 + l1 + l2 + c1 + c2 + bb + dd) + bool);// 11 } }// 13 diff --git a/testData/results/pkg/TestReturnSwitchExpression5.dec b/testData/results/pkg/TestReturnSwitchExpression5.dec new file mode 100644 index 0000000000..81ff5329e4 --- /dev/null +++ b/testData/results/pkg/TestReturnSwitchExpression5.dec @@ -0,0 +1,36 @@ +package pkg; + +public class TestReturnSwitchExpression5 { + public String test(int i) { + return switch (i) {// 6 + case 1 -> "1";// 7 + case 2 -> "2";// 8 + default -> { + int a = 0;// 10 + throw new RuntimeException();// 11 + } + }; + } +} + +class 'pkg/TestReturnSwitchExpression5' { + method 'test (I)Ljava/lang/String;' { + 0 4 + 1 4 + 1c 5 + 1d 5 + 21 6 + 22 6 + 26 8 + 27 8 + 2f 9 + 30 4 + } +} + +Lines mapping: +6 <-> 5 +7 <-> 6 +8 <-> 7 +10 <-> 9 +11 <-> 10 diff --git a/testData/results/pkg/TestStackCastParam.dec b/testData/results/pkg/TestStackCastParam.dec index cad0c3f392..2d76de1e67 100644 --- a/testData/results/pkg/TestStackCastParam.dec +++ b/testData/results/pkg/TestStackCastParam.dec @@ -5,8 +5,8 @@ public class TestStackCastParam { public int y; public void test(String s) { - float var10002 = (float)this.x; - get().b.accept(s, var10002, (float)this.y);// 8 + float var10002 = this.x; + get().b.accept(s, var10002, this.y);// 8 }// 9 public static TestStackCastParam.A get() { diff --git a/testData/results/pkg/TestSwitchInTry.dec b/testData/results/pkg/TestSwitchInTry.dec new file mode 100644 index 0000000000..b80405d1d0 --- /dev/null +++ b/testData/results/pkg/TestSwitchInTry.dec @@ -0,0 +1,96 @@ +package pkg; + +import java.util.Arrays; +import java.util.List; + +public class TestSwitchInTry { + public static List method(String[] args) { + String ret = "";// 13 + + for (String arg : args) {// 14 + try { + byte var7 = -1; + switch (arg.hashCode()) {// 16 + case 97: + if (arg.equals("a")) { + var7 = 0; + } + default: + switch (var7) { + case 0: + ret = "a";// 18 + return Arrays.asList(ret);// 24 + default: + return Arrays.asList(ret); + } + } + } catch (Exception var8) {// 21 + } + } + + return Arrays.asList(ret); + } +} + +class 'pkg/TestSwitchInTry' { + method 'method ([Ljava/lang/String;)Ljava/util/List;' { + 0 7 + 1 7 + 2 7 + 3 9 + 4 9 + 5 9 + 7 9 + 9 9 + a 9 + 15 9 + 16 9 + 17 12 + 18 12 + 1b 11 + 1c 11 + 1d 11 + 1e 12 + 1f 12 + 20 12 + 21 12 + 22 12 + 23 12 + 34 14 + 35 14 + 36 14 + 37 14 + 38 14 + 39 14 + 3a 14 + 3b 14 + 3e 15 + 3f 15 + 40 15 + 41 18 + 42 18 + 43 18 + 54 20 + 55 20 + 56 20 + 5a 26 + 5c 9 + 5d 9 + 5e 9 + 68 21 + 6a 21 + 6b 21 + 6c 21 + 6d 21 + } +} + +Lines mapping: +13 <-> 8 +14 <-> 10 +16 <-> 13 +18 <-> 21 +21 <-> 27 +24 <-> 22 +Not mapped: +20 diff --git a/testData/results/pkg/TestSwitchOnEnumJ21.dec b/testData/results/pkg/TestSwitchOnEnumJ21.dec index cff9f9f8cf..9cf0c1ccbd 100644 --- a/testData/results/pkg/TestSwitchOnEnumJ21.dec +++ b/testData/results/pkg/TestSwitchOnEnumJ21.dec @@ -1,43 +1,94 @@ package pkg; +import ext.TestEnum2; + public class TestSwitchOnEnumJ21 { public int test1(TestSwitchOnEnumJ21.TestEnum a) { - return switch (a) {// 5 - case A -> 1;// 6 - case B -> 2;// 7 - case C -> 3;// 8 + return switch (a) {// 7 + case A -> 1;// 8 + case B -> 2;// 9 + case C -> 3;// 10 + }; + } + + public int test2(TestEnum2 a) { + return switch (a) {// 15 + case A -> 1;// 16 + case B -> 2;// 17 + case C -> 3;// 18 + }; + } + + public int test3(TestSwitchOnEnumJ21.TestEnum a) { + return switch (a) {// 23 + case null -> 4;// 27 + case A -> 1;// 24 + case B -> 2;// 25 + case C -> 3;// 26 + }; + } + + public int test4(TestEnum2 a) { + return switch (a) {// 32 + case null -> 4;// 36 + case A -> 1;// 33 + case B -> 2;// 34 + case C -> 3;// 35 + }; + } + + public int test5(TestSwitchOnEnumJ21.TestEnum a, boolean b) { + return switch (a) {// 41 + case A -> 1;// 42 + case B -> 2;// 43 + case C -> { + if (b) {// 45 + boolean c = true;// 46 + yield 3;// 47 + } else { + boolean d = true;// 49 + yield 4;// 50 + } + } }; } public int testDefault(TestSwitchOnEnumJ21.TestEnum a) { - return switch (a) {// 13 - case A -> 1;// 14 - default -> 5;// 15 + return switch (a) {// 57 + case A -> 1;// 58 + default -> 5;// 59 + }; + } + + public int testDefault2(TestEnum2 a) { + return switch (a) {// 64 + case A -> 1;// 65 + default -> 5;// 66 }; } public void testStatement(TestSwitchOnEnumJ21.TestEnum a) { - switch (a) {// 20 + switch (a) {// 71 case A: - System.out.println("A");// 22 - break;// 23 + System.out.println("A");// 73 + break;// 74 case B: - System.out.println("B");// 25 - break;// 26 + System.out.println("B");// 76 + break;// 77 case C: - System.out.println("C");// 28 + System.out.println("C");// 79 } - }// 30 + }// 81 public void testStatementDefault(TestSwitchOnEnumJ21.TestEnum a) { - switch (a) {// 33 + switch (a) {// 84 case A: - System.out.println("A");// 35 - break;// 36 + System.out.println("A");// 86 + break;// 87 default: - System.out.println("C");// 38 + System.out.println("C");// 89 } - }// 40 + }// 91 static enum TestEnum { A, @@ -48,91 +99,173 @@ public class TestSwitchOnEnumJ21 { class 'pkg/TestSwitchOnEnumJ21' { method 'test1 (Lpkg/TestSwitchOnEnumJ21$TestEnum;)I' { - 0 4 - 4 4 - 2a 5 - 2e 6 - 32 7 - 33 4 + 0 6 + 4 6 + 2a 7 + 2e 8 + 32 9 + 33 6 + } + + method 'test2 (Lext/TestEnum2;)I' { + 3 14 + 7 14 + 8 14 + 2e 15 + 32 16 + 36 17 + 37 14 + } + + method 'test3 (Lpkg/TestSwitchOnEnumJ21$TestEnum;)I' { + 0 22 + 4 22 + b 22 + 32 24 + 36 25 + 3a 26 + 3e 23 + 3f 22 + } + + method 'test4 (Lext/TestEnum2;)I' { + 0 31 + 4 31 + b 31 + 32 33 + 36 34 + 3a 35 + 3e 32 + 3f 31 + } + + method 'test5 (Lpkg/TestSwitchOnEnumJ21$TestEnum;Z)I' { + 0 40 + 4 40 + 2a 41 + 2e 42 + 32 44 + 33 44 + 36 45 + 37 45 + 38 46 + 3c 48 + 3d 48 + 3e 49 + 42 40 } method 'testDefault (Lpkg/TestSwitchOnEnumJ21$TestEnum;)I' { - 0 12 - 4 12 - 18 13 - 1c 14 - 1d 12 + 0 56 + 4 56 + 18 57 + 1c 58 + 1d 56 + } + + method 'testDefault2 (Lext/TestEnum2;)I' { + 3 63 + 7 63 + 8 63 + 1c 64 + 20 65 + 21 63 } method 'testStatement (Lpkg/TestSwitchOnEnumJ21$TestEnum;)V' { - 0 19 - 4 19 - 20 21 - 21 21 - 22 21 - 23 21 - 24 21 - 25 21 - 26 21 - 27 21 - 28 22 - 2b 24 - 2c 24 - 2d 24 - 2e 24 - 2f 24 - 30 24 - 31 24 - 32 24 - 33 25 - 36 27 - 37 27 - 38 27 - 39 27 - 3a 27 - 3b 27 - 3e 29 + 0 70 + 4 70 + 20 72 + 21 72 + 22 72 + 23 72 + 24 72 + 25 72 + 26 72 + 27 72 + 28 73 + 2b 75 + 2c 75 + 2d 75 + 2e 75 + 2f 75 + 30 75 + 31 75 + 32 75 + 33 76 + 36 78 + 37 78 + 38 78 + 39 78 + 3a 78 + 3b 78 + 3e 80 } method 'testStatementDefault (Lpkg/TestSwitchOnEnumJ21$TestEnum;)V' { - 0 32 - 4 32 - 18 34 - 19 34 - 1a 34 - 1b 34 - 1c 34 - 1d 34 - 1e 34 - 1f 34 - 20 35 - 23 37 - 24 37 - 25 37 - 26 37 - 27 37 - 28 37 - 2b 39 + 0 83 + 4 83 + 18 85 + 19 85 + 1a 85 + 1b 85 + 1c 85 + 1d 85 + 1e 85 + 1f 85 + 20 86 + 23 88 + 24 88 + 25 88 + 26 88 + 27 88 + 28 88 + 2b 90 } } Lines mapping: -5 <-> 5 -6 <-> 6 7 <-> 7 8 <-> 8 -13 <-> 13 -14 <-> 14 +9 <-> 9 +10 <-> 10 15 <-> 15 -20 <-> 20 -22 <-> 22 +16 <-> 16 +17 <-> 17 +18 <-> 18 23 <-> 23 -25 <-> 25 -26 <-> 26 -28 <-> 28 -30 <-> 30 -33 <-> 33 -35 <-> 35 -36 <-> 36 -38 <-> 38 -40 <-> 40 \ No newline at end of file +24 <-> 25 +25 <-> 26 +26 <-> 27 +27 <-> 24 +32 <-> 32 +33 <-> 34 +34 <-> 35 +35 <-> 36 +36 <-> 33 +41 <-> 41 +42 <-> 42 +43 <-> 43 +45 <-> 45 +46 <-> 46 +47 <-> 47 +49 <-> 49 +50 <-> 50 +57 <-> 57 +58 <-> 58 +59 <-> 59 +64 <-> 64 +65 <-> 65 +66 <-> 66 +71 <-> 71 +73 <-> 73 +74 <-> 74 +76 <-> 76 +77 <-> 77 +79 <-> 79 +81 <-> 81 +84 <-> 84 +86 <-> 86 +87 <-> 87 +89 <-> 89 +91 <-> 91 diff --git a/testData/results/pkg/TestWhileTernary10.dec b/testData/results/pkg/TestWhileTernary10.dec index 5d4ec6f136..b3ef2d2a07 100644 --- a/testData/results/pkg/TestWhileTernary10.dec +++ b/testData/results/pkg/TestWhileTernary10.dec @@ -4,7 +4,7 @@ import java.util.stream.Stream; public class TestWhileTernary10 { public double test(boolean condition, int n, Stream doubles) { - double[] ds = new double[]{(double)n};// 7 + double[] ds = new double[]{n};// 7 for (int i = 0; condition ? i >= n : n >= i; i++) {// 9 for (int j = 0; j < n; j++) {// 10 @@ -20,10 +20,10 @@ public class TestWhileTernary10 { } public double test1(boolean condition, int n, Stream doubles) { - double[] ds = new double[]{(double)n};// 24 + double[] ds = new double[]{n};// 24 for (int i = 0; condition ? i >= n : n >= i; i++) {// 26 - ds[0] += (double)i;// 27 + ds[0] += i;// 27 } doubles.forEach(d -> ds[0] -= d);// 30 @@ -31,7 +31,7 @@ public class TestWhileTernary10 { } public double test2(boolean condition, int n, Stream doubles) { - double[] ds = new double[]{(double)n};// 35 + double[] ds = new double[]{n};// 35 for (int i = 0; condition ? i >= n : n >= i; i++) {// 37 for (int j = 0; j < n; j++) {// 38 diff --git a/testData/src/java16/pkg/TestReturnSwitchExpression5.java b/testData/src/java16/pkg/TestReturnSwitchExpression5.java new file mode 100644 index 0000000000..674f24656b --- /dev/null +++ b/testData/src/java16/pkg/TestReturnSwitchExpression5.java @@ -0,0 +1,15 @@ +package pkg; + + +public class TestReturnSwitchExpression5 { + public String test(int i) { + return switch (i) { + case 1 -> "1"; + case 2 -> "2"; + default -> { + int a = 0; + throw new RuntimeException(); + } + }; + } +} diff --git a/testData/src/java21/ext/TestEnum2.java b/testData/src/java21/ext/TestEnum2.java new file mode 100644 index 0000000000..bcc0edddad --- /dev/null +++ b/testData/src/java21/ext/TestEnum2.java @@ -0,0 +1,7 @@ +package ext; + +public enum TestEnum2 { + A, + B, + C +} diff --git a/testData/src/java21/pkg/TestInnerClasses2J21.java b/testData/src/java21/pkg/TestInnerClasses2J21.java new file mode 100644 index 0000000000..d856d67cd7 --- /dev/null +++ b/testData/src/java21/pkg/TestInnerClasses2J21.java @@ -0,0 +1,15 @@ +package pkg; + +public class TestInnerClasses2J21 { + private void test() { + new Inner().new Inner2(true, true); + } + + private class Inner { + private class Inner2 { + private Inner2(boolean nonFinal, final boolean finalB) { + TestInnerClasses2J21.this.test(); + } + } + } +} diff --git a/testData/src/java21/pkg/TestSwitchOnEnumJ21.java b/testData/src/java21/pkg/TestSwitchOnEnumJ21.java index f3fc6a301b..aa59f277f2 100644 --- a/testData/src/java21/pkg/TestSwitchOnEnumJ21.java +++ b/testData/src/java21/pkg/TestSwitchOnEnumJ21.java @@ -1,5 +1,7 @@ package pkg; +import ext.TestEnum2; + public class TestSwitchOnEnumJ21 { public int test1(TestEnum a) { return switch (a) { @@ -8,6 +10,48 @@ public int test1(TestEnum a) { case C -> 3; }; } + + public int test2(TestEnum2 a) { + return switch (a) { + case A -> 1; + case B -> 2; + case C -> 3; + }; + } + + public int test3(TestEnum a) { + return switch (a) { + case A -> 1; + case B -> 2; + case C -> 3; + case null -> 4; + }; + } + + public int test4(TestEnum2 a) { + return switch (a) { + case A -> 1; + case B -> 2; + case C -> 3; + case null -> 4; + }; + } + + public int test5(TestEnum a, boolean b) { + return switch (a) { + case A -> 1; + case B -> 2; + case C -> { + if (b) { + boolean c = true; + yield 3; + } else { + boolean d = true; + yield 4; + } + } + }; + } public int testDefault(TestEnum a) { return switch (a) { @@ -15,6 +59,13 @@ public int testDefault(TestEnum a) { default -> 5; }; } + + public int testDefault2(TestEnum2 a) { + return switch (a) { + case A -> 1; + default -> 5; + }; + } public void testStatement(TestEnum a) { switch (a) { diff --git a/testData/src/java8/pkg/TestBlankLinesSpaces.java b/testData/src/java8/pkg/TestBlankLinesSpaces.java new file mode 100644 index 0000000000..efba634512 --- /dev/null +++ b/testData/src/java8/pkg/TestBlankLinesSpaces.java @@ -0,0 +1,25 @@ +package pkg; + +import java.util.Random; + +public class TestBlankLinesSpaces { + private static final String STRING = longMethodName00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000(); + + private static String longMethodName00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000() { + return null; + } + + static { + takeLambda00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000(() -> { + for (int i = 0; i < 10; i++) { + System.out.println(i); + } + if (new Random().nextBoolean()) { + System.out.println(true); + } + }); + } + + static void takeLambda00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000(Runnable r) { + } +} diff --git a/testData/src/java8/pkg/TestNumberCasts.java b/testData/src/java8/pkg/TestNumberCasts.java new file mode 100644 index 0000000000..0b111c4504 --- /dev/null +++ b/testData/src/java8/pkg/TestNumberCasts.java @@ -0,0 +1,71 @@ +package pkg; + +public class TestNumberCasts { + private static void b(byte b) { + } + + private static void s(short s) { + } + + private static void i(int i) { + } + + private static void l(long l) { + } + + private static void f(float f) { + } + + private static void d(double d) { + } + + public void test() { + byte b = 127; + b(b); + s(b); + i(b); + l(b); + f(b); + d(b); + + short s = 32767; + b((byte) s); + s(s); + i(s); + l(s); + f(s); + d(s); + + int i = 2147483647; + b((byte) i); + s((short) i); + i(i); + l(i); + f(i); + d(i); + + long l = 9223372036854775807L; + b((byte) l); + s((short) l); + i((int) l); + l(l); + f(l); + d(l); + + float f = 3.4028235E38f; + b((byte) f); + s((short) f); + i((int) f); + l((long) f); + f(f); + d(f); + + double d = 1.7976931348623157E308; + b((byte) d); + s((short) d); + i((int) d); + l((long) d); + f((float) d); + d(d); + } +} diff --git a/testData/src/java8/pkg/TestNumberDisambiguation.java b/testData/src/java8/pkg/TestNumberDisambiguation.java new file mode 100644 index 0000000000..632432551d --- /dev/null +++ b/testData/src/java8/pkg/TestNumberDisambiguation.java @@ -0,0 +1,93 @@ +package pkg; + +public class TestNumberDisambiguation { + public void foo(byte b) { + } + + public void foo(short s) { + } + + public void foo(char c) { + } + + public void foo(int i) { + } + + public void foo(long l) { + } + + public void foo(float f) { + } + + public void foo(double d) { + } + + public void bar(byte a, byte b) { + } + + public void bar(short a, short b) { + } + + public void bar(char a, char b) { + } + + public void bar(int a, int b) { + } + + public void bar(long a, long b) { + } + + public void bar(float a, float b) { + } + + public void bar(double a, double b) { + } + + public void baz(int a, byte b, byte c) { + } + + public void baz(int a, short b, short c) { + } + + public void baz(int a, char b, char c) { + } + + public void baz(int a, int b, int c) { + } + + public void baz(int a, long b, long c) { + } + + public void baz(int a, float b, float c) { + } + + public void baz(int a, double b, double c) { + } + + public void test() { + int i = 24; + foo((byte) i); + foo((short) i); + foo((char) i); + foo(i); + foo((long) i); + foo((float) i); + foo((double) i); + + bar((byte) 0, (byte) i); + bar((short) 0, (short) i); + bar('\u0000', (char) i); + bar(0, i); + bar(0L, i); + bar(0.0F, i); + bar(0.0, i); + + baz(0, (byte) 127, (byte) i); + baz(0, (short) 32767, (short) i); + baz(0, '\uFFFF', (char) i); + baz(0, Integer.MAX_VALUE, i); + baz(0, Long.MAX_VALUE, i); + baz(0, Float.MAX_VALUE, i); + baz(0, Double.MAX_VALUE, i); + } +} diff --git a/testData/src/java8/pkg/TestSwitchInTry.java b/testData/src/java8/pkg/TestSwitchInTry.java new file mode 100644 index 0000000000..a7450667cf --- /dev/null +++ b/testData/src/java8/pkg/TestSwitchInTry.java @@ -0,0 +1,26 @@ +package pkg; + +import java.util.Arrays; +import java.util.List; + +public class TestSwitchInTry { + /** + * ISSUE 349: Infinite loop in SFormsConstructor->splitVariables + * Submitted by @mvisat + */ + + public static List method(String[] args) { + String ret = ""; + for (String arg : args) { + try { + switch (arg) { + case "a": + ret = "a"; + } + break; + } catch (Exception ex) { + } + } + return Arrays.asList(ret); + } +}