PsiType (@Nullable GrExpression expression, ExpressionContext context) { if (expression instanceof GrReferenceExpression) { final GroovyResolveResult resolveResult = ((GrReferenceExpression)expression).advancedResolve(); final PsiSubstitutor substitutor = resolveResult.getSubstitutor(); PsiElement resolved = resolveResult.getElement(); if (resolved instanceof PsiVariable) { return substitutor.substitute(context.typeProvider.getVarType((PsiVariable)resolved)); } else if (resolved instanceof PsiMethod) { return getDeclaredType((PsiMethod)resolved, substitutor, context); } } else if (expression instanceof GrMethodCall) { final GrExpression invokedExpression = ((GrMethodCall)expression).getInvokedExpression(); return getDeclaredType(invokedExpression, context); } else if (expression instanceof GrIndexProperty) { final GroovyResolveResult result = advancedResolve((GrIndexProperty)expression); if (result.getElement() instanceof PsiMethod) { return getDeclaredType((PsiMethod)result.getElement(), result.getSubstitutor(), context); } } else if (expression instanceof GrAssignmentExpression) { return getDeclaredType(((GrAssignmentExpression)expression).getRValue(), context); } else if (expression instanceof GrConditionalExpression) { return TypesUtil.getLeastUpperBoundNullable(getDeclaredType(((GrConditionalExpression)expression).getThenBranch(), context), getDeclaredType(((GrConditionalExpression)expression).getElseBranch(), context), expression.getManager()); } else if (expression instanceof GrParenthesizedExpression) { return getDeclaredType(((GrParenthesizedExpression)expression).getOperand(), context); } else if (expression == null) { return null; } return expression.getType(); }