@Nullable public static LookupElementBuilder createPropertyLookupElement( @NotNull PsiMethod accessor, @Nullable GroovyResolveResult resolveResult, @Nullable PrefixMatcher matcher) { String propName; PsiType propType; final boolean getter = GroovyPropertyUtils.isSimplePropertyGetter(accessor, null); if (getter) { propName = GroovyPropertyUtils.getPropertyNameByGetter(accessor); } else if (GroovyPropertyUtils.isSimplePropertySetter(accessor, null)) { propName = GroovyPropertyUtils.getPropertyNameBySetter(accessor); } else { return null; } assert propName != null; if (!PsiUtil.isValidReferenceName(propName)) { propName = "'" + propName + "'"; } if (matcher != null && !matcher.prefixMatches(propName)) { return null; } if (getter) { propType = PsiUtil.getSmartReturnType(accessor); } else { propType = accessor.getParameterList().getParameters()[0].getType(); } final PsiType substituted = resolveResult != null ? resolveResult.getSubstitutor().substitute(propType) : propType; LookupElementBuilder builder = LookupElementBuilder.create( generatePropertyResolveResult(propName, accessor, propType, resolveResult), propName) .withIcon(JetgroovyIcons.Groovy.Property); if (substituted != null) { builder = builder.withTypeText(substituted.getPresentableText()); } return builder; }
@Nullable private PsiType getNominalTypeInner(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); } } if (getParent() instanceof GrReferenceExpression || PsiUtil.isSuperReference(this)) { 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( GrReferenceResolveUtil.getQualifierType(this), getProject(), getResolveScope()); } return PsiUtil.getSmartReturnType(method); } if (resolved instanceof GrReferenceExpression) { PsiElement parent = resolved.getParent(); if (parent instanceof GrAssignmentExpression) { GrAssignmentExpression assignment = (GrAssignmentExpression) parent; if (resolved.equals(assignment.getLValue())) { GrExpression rValue = assignment.getRValue(); if (rValue != null) { PsiType rType = rValue.getType(); if (rType != null) { return rType; } } } } } 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; }
@Override @Nullable public String getQuickNavigateInfo(PsiElement element, PsiElement originalElement) { if (element instanceof GrVariable || element instanceof GrImplicitVariable) { StringBuilder buffer = new StringBuilder(); PsiVariable variable = (PsiVariable) element; if (originalElement instanceof GrVariableDeclaration && ((GrVariableDeclaration) originalElement).getVariables().length > 1) { for (GrVariable var : ((GrVariableDeclaration) originalElement).getVariables()) { generateVariableInfo(originalElement, buffer, var); buffer.append("\n\n"); } } else { generateVariableInfo(originalElement, buffer, variable); } return buffer.toString(); } else if (element instanceof PsiMethod) { StringBuilder buffer = new StringBuilder(); PsiMethod method = (PsiMethod) element; if (method instanceof GrGdkMethod) { buffer.append("[GDK] "); } else { PsiClass hisClass = method.getContainingClass(); if (hisClass != null) { String qName = hisClass.getQualifiedName(); if (qName != null) { buffer.append(qName).append("\n"); } } } PsiSubstitutor substitutor = calcSubstitutor(originalElement); if (!method.isConstructor()) { final PsiType substituted = substitutor.substitute(PsiUtil.getSmartReturnType(method)); PsiImplUtil.appendTypeString(buffer, substituted, originalElement); buffer.append(" "); } buffer.append(method.getName()).append(" "); buffer.append("("); PsiParameter[] parameters = method.getParameterList().getParameters(); for (int i = 0; i < parameters.length; i++) { PsiParameter parameter = parameters[i]; if (i > 0) buffer.append(", "); if (parameter instanceof GrParameter) { GroovyPresentationUtil.appendParameterPresentation( (GrParameter) parameter, substitutor, TypePresentation.LINK, buffer); } else { PsiType type = parameter.getType(); PsiImplUtil.appendTypeString(buffer, substitutor.substitute(type), originalElement); buffer.append(" "); buffer.append(parameter.getName()); } } buffer.append(")"); final PsiClassType[] referencedTypes = method.getThrowsList().getReferencedTypes(); if (referencedTypes.length > 0) { buffer.append("\nthrows "); for (PsiClassType referencedType : referencedTypes) { PsiImplUtil.appendTypeString(buffer, referencedType, originalElement); buffer.append(", "); } buffer.delete(buffer.length() - 2, buffer.length()); } return buffer.toString(); } else if (element instanceof GrTypeDefinition) { return generateClassInfo((GrTypeDefinition) element); } return null; }
@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; }