Commit bcfed5b3 authored by Ahmed Ashour's avatar Ahmed Ashour Committed by skylot

fix: generics constructor types (PR #594)

parent 4cb9f23a
...@@ -569,6 +569,21 @@ public class InsnGen { ...@@ -569,6 +569,21 @@ public class InsnGen {
} else { } else {
code.add("new "); code.add("new ");
useClass(code, insn.getClassType()); 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()); MethodNode callMth = mth.dex().resolveMethod(insn.getCallMth());
generateMethodArguments(code, insn, 0, callMth); generateMethodArguments(code, insn, 0, callMth);
...@@ -749,9 +764,17 @@ public class InsnGen { ...@@ -749,9 +764,17 @@ public class InsnGen {
if (argType.equals(origType)) { if (argType.equals(origType)) {
return false; return false;
} }
if (origType.isGeneric() if (origType.isGeneric()) {
&& origType.getObject().equals(argType.getObject())) { if (!argType.isGeneric() && arg.isInsnWrap()) {
return false; ((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('('); code.add('(');
useType(code, origType); useType(code, origType);
......
...@@ -48,5 +48,7 @@ public enum AFlag { ...@@ -48,5 +48,7 @@ public enum AFlag {
FALL_THROUGH, FALL_THROUGH,
EXPLICIT_GENERICS,
INCONSISTENT_CODE, // warning about incorrect decompilation INCONSISTENT_CODE, // warning about incorrect decompilation
} }
...@@ -5,7 +5,6 @@ import java.util.List; ...@@ -5,7 +5,6 @@ import java.util.List;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import jadx.NotYetImplemented;
import jadx.core.dex.nodes.ClassNode; import jadx.core.dex.nodes.ClassNode;
import jadx.tests.api.IntegrationTest; import jadx.tests.api.IntegrationTest;
...@@ -55,18 +54,6 @@ public class TestCastInOverloadedInvoke extends IntegrationTest { ...@@ -55,18 +54,6 @@ public class TestCastInOverloadedInvoke extends IntegrationTest {
ClassNode cls = getClassNode(TestCls.class); ClassNode cls = getClassNode(TestCls.class);
String code = cls.getCode().toString(); String code = cls.getCode().toString();
assertThat(code, containsOne("call(new ArrayList());"));
assertThat(code, containsOne("call((List<String>) 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(new ArrayList<>());"));
assertThat(code, containsOne("call((List<String>) new ArrayList<String>());")); assertThat(code, containsOne("call((List<String>) new ArrayList<String>());"));
......
...@@ -15,11 +15,10 @@ public class TestVariablesUsageWithLoops extends IntegrationTest { ...@@ -15,11 +15,10 @@ public class TestVariablesUsageWithLoops extends IntegrationTest {
public static class TestEnhancedFor { public static class TestEnhancedFor {
@SuppressWarnings("rawtypes")
public void test() { public void test() {
List list; List<Object> list;
synchronized (this) { synchronized (this) {
list = new ArrayList(); list = new ArrayList<>();
} }
for (Object o : list) { for (Object o : list) {
System.out.println(o); System.out.println(o);
...@@ -32,15 +31,15 @@ public class TestVariablesUsageWithLoops extends IntegrationTest { ...@@ -32,15 +31,15 @@ public class TestVariablesUsageWithLoops extends IntegrationTest {
ClassNode cls = getClassNode(TestEnhancedFor.class); ClassNode cls = getClassNode(TestEnhancedFor.class);
String code = cls.getCode().toString(); String code = cls.getCode().toString();
assertThat(code, containsString(" list = new ArrayList")); assertThat(code, containsString(" list = new ArrayList<>"));
} }
public static class TestForLoop { public static class TestForLoop {
public void test() { public void test() {
List list; List<Object> list;
synchronized (this) { synchronized (this) {
list = new ArrayList(); list = new ArrayList<>();
} }
for (int i = 0; i < list.size(); i++) { for (int i = 0; i < list.size(); i++) {
System.out.println(i); System.out.println(i);
...@@ -53,6 +52,6 @@ public class TestVariablesUsageWithLoops extends IntegrationTest { ...@@ -53,6 +52,6 @@ public class TestVariablesUsageWithLoops extends IntegrationTest {
ClassNode cls = getClassNode(TestForLoop.class); ClassNode cls = getClassNode(TestForLoop.class);
String code = cls.getCode().toString(); String code = cls.getCode().toString();
assertThat(code, containsString(" list = new ArrayList")); assertThat(code, containsString(" list = new ArrayList<>"));
} }
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment