@Nullable private static PsiType getTypeFromClassRef(@NotNull GrReferenceExpressionImpl ref) { if ("class".equals(ref.getReferenceName())) { return TypesUtil.createJavaLangClassType( PsiImplUtil.getQualifierType(ref), ref.getProject(), ref.getResolveScope()); } return null; }
private static PsiType doFun(GrReferenceExpression refExpr) { if (ResolveUtil.isClassReference(refExpr)) { GrExpression qualifier = refExpr.getQualifier(); LOG.assertTrue(qualifier != null); return TypesUtil.createJavaLangClassType( qualifier.getType(), refExpr.getProject(), refExpr.getResolveScope()); } if (PsiUtil.isCompileStatic(refExpr)) { final GroovyResolveResult resolveResult = refExpr.advancedResolve(); final PsiElement resolvedF = resolveResult.getElement(); final PsiType type; if (resolvedF instanceof GrField) { type = ((GrField) resolvedF).getType(); } else if (resolvedF instanceof GrAccessorMethod) { type = ((GrAccessorMethod) resolvedF).getProperty().getType(); } else { type = null; } if (type != null) { return resolveResult.getSubstitutor().substitute(type); } } final PsiElement resolved = refExpr.resolve(); final PsiType nominal = refExpr.getNominalType(); Boolean reassigned = GrReassignedLocalVarsChecker.isReassignedVar(refExpr); if (reassigned != null && reassigned.booleanValue()) { return GrReassignedLocalVarsChecker.getReassignedVarType(refExpr, true); } final PsiType inferred = getInferredTypes(refExpr, resolved); if (inferred == null) { 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; }
@Nullable private PsiType getNominalTypeInner(@Nullable PsiElement resolved) { if (resolved == null && !"class".equals(getReferenceName())) { resolved = resolve(); } if (resolved instanceof PsiClass) { final PsiElementFactory factory = JavaPsiFacade.getInstance(getProject()).getElementFactory(); if (PsiUtil.isInstanceThisRef(this)) { final PsiClassType categoryType = GdkMethodUtil.getCategoryType((PsiClass) resolved); if (categoryType != null) { return categoryType; } else { return factory.createType((PsiClass) resolved); } } else if (PsiUtil.isSuperReference(this)) { PsiClass contextClass = PsiUtil.getContextClass(this); if (GrTraitUtil.isTrait(contextClass)) { PsiClassType[] extendsTypes = contextClass.getExtendsListTypes(); PsiClassType[] implementsTypes = contextClass.getImplementsListTypes(); PsiClassType[] superTypes = ArrayUtil.mergeArrays(implementsTypes, extendsTypes, PsiClassType.ARRAY_FACTORY); return PsiIntersectionType.createIntersection(ArrayUtil.reverseArray(superTypes)); } return factory.createType((PsiClass) resolved); } if (getParent() instanceof GrReferenceExpression) { return factory.createType((PsiClass) resolved); } else { return TypesUtil.createJavaLangClassType( factory.createType((PsiClass) resolved), getProject(), getResolveScope()); } } if (resolved instanceof GrVariable) { return ((GrVariable) resolved).getDeclaredType(); } if (resolved instanceof PsiVariable) { return ((PsiVariable) resolved).getType(); } if (resolved instanceof PsiMethod) { PsiMethod method = (PsiMethod) resolved; if (PropertyUtil.isSimplePropertySetter(method) && !method.getName().equals(getReferenceName())) { return method.getParameterList().getParameters()[0].getType(); } // 'class' property with explicit generic PsiClass containingClass = method.getContainingClass(); if (containingClass != null && CommonClassNames.JAVA_LANG_OBJECT.equals(containingClass.getQualifiedName()) && "getClass".equals(method.getName())) { return TypesUtil.createJavaLangClassType( PsiImplUtil.getQualifierType(this), getProject(), getResolveScope()); } return PsiUtil.getSmartReturnType(method); } if (resolved == null) { final PsiType fromClassRef = getTypeFromClassRef(this); if (fromClassRef != null) { return fromClassRef; } final PsiType fromMapAccess = getTypeFromMapAccess(this); if (fromMapAccess != null) { return fromMapAccess; } final PsiType fromSpreadOperator = getTypeFromSpreadOperator(this); if (fromSpreadOperator != null) { return fromSpreadOperator; } } return null; }