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 3e7ca0447..4ce8e5172 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/InvocationExprent.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/InvocationExprent.java @@ -397,7 +397,7 @@ else if (!bounds.containsKey(from)) { start = (newNode.access & CodeConstants.ACC_STATIC) == 0 ? 1 : 0; } } - + Set commonGenerics = new HashSet<>(); ClassNode currentNode = DecompilerContext.getContextProperty(DecompilerContext.CURRENT_CLASS_NODE); MethodWrapper methodWrapper = DecompilerContext.getContextProperty(DecompilerContext.CURRENT_METHOD_WRAPPER); @@ -410,7 +410,7 @@ else if (!bounds.containsKey(from)) { parents.add(search); search = (search.access & CodeConstants.ACC_STATIC) == 0 ? search.parent : null; } - + search = newNode; while (search != null) { if (parents.contains(search) && search.classStruct.getSignature() != null) { @@ -812,7 +812,12 @@ else if (instance != null) { ClassNode instNode = DecompilerContext.getClassProcessor().getMapRootClasses().get(classname); // Don't cast to anonymous classes, since they by definition can't have a name // TODO: better fix may be to change equals to isSuperSet? all anonymous classes are superset of Object - if (rightType.equals(VarType.VARTYPE_OBJECT) && !leftType.equals(rightType) && (instNode != null && instNode.type != ClassNode.Type.ANONYMOUS)) { + if (!leftType.equals(rightType) && + (rightType.equals(VarType.VARTYPE_OBJECT) || + // try to preserve for navigation in certain cases: virtual call on variable + (rightType.type != CodeType.UNKNOWN && instance instanceof VarExprent && invocationType == InvocationType.VIRTUAL && !leftType.equals(VarType.VARTYPE_OBJECT)) + ) + ) { appendInstCast(buf, leftType, res); } else if (remappedInstType != null) { // If we have a remap inst type, do a cast @@ -822,10 +827,10 @@ else if (instance != null) { } //Java 9+ adds some overrides to java/nio/Buffer's subclasses that alter the return types. //This isn't properly handled by the compiler. So explicit casts are needed to retain J8 compatibility. - else if (JAVA_NIO_BUFFER.equals(descriptor.ret) && !JAVA_NIO_BUFFER.equals(rightType) - && DecompilerContext.getStructContext().instanceOf(rightType.value, JAVA_NIO_BUFFER.value)) { - buf.append("((").appendCastTypeName(JAVA_NIO_BUFFER).append(")").append(res).append(")"); - } + // else if (JAVA_NIO_BUFFER.equals(descriptor.ret) && !JAVA_NIO_BUFFER.equals(rightType) + // && DecompilerContext.getStructContext().instanceOf(rightType.value, JAVA_NIO_BUFFER.value)) { + // buf.append("((").appendCastTypeName(JAVA_NIO_BUFFER).append(")").append(res).append(")"); + // } else { buf.append(res); } diff --git a/test/org/jetbrains/java/decompiler/SingleClassesTest.java b/test/org/jetbrains/java/decompiler/SingleClassesTest.java index a67fa6b1d..e886e98ec 100644 --- a/test/org/jetbrains/java/decompiler/SingleClassesTest.java +++ b/test/org/jetbrains/java/decompiler/SingleClassesTest.java @@ -711,6 +711,7 @@ private void registerDefault() { register(JAVA_21, "TestCastIntersectionJ21"); register(JAVA_16, "TestRecordLocal"); register(JAVA_8, "TestAnonymousClassToLambda"); + register(JAVA_8, "TryToPreserveCast"); } private void registerEntireClassPath() { diff --git a/testData/results/pkg/TestSynchronizedTry.dec b/testData/results/pkg/TestSynchronizedTry.dec index 48c531412..622ccbf44 100644 --- a/testData/results/pkg/TestSynchronizedTry.dec +++ b/testData/results/pkg/TestSynchronizedTry.dec @@ -1,3 +1,4 @@ + package pkg; public class TestSynchronizedTry { diff --git a/testData/src/java8/pkg/TryToPreserveCast.java b/testData/src/java8/pkg/TryToPreserveCast.java new file mode 100644 index 000000000..f8feb6264 --- /dev/null +++ b/testData/src/java8/pkg/TryToPreserveCast.java @@ -0,0 +1,18 @@ +package pkg; + +import java.nio.Buffer; +import java.nio.ByteBuffer; + +public class TryToPreserveCast { + public TryToPreserveCast() { + } + + public static void main(String[] args) { + + } + + public void test(ByteBuffer buffer) { + ((Buffer) buffer).limit(1); + (buffer).limit(2); + } +} \ No newline at end of file