PsiType (final PsiElement context, Ref<String> errorMessage, boolean inferParent) { PsiType targetType = PsiTypesUtil.getExpectedTypeByParent(context); if (targetType != null) { return targetType; } final PsiElement parent = PsiUtil.skipParenthesizedExprUp(context.getParent()); if (parent instanceof PsiExpressionList) { PsiElement gParent = parent.getParent(); if (gParent instanceof PsiAnonymousClass) { gParent = gParent.getParent(); } if (gParent instanceof PsiCall) { final PsiExpressionList argumentList = ((PsiCall)gParent).getArgumentList(); if (argumentList != null) { if (MethodCandidateInfo.isOverloadCheck(argumentList)) { return ThreadLocalTypes.getElementType(context); } final JavaResolveResult result = PsiDiamondType.getDiamondsAwareResolveResult((PsiCall)gParent); final PsiElement element = result.getElement(); if (element == null) { errorMessage.set("Overload resolution failed"); return null; } if (element instanceof PsiMethod && (inferParent || !((PsiMethod)element).hasTypeParameters())) { final boolean varargs = result instanceof MethodCandidateInfo && ((MethodCandidateInfo)result).isVarargs(); return PsiTypesUtil.getTypeByMethod(context, argumentList, result.getElement(), varargs, result.getSubstitutor(), inferParent); } } } } else if (parent instanceof PsiConditionalExpression) { return getTargetTypeFromParent(parent, errorMessage, inferParent); } else if (parent instanceof PsiLambdaExpression) { return getTargetTypeFromParentLambda((PsiLambdaExpression)parent, errorMessage, inferParent); } else if (parent instanceof PsiReturnStatement) { return getTargetTypeFromParentLambda(PsiTreeUtil.getParentOfType(parent, PsiLambdaExpression.class, true, PsiMethod.class), errorMessage, inferParent); } PsiSwitchExpression switchExpression = PsiTreeUtil.getParentOfType(parent, PsiSwitchExpression.class); if (switchExpression != null && PsiUtil.getSwitchResultExpressions(switchExpression).contains(context)) { return getTargetTypeFromParent(switchExpression, errorMessage, inferParent); } return null; }