fix: handle wildcard in invoke type resolver (#1238)

This commit is contained in:
Skylot
2022-04-18 16:09:33 +01:00
parent abcaafa89a
commit b66293a2f7
9 changed files with 249 additions and 6 deletions
@@ -0,0 +1,75 @@
package jadx.tests.integration.types;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import org.junit.jupiter.api.Test;
import jadx.tests.api.SmaliTest;
import jadx.tests.api.extensions.profiles.TestProfile;
import jadx.tests.api.extensions.profiles.TestWithProfiles;
import static jadx.tests.api.utils.assertj.JadxAssertions.assertThat;
/**
* Issue 1238
*/
public class TestTypeResolver20 extends SmaliTest {
public static class TestCls {
public interface Sequence<T> {
Iterator<T> iterator();
}
public static <T extends Comparable<? super T>> T max(Sequence<? extends T> seq) {
Iterator<? extends T> it = seq.iterator();
if (!it.hasNext()) {
return null;
}
T t = it.next();
while (it.hasNext()) {
T next = it.next();
if (t.compareTo(next) < 0) {
t = next;
}
}
return t;
}
private static class ArraySeq<T> implements Sequence<T> {
private final List<T> list;
@SafeVarargs
public ArraySeq(T... arr) {
this.list = Arrays.asList(arr);
}
@Override
public Iterator<T> iterator() {
return list.iterator();
}
}
public void check() {
assertThat(max(new ArraySeq<>(2, 5, 3, 4))).isEqualTo(5);
}
}
@TestWithProfiles({ TestProfile.DX_J8, TestProfile.JAVA8 })
public void test() {
noDebugInfo();
assertThat(getClassNode(TestCls.class))
.code()
.doesNotContain("next = next;")
.containsOne("T next = it.next();");
}
@Test
public void testSmali() {
assertThat(getClassNodeFromSmaliFiles())
.code()
.containsOne("T next = it.next();")
.containsOne("T next2 = it.next();");
}
}
@@ -0,0 +1,22 @@
.class public interface abstract Lkotlin/sequences/Sequence;
.super Ljava/lang/Object;
.source "SourceFile"
.annotation system Ldalvik/annotation/Signature;
value = {
"<T:",
"Ljava/lang/Object;",
">",
"Ljava/lang/Object;"
}
.end annotation
.method public abstract iterator()Ljava/util/Iterator;
.annotation system Ldalvik/annotation/Signature;
value = {
"()",
"Ljava/util/Iterator<",
"TT;>;"
}
.end annotation
.end method
@@ -0,0 +1,61 @@
.class public Ltypes/TestTypeResolver20;
.super Ljava/lang/Object;
.source "SourceFile"
.method public static final max(Lkotlin/sequences/Sequence;)Ljava/lang/Comparable;
.registers 4
.annotation system Ldalvik/annotation/Signature;
value = {
"<T::",
"Ljava/lang/Comparable<",
"-TT;>;>(",
"Lkotlin/sequences/Sequence<",
"+TT;>;)TT;"
}
.end annotation
.line 1147
invoke-interface {p0}, Lkotlin/sequences/Sequence;->iterator()Ljava/util/Iterator;
move-result-object p0
.line 1148
invoke-interface {p0}, Ljava/util/Iterator;->hasNext()Z
move-result v0
if-nez v0, :cond_11
const/4 p0, 0x0
return-object p0
.line 1149
:cond_11
invoke-interface {p0}, Ljava/util/Iterator;->next()Ljava/lang/Object;
move-result-object v0
check-cast v0, Ljava/lang/Comparable;
.line 1150
:cond_17
:goto_17
invoke-interface {p0}, Ljava/util/Iterator;->hasNext()Z
move-result v1
if-eqz v1, :cond_2b
.line 1151
invoke-interface {p0}, Ljava/util/Iterator;->next()Ljava/lang/Object;
move-result-object v1
check-cast v1, Ljava/lang/Comparable;
.line 1152
invoke-interface {v0, v1}, Ljava/lang/Comparable;->compareTo(Ljava/lang/Object;)I
move-result v2
if-gez v2, :cond_17
move-object v0, v1
goto :goto_17
:cond_2b
return-object v0
.end method