diff --git a/jadx-core/src/main/java/jadx/core/dex/visitors/typeinference/TypeCompare.java b/jadx-core/src/main/java/jadx/core/dex/visitors/typeinference/TypeCompare.java index cf05bec9b..45480b9f5 100644 --- a/jadx-core/src/main/java/jadx/core/dex/visitors/typeinference/TypeCompare.java +++ b/jadx-core/src/main/java/jadx/core/dex/visitors/typeinference/TypeCompare.java @@ -174,15 +174,24 @@ public class TypeCompare { // both wildcards return compareWildcardTypes(first, second); } - // compare generics arrays ArgType[] firstGenericTypes = first.getGenericTypes(); ArgType[] secondGenericTypes = second.getGenericTypes(); - int len = firstGenericTypes.length; - if (len == secondGenericTypes.length) { - for (int i = 0; i < len; i++) { - TypeCompareEnum res = compareTypes(firstGenericTypes[i], secondGenericTypes[i]); - if (res != EQUAL) { - return res; + if (firstGenericTypes == null || secondGenericTypes == null) { + // check outer types + ArgType firstOuterType = first.getOuterType(); + ArgType secondOuterType = second.getOuterType(); + if (firstOuterType != null && secondOuterType != null) { + return compareTypes(firstOuterType, secondOuterType); + } + } else { + // compare generics arrays + int len = firstGenericTypes.length; + if (len == secondGenericTypes.length) { + for (int i = 0; i < len; i++) { + TypeCompareEnum res = compareTypes(firstGenericTypes[i], secondGenericTypes[i]); + if (res != EQUAL) { + return res; + } } } } diff --git a/jadx-core/src/test/java/jadx/core/dex/visitors/typeinference/TypeCompareTest.java b/jadx-core/src/test/java/jadx/core/dex/visitors/typeinference/TypeCompareTest.java index 1660b3478..035a35892 100644 --- a/jadx-core/src/test/java/jadx/core/dex/visitors/typeinference/TypeCompareTest.java +++ b/jadx-core/src/test/java/jadx/core/dex/visitors/typeinference/TypeCompareTest.java @@ -155,6 +155,16 @@ public class TypeCompareTest { check(vType, ArgType.STRING, TypeCompareEnum.CONFLICT); } + @Test + public void compareOuterGenerics() { + ArgType hashMapType = object("java.util.HashMap"); + ArgType innerEntrySetType = object("EntrySet"); + ArgType firstInstance = ArgType.outerGeneric(generic(hashMapType, STRING, STRING), innerEntrySetType); + ArgType secondInstance = ArgType.outerGeneric(generic(hashMapType, OBJECT, OBJECT), innerEntrySetType); + + check(firstInstance, secondInstance, TypeCompareEnum.NARROW); + } + private void firstIsNarrow(ArgType first, ArgType second) { check(first, second, TypeCompareEnum.NARROW); }