fix: use soft checks for objects and arrays in 'if' type listener (#401)
This commit is contained in:
@@ -518,6 +518,14 @@ public abstract class ArgType {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean canBeObject() {
|
||||
return isObject() || (!isTypeKnown() && contains(PrimitiveType.OBJECT));
|
||||
}
|
||||
|
||||
public boolean canBeArray() {
|
||||
return isArray() || (!isTypeKnown() && contains(PrimitiveType.ARRAY));
|
||||
}
|
||||
|
||||
public static ArgType convertFromPrimitiveType(PrimitiveType primitiveType) {
|
||||
switch (primitiveType) {
|
||||
case BOOLEAN:
|
||||
|
||||
@@ -306,7 +306,18 @@ public final class TypeUpdate {
|
||||
InsnArg firstArg = insn.getArg(0);
|
||||
InsnArg secondArg = insn.getArg(1);
|
||||
InsnArg updateArg = firstArg == arg ? secondArg : firstArg;
|
||||
return updateTypeChecked(updateInfo, updateArg, candidateType);
|
||||
TypeUpdateResult result = updateTypeChecked(updateInfo, updateArg, candidateType);
|
||||
if (result == REJECT) {
|
||||
// soft checks for objects and array - exact type not compared
|
||||
ArgType updateArgType = updateArg.getType();
|
||||
if (candidateType.isObject() && updateArgType.canBeObject()) {
|
||||
return SAME;
|
||||
}
|
||||
if (candidateType.isArray() && updateArgType.canBeArray()) {
|
||||
return SAME;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private static boolean isAssign(InsnNode insn, InsnArg arg) {
|
||||
|
||||
@@ -0,0 +1,64 @@
|
||||
package jadx.tests.integration.types;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import jadx.core.dex.nodes.ClassNode;
|
||||
import jadx.tests.api.IntegrationTest;
|
||||
|
||||
import static jadx.tests.api.utils.JadxMatchers.containsOne;
|
||||
import static org.hamcrest.Matchers.anyOf;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotEquals;
|
||||
import static org.junit.Assert.assertThat;
|
||||
|
||||
public class TestConstTypeInference extends IntegrationTest {
|
||||
|
||||
public static class TestCls {
|
||||
private final int a;
|
||||
|
||||
public TestCls() {
|
||||
this(0);
|
||||
}
|
||||
|
||||
public TestCls(int a) {
|
||||
this.a = a;
|
||||
}
|
||||
|
||||
public boolean equals(Object obj) {
|
||||
if (obj == this) {
|
||||
return true;
|
||||
}
|
||||
if (obj != null) {
|
||||
if (getClass() == obj.getClass()) {
|
||||
TestCls other = (TestCls) obj;
|
||||
return this.a == other.a;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public void check() {
|
||||
TestCls seven = new TestCls(7);
|
||||
assertEquals(seven, seven);
|
||||
assertNotEquals(seven, null);
|
||||
|
||||
TestCls six = new TestCls(6);
|
||||
assertNotEquals(seven, six);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test() {
|
||||
ClassNode cls = getClassNode(TestCls.class);
|
||||
String code = cls.getCode().toString();
|
||||
|
||||
assertThat(code, containsOne("obj == this"));
|
||||
assertThat(code, anyOf(containsOne("obj == null"), containsOne("obj != null")));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test2() {
|
||||
noDebugInfo();
|
||||
getClassNode(TestCls.class);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user