@Nullable public PsiType fun(GrReferenceExpressionImpl refExpr) { PsiType result = GrReassignedLocalVarsChecker.checkReassignedVar(refExpr, true); if (result != null) return result; if (GrUnresolvedAccessInspection.isClassReference(refExpr)) { GrExpression qualifier = refExpr.getQualifier(); LOG.assertTrue(qualifier != null); return TypesUtil.createJavaLangClassType( qualifier.getType(), refExpr.getProject(), refExpr.getResolveScope()); } final PsiElement resolved = refExpr.resolve(); final PsiType inferred = getInferredTypes(refExpr, resolved); final PsiType nominal = refExpr.getNominalType(); if (inferred == null || PsiType.NULL.equals(inferred)) { if (nominal == null) { // inside nested closure we could still try to infer from variable initializer. Not sound, // but makes sense if (resolved instanceof GrVariable) { LOG.assertTrue(resolved.isValid()); return ((GrVariable) resolved).getTypeGroovy(); } } return nominal; } if (nominal == null) return inferred; if (!TypeConversionUtil.isAssignable(TypeConversionUtil.erasure(nominal), inferred, false)) { if (resolved instanceof GrVariable && ((GrVariable) resolved).getTypeElementGroovy() != null) { return nominal; } } return inferred; }
private static void assertAllAreValid(GroovyResolveResult[] candidates) { for (GroovyResolveResult candidate : candidates) { final PsiElement element = candidate.getElement(); LOG.assertTrue(element == null || element.isValid()); } }