boolean (PsiExpression expr, PsiType sType, PsiType tType) { if (expr instanceof PsiParenthesizedExpression) { return isFunctionalTypeMoreSpecific(((PsiParenthesizedExpression)expr).getExpression(), sType, tType); } if (expr instanceof PsiConditionalExpression) { return isFunctionalTypeMoreSpecific(((PsiConditionalExpression)expr).getThenExpression(), sType, tType) && isFunctionalTypeMoreSpecific(((PsiConditionalExpression)expr).getElseExpression(), sType, tType); } if (expr instanceof PsiSwitchExpression) { return PsiUtil.getSwitchResultExpressions((PsiSwitchExpression)expr).stream().allMatch(resultExpr -> isFunctionalTypeMoreSpecific(resultExpr, sType, tType)); } if (expr instanceof PsiFunctionalExpression) { if (expr instanceof PsiLambdaExpression && !((PsiLambdaExpression)expr).hasFormalParameterTypes()) { return false; } if (expr instanceof PsiMethodReferenceExpression && !((PsiMethodReferenceExpression)expr).isExact()) { return false; } if (LambdaUtil.isFunctionalType(sType) && LambdaUtil.isFunctionalType(tType) && !TypeConversionUtil.erasure(tType).isAssignableFrom(sType) && !TypeConversionUtil.erasure(sType).isAssignableFrom(tType)) { return InferenceSession.isFunctionalTypeMoreSpecificOnExpression(sType, tType, expr); } } return false; }