boolean (@NotNull PsiManager manager, @NotNull PsiType type1, @NotNull PsiType type2, Set<? super String> visited) { if (type1 instanceof PsiArrayType) { if (type2 instanceof PsiArrayType) { PsiType componentType1 = ((PsiArrayType)type1).getComponentType(); PsiType componentType2 = ((PsiArrayType)type2).getComponentType(); if (compareParamTypes(manager, componentType1, componentType2, visited)) return true; } return false; } if (!(type1 instanceof PsiClassType) || !(type2 instanceof PsiClassType)) { return type1.equals(type2); } PsiClass class1 = ((PsiClassType)type1).resolve(); PsiClass class2 = ((PsiClassType)type2).resolve(); visited.add(type1.getCanonicalText()); visited.add(type2.getCanonicalText()); if (class1 instanceof PsiTypeParameter && class2 instanceof PsiTypeParameter) { if (!(Objects.equals(class1.getName(), class2.getName()) && ((PsiTypeParameter)class1).getIndex() == ((PsiTypeParameter)class2).getIndex())) return false; PsiClassType[] eTypes1 = class1.getExtendsListTypes(); PsiClassType[] eTypes2 = class2.getExtendsListTypes(); if (eTypes1.length != eTypes2.length) return false; for (int i = 0; i < eTypes1.length; i++) { PsiClassType eType1 = eTypes1[i]; PsiClassType eType2 = eTypes2[i]; if (visited.contains(eType1.getCanonicalText()) || visited.contains(eType2.getCanonicalText())) { return false; } if (!compareParamTypes(manager, eType1, eType2, visited)) return false; } return true; } return manager.areElementsEquivalent(class1, class2); }