fix: improve type inference for arrays (#837)
This commit is contained in:
@@ -96,13 +96,13 @@ public final class TypeUpdate {
|
||||
TypeCompareEnum compareResult = comparator.compareTypes(candidateType, currentType);
|
||||
if (arg.isTypeImmutable() && currentType != ArgType.UNKNOWN) {
|
||||
// don't changed type
|
||||
if (compareResult == TypeCompareEnum.CONFLICT) {
|
||||
if (Consts.DEBUG) {
|
||||
LOG.debug("Type rejected for {} due to conflict: candidate={}, current={}", arg, candidateType, currentType);
|
||||
}
|
||||
return REJECT;
|
||||
if (compareResult == TypeCompareEnum.EQUAL) {
|
||||
return SAME;
|
||||
}
|
||||
return SAME;
|
||||
if (Consts.DEBUG) {
|
||||
LOG.debug("Type rejected for {} due to conflict: candidate={}, current={}", arg, candidateType, currentType);
|
||||
}
|
||||
return REJECT;
|
||||
}
|
||||
if (compareResult.isWider() && !updateInfo.getFlags().isAllowWider()) {
|
||||
if (Consts.DEBUG) {
|
||||
@@ -412,7 +412,7 @@ public final class TypeUpdate {
|
||||
TypeUpdateResult result = updateTypeChecked(updateInfo, putArg, arrayElement);
|
||||
if (result == REJECT) {
|
||||
ArgType putType = putArg.getType();
|
||||
if (putType.isTypeKnown() && putType.isObject()) {
|
||||
if (putType.isTypeKnown() && !putType.isPrimitive()) {
|
||||
TypeCompareEnum compResult = comparator.compareTypes(arrayElement, putType);
|
||||
if (compResult == TypeCompareEnum.WIDER || compResult == TypeCompareEnum.WIDER_BY_GENERIC) {
|
||||
// allow wider result (i.e allow put in Object[] any objects)
|
||||
|
||||
@@ -15,6 +15,7 @@ import jadx.core.dex.instructions.args.ArgType;
|
||||
import jadx.core.dex.nodes.RootNode;
|
||||
|
||||
import static jadx.core.dex.instructions.args.ArgType.BOOLEAN;
|
||||
import static jadx.core.dex.instructions.args.ArgType.BYTE;
|
||||
import static jadx.core.dex.instructions.args.ArgType.CHAR;
|
||||
import static jadx.core.dex.instructions.args.ArgType.CLASS;
|
||||
import static jadx.core.dex.instructions.args.ArgType.INT;
|
||||
@@ -77,6 +78,9 @@ public class TypeCompareTest {
|
||||
|
||||
firstIsNarrow(UNKNOWN_ARRAY, OBJECT);
|
||||
|
||||
firstIsNarrow(array(BYTE), OBJECT);
|
||||
firstIsNarrow(array(array(BYTE)), array(OBJECT));
|
||||
|
||||
check(array(OBJECT), array(INT), TypeCompareEnum.CONFLICT);
|
||||
|
||||
ArgType integerType = ArgType.object("java.lang.Integer");
|
||||
|
||||
@@ -1,16 +1,19 @@
|
||||
package jadx.tests.integration.types;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import jadx.NotYetImplemented;
|
||||
import jadx.tests.api.IntegrationTest;
|
||||
|
||||
import static jadx.tests.api.utils.assertj.JadxAssertions.assertThat;
|
||||
|
||||
public class TestTypeResolver11 extends IntegrationTest {
|
||||
|
||||
public static class TestCls {
|
||||
public Void test(Object... objArr) {
|
||||
int val = (Integer) objArr[0];
|
||||
String str = (String) objArr[1];
|
||||
public Void test(Object... objects) {
|
||||
int val = (Integer) objects[0];
|
||||
String str = (String) objects[1];
|
||||
call(str, str, val, val);
|
||||
return null;
|
||||
}
|
||||
@@ -18,21 +21,31 @@ public class TestTypeResolver11 extends IntegrationTest {
|
||||
private void call(String a, String b, int... val) {
|
||||
}
|
||||
|
||||
private boolean test2(String s1, String... args) {
|
||||
String str = Arrays.toString(args);
|
||||
return s1.length() + str.length() > 0;
|
||||
}
|
||||
|
||||
public void check() {
|
||||
test(1, "str");
|
||||
assertThat(test2("1", "2", "34")).isTrue();
|
||||
}
|
||||
}
|
||||
|
||||
@NotYetImplemented("Missing cast")
|
||||
@Test
|
||||
public void test() {
|
||||
getClassNode(TestCls.class);
|
||||
assertThat(getClassNode(TestCls.class))
|
||||
.code()
|
||||
.containsOne("(Integer) objects[0]")
|
||||
.containsOne("String str = (String) objects[1];");
|
||||
}
|
||||
|
||||
@NotYetImplemented("Missing cast")
|
||||
@Test
|
||||
public void testNoDebug() {
|
||||
noDebugInfo();
|
||||
getClassNode(TestCls.class);
|
||||
assertThat(getClassNode(TestCls.class))
|
||||
.code()
|
||||
.containsOne("(Integer) objArr[0]")
|
||||
.containsOne("String str = (String) objArr[1];");
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user