String (@NotNull PsiClass psiClass, @NotNull PsiAnnotation psiAnnotation, boolean hasCanEqualMethod, Collection<MemberInfo> memberInfos) { final boolean callSuper = readCallSuperAnnotationOrConfigProperty(psiAnnotation, psiClass, ConfigKey.EQUALSANDHASHCODE_CALL_SUPER); final boolean doNotUseGetters = readAnnotationOrConfigProperty(psiAnnotation, psiClass, "doNotUseGetters", ConfigKey.EQUALSANDHASHCODE_DO_NOT_USE_GETTERS); final String canonicalClassName = PsiTypesUtil.getClassType(psiClass).getCanonicalText(); final String canonicalWildcardClassName = PsiClassUtil.getWildcardClassType(psiClass).getCanonicalText(); final StringBuilder builder = new StringBuilder(); builder.append("if (o == this) return true;\n"); builder.append("if (!(o instanceof ").append(canonicalClassName).append(")) return false;\n"); builder.append("final ").append(canonicalWildcardClassName).append(" other = (").append(canonicalWildcardClassName).append(")o;\n"); if (hasCanEqualMethod) { builder.append("if (!other.canEqual((java.lang.Object)this)) return false;\n"); } if (callSuper) { builder.append("if (!super.equals(o)) return false;\n"); } for (MemberInfo memberInfo : memberInfos) { final String memberAccessor = EqualsAndHashCodeToStringHandler.getMemberAccessorName(memberInfo, doNotUseGetters, psiClass); final PsiType memberType = memberInfo.getType(); if (memberType instanceof PsiPrimitiveType) { if (PsiTypes.floatType().equals(memberType)) { builder.append("if (java.lang.Float.compare(this.").append(memberAccessor).append(", other.").append(memberAccessor) .append(") != 0) return false;\n"); } else if (PsiTypes.doubleType().equals(memberType)) { builder.append("if (java.lang.Double.compare(this.").append(memberAccessor).append(", other.").append(memberAccessor) .append(") != 0) return false;\n"); } else { builder.append("if (this.").append(memberAccessor).append(" != other.").append(memberAccessor).append(") return false;\n"); } } else if (memberType instanceof PsiArrayType) { final PsiType componentType = ((PsiArrayType)memberType).getComponentType(); if (componentType instanceof PsiPrimitiveType) { builder.append("if (!java.util.Arrays.equals(this.").append(memberAccessor).append(", other.").append(memberAccessor) .append(")) return false;\n"); } else { builder.append("if (!java.util.Arrays.deepEquals(this.").append(memberAccessor).append(", other.").append(memberAccessor) .append(")) return false;\n"); } } else { final String memberName = memberInfo.getName(); builder.append("final java.lang.Object this$").append(memberName).append(" = this.").append(memberAccessor).append(";\n"); builder.append("final java.lang.Object other$").append(memberName).append(" = other.").append(memberAccessor).append(";\n"); builder.append("if (this$").append(memberName).append(" == null ? other$").append(memberName).append(" != null : !this$") .append(memberName).append(".equals(other$").append(memberName).append(")) return false;\n"); } } builder.append("return true;\n"); return builder.toString(); }