fix: replace type variables in arrays (#913)

This commit is contained in:
Skylot
2020-05-12 17:17:22 +01:00
parent 0692464b85
commit 85760cc844
5 changed files with 66 additions and 2 deletions
@@ -5,6 +5,8 @@ import java.util.Collections;
import java.util.List;
import java.util.Objects;
import org.jetbrains.annotations.NotNull;
import jadx.core.Consts;
import jadx.core.dex.info.ClassInfo;
import jadx.core.dex.nodes.ClassNode;
@@ -114,7 +116,7 @@ public abstract class ArgType {
return new OuterGenericObject((GenericObject) genericOuterType, (ObjectType) innerType);
}
public static ArgType array(ArgType vtype) {
public static ArgType array(@NotNull ArgType vtype) {
return new ArrayArg(vtype);
}
@@ -117,6 +117,13 @@ public class TypeUtils {
if (replaceType.isGenericType()) {
return replaceMap.get(replaceType);
}
if (replaceType.isArray()) {
ArgType replaced = replaceTypeVariablesUsingMap(replaceType.getArrayElement(), replaceMap);
if (replaced == null) {
return null;
}
return ArgType.array(replaced);
}
ArgType wildcardType = replaceType.getWildcardType();
if (wildcardType != null && wildcardType.containsTypeVariable()) {
@@ -0,0 +1,45 @@
package jadx.core.dex.nodes.utils;
import java.util.Collections;
import java.util.Map;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import jadx.api.JadxArgs;
import jadx.core.dex.instructions.args.ArgType;
import jadx.core.dex.nodes.RootNode;
import static jadx.core.dex.instructions.args.ArgType.STRING;
import static jadx.core.dex.instructions.args.ArgType.array;
import static jadx.core.dex.instructions.args.ArgType.generic;
import static jadx.core.dex.instructions.args.ArgType.genericType;
import static jadx.core.dex.instructions.args.ArgType.object;
import static org.assertj.core.api.Assertions.assertThat;
class TypeUtilsTest {
private TypeUtils typeUtils;
@BeforeEach
public void init() {
typeUtils = new TypeUtils(new RootNode(new JadxArgs()));
}
@Test
void replaceTypeVariablesUsingMap() {
ArgType typeVar = genericType("T");
ArgType listCls = object("java.util.List");
Map<ArgType, ArgType> typeMap = Collections.singletonMap(typeVar, STRING);
replaceTypeVar(typeVar, typeMap, STRING);
replaceTypeVar(generic(listCls, typeVar), typeMap, generic(listCls, STRING));
replaceTypeVar(array(typeVar), typeMap, array(STRING));
}
private void replaceTypeVar(ArgType typeVar, Map<ArgType, ArgType> typeMap, ArgType expected) {
ArgType resultType = typeUtils.replaceTypeVariablesUsingMap(typeVar, typeMap);
assertThat(resultType)
.as("Replace %s using map %s", typeVar, typeMap)
.isEqualTo(expected);
}
}
@@ -15,6 +15,7 @@ public class TestMethodOverride extends SmaliTest {
assertThat(getClassNodeFromSmali())
.code()
.containsOne("String createFromParcel(Parcel parcel) {")
.containsOne("@Override");
.containsOne("String[] newArray(int i) {")
.countString(2, "@Override");
}
}
@@ -36,3 +36,12 @@
return-object v0
.end method
.method public final synthetic newArray(I)[Ljava/lang/Object;
.registers 2
.line 4
new-array p1, p1, [Ljava/lang/String;
return-object p1
.end method