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 {
} 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);
......
......@@ -48,5 +48,7 @@ public enum AFlag {
FALL_THROUGH,
EXPLICIT_GENERICS,
INCONSISTENT_CODE, // warning about incorrect decompilation
}
......@@ -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<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((List<String>) new ArrayList<String>());"));
......
......@@ -15,11 +15,10 @@ public class TestVariablesUsageWithLoops extends IntegrationTest {
public static class TestEnhancedFor {
@SuppressWarnings("rawtypes")
public void test() {
List list;
List<Object> 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<Object> 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<>"));
}
}
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