DfType (@NotNull DfType other) { if (other instanceof DfConstantType || other instanceof DfEphemeralReferenceType) { return other.meet(this); } if (isSuperType(other)) return other; if (other.isSuperType(this)) return this; if (!(other instanceof DfReferenceType type)) return BOTTOM; TypeConstraint constraint = getConstraint().meet(type.getConstraint()); if (constraint == TypeConstraints.BOTTOM) { return isSuperType(DfTypes.NULL) && other.isSuperType(DfTypes.NULL) ? DfTypes.NULL : BOTTOM; } DfaNullability nullability = getNullability().intersect(type.getNullability()); if (nullability == null) return BOTTOM; Mutability mutability = getMutability().meet(type.getMutability()); if (mutability == null) return BOTTOM; boolean locality = isLocal() || type.isLocal(); SpecialField sf; DfType sfType; if (getSpecialField() == null) { sf = type.getSpecialField(); sfType = type.getSpecialFieldType(); } else if (type.getSpecialField() == null) { sf = getSpecialField(); sfType = getSpecialFieldType(); } else { sf = getSpecialField(); if (sf != type.getSpecialField()) return BOTTOM; sfType = getSpecialFieldType().meet(type.getSpecialFieldType()); } if (sf != null && sfType == BOTTOM) return BOTTOM; Set<Object> notValues = myNotValues; if (type instanceof DfGenericObjectType) { Set<Object> otherNotValues = ((DfGenericObjectType)other).myNotValues; if (otherNotValues.containsAll(myNotValues)) { notValues = otherNotValues; } else if (!myNotValues.containsAll(otherNotValues)) { notValues = new HashSet<>(myNotValues); notValues.addAll(otherNotValues); if (nullability == DfaNullability.NOT_NULL) { DfEphemeralReferenceType ephemeralValue = checkEphemeral(constraint, notValues); if (ephemeralValue != null) { return ephemeralValue; } } } } if (nullability == DfaNullability.NOT_NULL && constraint.isSingleton()) { return new DfReferenceConstantType(constraint, constraint, false); } return new DfGenericObjectType(notValues, constraint, nullability, mutability, sf, sfType, locality); }