diff --git a/jadx-core/src/main/java/jadx/core/codegen/InsnGen.java b/jadx-core/src/main/java/jadx/core/codegen/InsnGen.java index 0301cae82..bbb7241ab 100644 --- a/jadx-core/src/main/java/jadx/core/codegen/InsnGen.java +++ b/jadx-core/src/main/java/jadx/core/codegen/InsnGen.java @@ -569,6 +569,21 @@ public class InsnGen { } else { code.add("new "); useClass(code, insn.getClassType()); + ArgType argType = insn.getResult().getSVar().getCodeVar().getType(); + if (argType.isGeneric()) { + code.add('<'); + if (insn.contains(AFlag.EXPLICIT_GENERICS)) { + boolean first = true; + for (ArgType type : argType.getGenericTypes()) { + if (!first) { + code.add(','); + } + mgen.getClassGen().useType(code, type); + first = false; + } + } + code.add('>'); + } } MethodNode callMth = mth.dex().resolveMethod(insn.getCallMth()); generateMethodArguments(code, insn, 0, callMth); @@ -749,9 +764,17 @@ public class InsnGen { if (argType.equals(origType)) { return false; } - if (origType.isGeneric() - && origType.getObject().equals(argType.getObject())) { - return false; + if (origType.isGeneric()) { + if (!argType.isGeneric() && arg.isInsnWrap()) { + ((InsnWrapArg) arg).getWrapInsn().getResult().setType( + ArgType.generic(argType.getObject(), origType.getGenericTypes())); + } + if (origType.getObject().equals(argType.getObject())) { + return false; + } + if (arg.isInsnWrap()) { + ((InsnWrapArg) arg).getWrapInsn().add(AFlag.EXPLICIT_GENERICS); + } } code.add('('); useType(code, origType); diff --git a/jadx-core/src/main/java/jadx/core/dex/attributes/AFlag.java b/jadx-core/src/main/java/jadx/core/dex/attributes/AFlag.java index 27cec6bc1..8b62c61cd 100644 --- a/jadx-core/src/main/java/jadx/core/dex/attributes/AFlag.java +++ b/jadx-core/src/main/java/jadx/core/dex/attributes/AFlag.java @@ -48,5 +48,7 @@ public enum AFlag { FALL_THROUGH, + EXPLICIT_GENERICS, + INCONSISTENT_CODE, // warning about incorrect decompilation } diff --git a/jadx-core/src/test/java/jadx/tests/integration/invoke/TestCastInOverloadedInvoke.java b/jadx-core/src/test/java/jadx/tests/integration/invoke/TestCastInOverloadedInvoke.java index d5b1fbbb8..77ea6e7bb 100644 --- a/jadx-core/src/test/java/jadx/tests/integration/invoke/TestCastInOverloadedInvoke.java +++ b/jadx-core/src/test/java/jadx/tests/integration/invoke/TestCastInOverloadedInvoke.java @@ -5,7 +5,6 @@ import java.util.List; import org.junit.jupiter.api.Test; -import jadx.NotYetImplemented; import jadx.core.dex.nodes.ClassNode; import jadx.tests.api.IntegrationTest; @@ -55,18 +54,6 @@ public class TestCastInOverloadedInvoke extends IntegrationTest { ClassNode cls = getClassNode(TestCls.class); String code = cls.getCode().toString(); - assertThat(code, containsOne("call(new ArrayList());")); - assertThat(code, containsOne("call((List) new ArrayList());")); - - assertThat(code, containsOne("call((String) obj);")); - } - - @Test - @NotYetImplemented - public void testNYI() { - ClassNode cls = getClassNode(TestCls.class); - String code = cls.getCode().toString(); - assertThat(code, containsOne("call(new ArrayList<>());")); assertThat(code, containsOne("call((List) new ArrayList());")); diff --git a/jadx-core/src/test/java/jadx/tests/integration/variables/TestVariablesUsageWithLoops.java b/jadx-core/src/test/java/jadx/tests/integration/variables/TestVariablesUsageWithLoops.java index e75bcb20a..1e2fe25a8 100644 --- a/jadx-core/src/test/java/jadx/tests/integration/variables/TestVariablesUsageWithLoops.java +++ b/jadx-core/src/test/java/jadx/tests/integration/variables/TestVariablesUsageWithLoops.java @@ -15,11 +15,10 @@ public class TestVariablesUsageWithLoops extends IntegrationTest { public static class TestEnhancedFor { - @SuppressWarnings("rawtypes") public void test() { - List list; + List list; synchronized (this) { - list = new ArrayList(); + list = new ArrayList<>(); } for (Object o : list) { System.out.println(o); @@ -32,15 +31,15 @@ public class TestVariablesUsageWithLoops extends IntegrationTest { ClassNode cls = getClassNode(TestEnhancedFor.class); String code = cls.getCode().toString(); - assertThat(code, containsString(" list = new ArrayList")); + assertThat(code, containsString(" list = new ArrayList<>")); } public static class TestForLoop { public void test() { - List list; + List list; synchronized (this) { - list = new ArrayList(); + list = new ArrayList<>(); } for (int i = 0; i < list.size(); i++) { System.out.println(i); @@ -53,6 +52,6 @@ public class TestVariablesUsageWithLoops extends IntegrationTest { ClassNode cls = getClassNode(TestForLoop.class); String code = cls.getCode().toString(); - assertThat(code, containsString(" list = new ArrayList")); + assertThat(code, containsString(" list = new ArrayList<>")); } }