PsiType () { PsiExpression expr1 = getThenExpression(); PsiExpression expr2 = getElseExpression(); PsiType type1 = expr1 == null ? null : expr1.getType(); PsiType type2 = expr2 == null ? null : expr2.getType(); if (Objects.equals(type1, type2)) return type1; if (PsiUtil.isLanguageLevel8OrHigher(this) && PsiPolyExpressionUtil.isPolyExpression(this)) { //15.25.3 Reference Conditional Expressions // The type of a poly reference conditional expression is the same as its target type. PsiType targetType = InferenceSession.getTargetType(this); if (MethodCandidateInfo.isOverloadCheck()) { return targetType != null && type1 != null && type2 != null && targetType.isAssignableFrom(type1) && targetType.isAssignableFrom(type2) ? targetType : null; } //for standalone conditional expression try to detect target type by type of the sides if (targetType != null) { return targetType; } } if (type1 == null) return type2; if (type2 == null) return type1; final int typeRank1 = TypeConversionUtil.getTypeRank(type1); final int typeRank2 = TypeConversionUtil.getTypeRank(type2); // bug in JLS3, see http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6888770 if (type1 instanceof PsiClassType && type2.equals(PsiPrimitiveType.getUnboxedType(type1))) return type2; if (type2 instanceof PsiClassType && type1.equals(PsiPrimitiveType.getUnboxedType(type2))) return type1; if (TypeConversionUtil.isNumericType(typeRank1) && TypeConversionUtil.isNumericType(typeRank2)){ if (typeRank1 == TypeConversionUtil.BYTE_RANK && typeRank2 == TypeConversionUtil.SHORT_RANK) { return type2 instanceof PsiPrimitiveType ? type2 : PsiPrimitiveType.getUnboxedType(type2); } if (typeRank1 == TypeConversionUtil.SHORT_RANK && typeRank2 == TypeConversionUtil.BYTE_RANK) { return type1 instanceof PsiPrimitiveType ? type1 : PsiPrimitiveType.getUnboxedType(type1); } if (typeRank2 == TypeConversionUtil.INT_RANK && (typeRank1 == TypeConversionUtil.BYTE_RANK || typeRank1 == TypeConversionUtil.SHORT_RANK || typeRank1 == TypeConversionUtil.CHAR_RANK)){ if (TypeConversionUtil.areTypesAssignmentCompatible(type1, expr2)) return type1; } if (typeRank1 == TypeConversionUtil.INT_RANK && (typeRank2 == TypeConversionUtil.BYTE_RANK || typeRank2 == TypeConversionUtil.SHORT_RANK || typeRank2 == TypeConversionUtil.CHAR_RANK)){ if (TypeConversionUtil.areTypesAssignmentCompatible(type2, expr1)) return type2; } return TypeConversionUtil.binaryNumericPromotion(type1, type2); } if (TypeConversionUtil.isNullType(type1) && !(type2 instanceof PsiPrimitiveType)) return type2; if (TypeConversionUtil.isNullType(type2) && !(type1 instanceof PsiPrimitiveType)) return type1; if (TypeConversionUtil.isAssignable(type1, type2, false)) return type1; if (TypeConversionUtil.isAssignable(type2, type1, false)) return type2; if (!PsiUtil.isLanguageLevel5OrHigher(this)) { return null; } if (TypeConversionUtil.isPrimitiveAndNotNull(type1)) { type1 = ((PsiPrimitiveType)type1).getBoxedType(this); if (type1 == null) return null; } if (TypeConversionUtil.isPrimitiveAndNotNull(type2)) { type2 = ((PsiPrimitiveType)type2).getBoxedType(this); if (type2 == null) return null; } if (type1 instanceof PsiLambdaParameterType || type2 instanceof PsiLambdaParameterType) return null; final PsiType leastUpperBound = GenericsUtil.getLeastUpperBound(type1, type2, getManager()); return leastUpperBound != null ? PsiUtil.captureToplevelWildcards(leastUpperBound, this) : null; }