diff --git a/checks/src/main/java/com/kozaxinan/android/checks/RetrofitReturnTypeDetector.kt b/checks/src/main/java/com/kozaxinan/android/checks/RetrofitReturnTypeDetector.kt index 93b91cb..a54bfc1 100644 --- a/checks/src/main/java/com/kozaxinan/android/checks/RetrofitReturnTypeDetector.kt +++ b/checks/src/main/java/com/kozaxinan/android/checks/RetrofitReturnTypeDetector.kt @@ -84,13 +84,19 @@ internal abstract class RetrofitReturnTypeDetector : Detector(), UastScanner { .isNotEmpty() } - private fun findAllInnerFields(typeRef: PsiClassType): Set { + private fun findAllInnerFields(typeRef: PsiClassType, visitedTypes: MutableSet = mutableSetOf()): Set { val actualReturnType = findGenericClassType(typeRef) val typeClass = actualReturnType .resolve() .toUElement() as? UClass ?: return emptySet() + + if (visitedTypes.contains(actualReturnType)) { + return setOf() + } + visitedTypes.add(actualReturnType) + val innerFields: Set = typeClass .fields .filterNot { it.isStatic && it !is PsiEnumConstant } @@ -101,7 +107,8 @@ internal abstract class RetrofitReturnTypeDetector : Detector(), UastScanner { .filterNot { it.isStatic } .map { it.type } .filterIsInstance() - .map(::findAllInnerFields) + .filterNot { visitedTypes.contains(it) } + .map { innerTypeRef -> findAllInnerFields(innerTypeRef, visitedTypes) } .flatten() .toSet() } @@ -113,15 +120,21 @@ internal abstract class RetrofitReturnTypeDetector : Detector(), UastScanner { return if (substitutor == PsiSubstitutor.EMPTY) { returnType } else { - when (val psiType: PsiType = substitutor.substitutionMap.values.first()) { + when (val psiType: PsiType? = substitutor.substitutionMap.values.first()) { is PsiClassReferenceType -> findGenericClassType(psiType) is PsiWildcardType -> { - when (val superBound: PsiType = psiType.superBound) { - is PsiClassType -> findGenericClassType(superBound) - else -> returnType + when { + psiType.isSuper -> { + findGenericClassType(psiType.superBound as PsiClassType) + } + psiType.isExtends -> { + findGenericClassType(psiType.extendsBound as PsiClassType) + } + else -> { + returnType + } } } - else -> returnType } }