public String toString() { @NonNls StringBuilder buffer = new StringBuilder(); final Set<Map.Entry<PsiTypeParameter, PsiType>> set = mySubstitutionMap.entrySet(); for (Map.Entry<PsiTypeParameter, PsiType> entry : set) { final PsiTypeParameter typeParameter = entry.getKey(); buffer.append(typeParameter.getName()); final PsiElement owner = typeParameter.getOwner(); if (owner instanceof PsiClass) { buffer.append(" of "); buffer.append(((PsiClass) owner).getQualifiedName()); } else if (owner instanceof PsiMethod) { buffer.append(" of "); buffer.append(((PsiMethod) owner).getName()); buffer.append(" in "); buffer.append(((PsiMethod) owner).getContainingClass().getQualifiedName()); } buffer.append(" -> "); if (entry.getValue() != null) { buffer.append(entry.getValue().getCanonicalText()); } else { buffer.append("null"); } buffer.append('\n'); } return buffer.toString(); }
public String calcGenerics(@NotNull PsiElement context, InsertionContext insertionContext) { if (insertionContext.getCompletionChar() == '<') { return ""; } assert context.isValid(); if (myDiamond) { return "<>"; } if (getObject() instanceof PsiClass) { PsiClass psiClass = (PsiClass) getObject(); PsiResolveHelper resolveHelper = JavaPsiFacade.getInstance(psiClass.getProject()).getResolveHelper(); PsiSubstitutor substitutor = getSubstitutor(); StringBuilder builder = new StringBuilder(); for (PsiTypeParameter parameter : psiClass.getTypeParameters()) { PsiType substitute = substitutor.substitute(parameter); if (substitute == null || (PsiUtil.resolveClassInType(substitute) == parameter && resolveHelper.resolveReferencedClass(parameter.getName(), context) != CompletionUtil.getOriginalOrSelf(parameter))) { return ""; } if (builder.length() > 0) { builder.append(", "); } builder.append(substitute.getCanonicalText()); } if (builder.length() > 0) { return "<" + builder + ">"; } } return ""; }
@Nullable private PsiElement resolveElement() { PsiElement element = getParent(); while (element != null && (!(element instanceof PsiClass) || element instanceof PsiTypeParameter)) { if (element instanceof PsiMethod) { final PsiMethod method = (PsiMethod) element; final PsiTypeParameterList list = method.getTypeParameterList(); if (list != null) { final PsiTypeParameter[] parameters = list.getTypeParameters(); for (int i = 0; parameters != null && i < parameters.length; i++) { final PsiTypeParameter parameter = parameters[i]; if (myQualifiedName.equals(parameter.getName())) return parameter; } } } element = element.getParent(); } if (element == null) return null; for (PsiTypeParameter parameter : PsiUtil.typeParametersIterable((PsiTypeParameterListOwner) element)) { if (myQualifiedName.equals(parameter.getName())) return parameter; } return resolveClassPreferringMyJar(); }
private JavaResolveResult advancedResolveImpl() { final PsiElement resolve = resolveElement(); if (resolve instanceof PsiClass) { final Map<PsiTypeParameter, PsiType> substitutionMap = new HashMap<PsiTypeParameter, PsiType>(); int index = 0; for (PsiTypeParameter parameter : PsiUtil.typeParametersIterable((PsiClass) resolve)) { if (index >= myTypeParameters.length) { final PsiTypeParameterListOwner parameterOwner = parameter.getOwner(); if (parameterOwner == resolve) { substitutionMap.put(parameter, null); } else if (parameterOwner instanceof PsiClass) { PsiElement containingClass = myParent; while ((containingClass = PsiTreeUtil.getParentOfType(containingClass, PsiClass.class, true)) != null) { final PsiSubstitutor superClassSubstitutor = TypeConversionUtil.getClassSubstitutor( (PsiClass) parameterOwner, (PsiClass) containingClass, PsiSubstitutor.EMPTY); if (superClassSubstitutor != null) { substitutionMap.put(parameter, superClassSubstitutor.substitute(parameter)); break; } } } } else { substitutionMap.put(parameter, myTypeParameters[index].getType()); } index++; } return new CandidateInfo(resolve, PsiSubstitutorImpl.createSubstitutor(substitutionMap)); } else { return new CandidateInfo(resolve, PsiSubstitutor.EMPTY); } }
private PsiType rawTypeForTypeParameter(final PsiTypeParameter typeParameter) { final PsiClassType[] extendsTypes = typeParameter.getExtendsListTypes(); if (extendsTypes.length > 0) { // First bound return substitute(extendsTypes[0]); } // Object return PsiType.getJavaLangObject(typeParameter.getManager(), typeParameter.getResolveScope()); }
private static void createTypeParamsListComment( final StringBuilder buffer, final Project project, final CodeDocumentationAwareCommenter commenter, final PsiTypeParameterList typeParameterList) { final PsiTypeParameter[] typeParameters = typeParameterList.getTypeParameters(); for (PsiTypeParameter typeParameter : typeParameters) { buffer.append(CodeDocumentationUtil.createDocCommentLine(PARAM_TAG, project, commenter)); buffer.append("<").append(typeParameter.getName()).append(">"); buffer.append(LINE_SEPARATOR); } }
private static void findTypeParameterExternalUsages( final PsiTypeParameter typeParameter, final Collection<UsageInfo> usages) { PsiTypeParameterListOwner owner = typeParameter.getOwner(); if (owner != null) { final PsiTypeParameterList parameterList = owner.getTypeParameterList(); if (parameterList != null) { final int paramsCount = parameterList.getTypeParameters().length; final int index = parameterList.getTypeParameterIndex(typeParameter); ReferencesSearch.search(owner) .forEach( reference -> { if (reference instanceof PsiJavaCodeReferenceElement) { final PsiReferenceParameterList parameterList1 = ((PsiJavaCodeReferenceElement) reference).getParameterList(); if (parameterList1 != null) { PsiTypeElement[] typeArgs = parameterList1.getTypeParameterElements(); if (typeArgs.length > index) { if (typeArgs.length == 1 && paramsCount > 1 && typeArgs[0].getType() instanceof PsiDiamondType) return true; usages.add( new SafeDeleteReferenceJavaDeleteUsageInfo( typeArgs[index], typeParameter, true)); } } } return true; }); } } }
@Nullable public static PsiType getSubstitutedType(@Nullable PsiParameter parameter) { if (parameter == null) return null; final PsiType type = getType(parameter); if (type instanceof PsiArrayType) { return type; } final PsiClassType.ClassResolveResult result = PsiUtil.resolveGenericsClassInType(type); final PsiClass psiClass = result.getElement(); if (psiClass == null) return type; final Set<PsiTypeParameter> usedTypeParameters = new HashSet<PsiTypeParameter>(); RefactoringUtil.collectTypeParameters(usedTypeParameters, parameter); for (Iterator<PsiTypeParameter> iterator = usedTypeParameters.iterator(); iterator.hasNext(); ) { PsiTypeParameter usedTypeParameter = iterator.next(); if (parameter.getDeclarationScope() != usedTypeParameter.getOwner()) { iterator.remove(); } } PsiSubstitutor subst = PsiSubstitutor.EMPTY; for (PsiTypeParameter usedTypeParameter : usedTypeParameters) { subst = subst.put(usedTypeParameter, TypeConversionUtil.typeParameterErasure(usedTypeParameter)); } PsiSubstitutor substitutor = PsiSubstitutor.EMPTY; final Map<PsiTypeParameter, PsiType> typeMap = result.getSubstitutor().getSubstitutionMap(); for (PsiTypeParameter typeParameter : typeMap.keySet()) { final PsiType psiType = typeMap.get(typeParameter); substitutor = substitutor.put(typeParameter, psiType != null ? subst.substitute(psiType) : null); } if (psiClass instanceof PsiTypeParameter) { return subst.substitute((PsiTypeParameter) psiClass); } else { return JavaPsiFacade.getElementFactory(parameter.getProject()) .createType(psiClass, substitutor); } }
@Override public void visitTypeParameter(PsiTypeParameter parameter) { super.visitTypeParameter(parameter); final String name = parameter.getName(); if (!PsiKeyword.ASSERT.equals(name)) { return; } registerTypeParameterError(parameter); }
protected final void registerTypeParameterError( @NotNull PsiTypeParameter typeParameter, Object... infos) { final PsiElement nameIdentifier = typeParameter.getNameIdentifier(); if (nameIdentifier == null) { registerError(typeParameter, infos); } else { registerError(nameIdentifier, infos); } }
@Override public PsiType substitute(@NotNull PsiTypeParameter typeParameter) { if (containsInMap(typeParameter)) { return getFromMap(typeParameter); } return JavaPsiFacade.getInstance(typeParameter.getProject()) .getElementFactory() .createType(typeParameter); }
public static int getTypeParameterIndex( @NotNull PsiTypeParameter typeParameter, @NotNull PsiTypeParameterList typeParameterList) { PsiTypeParameter[] typeParameters = typeParameterList.getTypeParameters(); for (int i = 0; i < typeParameters.length; i++) { if (typeParameter.equals(typeParameters[i])) return i; } LOG.assertTrue(false); return -1; }
private void buildDelegate() { final PsiManager manager = sourceClass.getManager(); final PsiElementFactory factory = JavaPsiFacade.getInstance(manager.getProject()).getElementFactory(); final CodeStyleManager codeStyleManager = CodeStyleManager.getInstance(manager.getProject()); @NonNls final StringBuilder fieldBuffer = new StringBuilder(); final String delegateVisibility = calculateDelegateVisibility(); if (delegateVisibility.length() > 0) fieldBuffer.append(delegateVisibility).append(' '); fieldBuffer.append("final "); final String fullyQualifiedName = getQualifiedName(); fieldBuffer.append(fullyQualifiedName); if (!typeParams.isEmpty()) { fieldBuffer.append('<'); for (PsiTypeParameter typeParameter : typeParams) { fieldBuffer.append(typeParameter.getName()); } fieldBuffer.append('>'); } fieldBuffer.append(' '); fieldBuffer.append(delegateFieldName); fieldBuffer.append(" = new ").append(fullyQualifiedName); if (!typeParams.isEmpty()) { fieldBuffer.append('<'); for (PsiTypeParameter typeParameter : typeParams) { fieldBuffer.append(typeParameter.getName()); } fieldBuffer.append('>'); } fieldBuffer.append('('); if (requiresBackpointer) { fieldBuffer.append("this"); } fieldBuffer.append(");"); try { final String fieldString = fieldBuffer.toString(); final PsiField field = factory.createFieldFromText(fieldString, sourceClass); final PsiElement newField = sourceClass.add(field); codeStyleManager.reformat( JavaCodeStyleManager.getInstance(myProject).shortenClassReferences(newField)); } catch (IncorrectOperationException e) { logger.error(e); } }
private PsiType addBounds(PsiType substituted, final PsiTypeParameter typeParameter) { PsiElement captureContext = null; if (substituted instanceof PsiCapturedWildcardType) { final PsiCapturedWildcardType captured = (PsiCapturedWildcardType) substituted; substituted = captured.getWildcard(); captureContext = captured.getContext(); } if (substituted instanceof PsiWildcardType && !((PsiWildcardType) substituted).isSuper()) { PsiType originalBound = ((PsiWildcardType) substituted).getBound(); PsiManager manager = typeParameter.getManager(); final PsiType[] boundTypes = typeParameter.getExtendsListTypes(); for (PsiType boundType : boundTypes) { PsiType substitutedBoundType = boundType.accept(mySimpleSubstitutionVisitor); PsiWildcardType wildcardType = (PsiWildcardType) substituted; if (substitutedBoundType != null && !(substitutedBoundType instanceof PsiWildcardType) && !substitutedBoundType.equalsToText("java.lang.Object")) { if (originalBound == null || (!TypeConversionUtil.erasure(substitutedBoundType) .isAssignableFrom(TypeConversionUtil.erasure(originalBound)) && !TypeConversionUtil.erasure(substitutedBoundType) .isAssignableFrom( originalBound))) { // erasure is essential to avoid infinite recursion if (wildcardType.isExtends()) { final PsiType glb = GenericsUtil.getGreatestLowerBound(wildcardType.getBound(), substitutedBoundType); if (glb != null) { substituted = PsiWildcardType.createExtends(manager, glb); } } else { // unbounded substituted = PsiWildcardType.createExtends(manager, substitutedBoundType); } } } } } if (captureContext != null) { LOG.assertTrue(substituted instanceof PsiWildcardType); substituted = PsiCapturedWildcardType.create((PsiWildcardType) substituted, captureContext); } return substituted; }
@NotNull private static PsiSubstitutor calculateMethodSubstitutor( @NotNull PsiTypeParameter[] typeParameters, @NotNull PsiMethod method, @NotNull PsiSubstitutor siteSubstitutor, @NotNull PsiType[] types1, @NotNull PsiType[] types2, @NotNull LanguageLevel languageLevel) { PsiSubstitutor substitutor = PsiResolveHelper.SERVICE .getInstance(method.getProject()) .inferTypeArguments(typeParameters, types1, types2, languageLevel); for (PsiTypeParameter typeParameter : PsiUtil.typeParametersIterable(method)) { ProgressManager.checkCanceled(); LOG.assertTrue(typeParameter != null); if (!substitutor.getSubstitutionMap().containsKey(typeParameter)) { PsiType type = siteSubstitutor.substitute(typeParameter); if (type instanceof PsiClassType && typeParameter.getOwner() == method) { final PsiClass aClass = ((PsiClassType) type).resolve(); if (aClass instanceof PsiTypeParameter && ((PsiTypeParameter) aClass).getOwner() == method) { type = TypeConversionUtil.erasure(type, siteSubstitutor); } } substitutor = substitutor.put(typeParameter, type); } else { final PsiType type = substitutor.substitute(typeParameter); if (type instanceof PsiClassType) { final PsiClass aClass = ((PsiClassType) type).resolve(); if (aClass instanceof PsiTypeParameter) { substitutor = substitutor.put( typeParameter, JavaPsiFacade.getElementFactory(aClass.getProject()) .createType(aClass, siteSubstitutor)); } } } } return substitutor; }
@Nullable private static PsiSubstitutor getSuperMethodSignatureSubstitutorImpl( @NotNull MethodSignature methodSignature, @NotNull MethodSignature superSignature) { // normalize generic method declarations: correlate type parameters // todo: correlate type params by name? PsiTypeParameter[] methodTypeParameters = methodSignature.getTypeParameters(); PsiTypeParameter[] superTypeParameters = superSignature.getTypeParameters(); // both methods are parameterized and number of parameters mismatch if (methodTypeParameters.length != superTypeParameters.length) return null; PsiSubstitutor result = superSignature.getSubstitutor(); for (int i = 0; i < methodTypeParameters.length; i++) { PsiTypeParameter methodTypeParameter = methodTypeParameters[i]; PsiElementFactory factory = JavaPsiFacade.getInstance(methodTypeParameter.getProject()).getElementFactory(); result = result.put(superTypeParameters[i], factory.createType(methodTypeParameter)); } return result; }
public static boolean isClassEquivalentTo(@NotNull PsiClass aClass, PsiElement another) { if (aClass == another) return true; if (!(another instanceof PsiClass)) return false; String name1 = aClass.getName(); if (name1 == null) return false; if (!another.isValid()) return false; String name2 = ((PsiClass) another).getName(); if (name2 == null) return false; if (name1.hashCode() != name2.hashCode()) return false; if (!name1.equals(name2)) return false; String qName1 = aClass.getQualifiedName(); String qName2 = ((PsiClass) another).getQualifiedName(); if (qName1 == null || qName2 == null) { //noinspection StringEquality if (qName1 != qName2) return false; if (aClass instanceof PsiTypeParameter && another instanceof PsiTypeParameter) { PsiTypeParameter p1 = (PsiTypeParameter) aClass; PsiTypeParameter p2 = (PsiTypeParameter) another; return p1.getIndex() == p2.getIndex() && aClass.getManager().areElementsEquivalent(p1.getOwner(), p2.getOwner()); } else { return false; } } if (qName1.hashCode() != qName2.hashCode() || !qName1.equals(qName2)) { return false; } if (originalElement(aClass).equals(originalElement((PsiClass) another))) { return true; } final PsiFile file1 = aClass.getContainingFile().getOriginalFile(); final PsiFile file2 = another.getContainingFile().getOriginalFile(); // see com.intellij.openapi.vcs.changes.PsiChangeTracker // see com.intellij.psi.impl.PsiFileFactoryImpl#createFileFromText(CharSequence,PsiFile) final PsiFile original1 = file1.getUserData(PsiFileFactory.ORIGINAL_FILE); final PsiFile original2 = file2.getUserData(PsiFileFactory.ORIGINAL_FILE); if (original1 == original2 && original1 != null || original1 == file2 || original2 == file1 || file1 == file2) { return compareClassSeqNumber(aClass, (PsiClass) another); } final FileIndexFacade fileIndex = ServiceManager.getService(file1.getProject(), FileIndexFacade.class); final VirtualFile vfile1 = file1.getViewProvider().getVirtualFile(); final VirtualFile vfile2 = file2.getViewProvider().getVirtualFile(); boolean lib1 = fileIndex.isInLibraryClasses(vfile1); boolean lib2 = fileIndex.isInLibraryClasses(vfile2); return (fileIndex.isInSource(vfile1) || lib1) && (fileIndex.isInSource(vfile2) || lib2); }
@NotNull public static PsiClass[] getInterfaces(@NotNull PsiTypeParameter typeParameter) { final PsiClassType[] referencedTypes = typeParameter.getExtendsListTypes(); if (referencedTypes.length == 0) { return PsiClass.EMPTY_ARRAY; } final List<PsiClass> result = new ArrayList<PsiClass>(referencedTypes.length); for (PsiClassType referencedType : referencedTypes) { final PsiClass psiClass = referencedType.resolve(); if (psiClass != null && psiClass.isInterface()) { result.add(psiClass); } } return result.toArray(new PsiClass[result.size()]); }
public SNode convertTypeParameter(PsiTypeParameter x) { SNode typeVar = SConceptOperations.createNewNode( "jetbrains.mps.baseLanguage.structure.TypeVariableDeclaration", null); SPropertyOperations.set(typeVar, "name", x.getName()); if (x.getExtendsListTypes().length > 0) { Iterable<PsiClassType> extend = Sequence.fromArray(x.getExtendsListTypes()); SLinkOperations.setTarget( typeVar, "bound", resolveClass(Sequence.fromIterable(extend).first()), true); ListSequence.fromList(SLinkOperations.getTargets(typeVar, "auxBounds", true)) .addSequence( Sequence.fromIterable(extend) .skip(1) .select( new ISelector<PsiClassType, SNode>() { public SNode select(PsiClassType it) { return resolveClass(it); } })); } return typeVar; }
/** * @param methodSignature method signature * @param superMethodSignature super method signature * @return null if signatures do not match */ @Nullable public static PsiSubstitutor getSuperMethodSignatureSubstitutor( @NotNull MethodSignature methodSignature, @NotNull MethodSignature superMethodSignature) { PsiSubstitutor result = getSuperMethodSignatureSubstitutorImpl(methodSignature, superMethodSignature); if (result == null) return null; PsiTypeParameter[] methodTypeParameters = methodSignature.getTypeParameters(); PsiTypeParameter[] superTypeParameters = superMethodSignature.getTypeParameters(); PsiSubstitutor methodSubstitutor = methodSignature.getSubstitutor(); // check bounds for (int i = 0; i < methodTypeParameters.length; i++) { PsiTypeParameter methodTypeParameter = methodTypeParameters[i]; PsiTypeParameter superTypeParameter = superTypeParameters[i]; final Set<PsiType> methodSupers = new HashSet<PsiType>(); for (PsiClassType methodSuper : methodTypeParameter.getSuperTypes()) { methodSupers.add(methodSubstitutor.substitute(methodSuper)); } final Set<PsiType> superSupers = new HashSet<PsiType>(); for (PsiClassType superSuper : superTypeParameter.getSuperTypes()) { superSupers.add( methodSubstitutor.substitute( PsiUtil.captureToplevelWildcards( result.substitute(superSuper), methodTypeParameter))); } methodSupers.remove( PsiType.getJavaLangObject( methodTypeParameter.getManager(), methodTypeParameter.getResolveScope())); superSupers.remove( PsiType.getJavaLangObject( superTypeParameter.getManager(), superTypeParameter.getResolveScope())); if (!methodSupers.equals(superSupers)) return null; } return result; }
private void buildText( @NotNull PsiClass aClass, @NotNull PsiSubstitutor substitutor, @NotNull StringBuilder buffer, boolean canonical, boolean internal) { if (aClass instanceof PsiAnonymousClass) { ClassResolveResult baseResolveResult = ((PsiAnonymousClass) aClass).getBaseClassType().resolveGenerics(); PsiClass baseClass = baseResolveResult.getElement(); PsiSubstitutor baseSub = baseResolveResult.getSubstitutor(); if (baseClass != null) { buildText(baseClass, baseSub, buffer, canonical, internal); } return; } if (canonical == internal) { buffer.append(getAnnotationsTextPrefix(internal, false, true)); } PsiClass enclosingClass = null; if (!aClass.hasModifierProperty(PsiModifier.STATIC)) { final PsiElement parent = aClass.getParent(); if (parent instanceof PsiClass && !(parent instanceof PsiAnonymousClass)) { enclosingClass = (PsiClass) parent; } } if (enclosingClass != null) { buildText(enclosingClass, substitutor, buffer, canonical, false); buffer.append('.'); buffer.append(aClass.getName()); } else { final String name; if (!canonical) { name = aClass.getName(); } else { final String qualifiedName = aClass.getQualifiedName(); if (qualifiedName == null) { name = aClass.getName(); } else { name = qualifiedName; } } buffer.append(name); } PsiTypeParameter[] typeParameters = aClass.getTypeParameters(); if (typeParameters.length > 0) { StringBuilder pineBuffer = new StringBuilder(); pineBuffer.append('<'); for (int i = 0; i < typeParameters.length; i++) { PsiTypeParameter typeParameter = typeParameters[i]; assert typeParameter.isValid(); if (i > 0) pineBuffer.append(','); final PsiType substitutionResult = substitutor.substitute(typeParameter); if (substitutionResult == null) { pineBuffer = null; break; } assert substitutionResult.isValid(); if (canonical) { if (internal) { pineBuffer.append(substitutionResult.getInternalCanonicalText()); } else { pineBuffer.append(substitutionResult.getCanonicalText()); } } else { pineBuffer.append(substitutionResult.getPresentableText()); } } if (pineBuffer != null) { buffer.append(pineBuffer); buffer.append('>'); } } }
@Override public int computeHashCode(PsiTypeParameter object) { String name = object.getName(); return name == null ? 0 : name.hashCode(); }
@Override public PsiReference getReference() { final PsiDocComment comment = PsiTreeUtil.getParentOfType(this, PsiDocComment.class); if (comment == null) return null; final PsiDocCommentOwner owner = comment.getOwner(); if (!(owner instanceof PsiMethod) && !(owner instanceof PsiClass)) return null; final ASTNode valueToken = findChildByType(JavaDocTokenType.DOC_TAG_VALUE_TOKEN); if (valueToken == null) return null; final String name = valueToken.getText(); PsiElement reference = null; final PsiElement firstChild = getFirstChild(); if (firstChild instanceof PsiDocToken && ((PsiDocToken) firstChild).getTokenType().equals(JavaDocTokenType.DOC_TAG_VALUE_LT)) { final PsiTypeParameter[] typeParameters = ((PsiTypeParameterListOwner) owner).getTypeParameters(); for (PsiTypeParameter typeParameter : typeParameters) { if (typeParameter.getName().equals(name)) { reference = typeParameter; } } } else if (owner instanceof PsiMethod) { final PsiParameter[] parameters = ((PsiMethod) owner).getParameterList().getParameters(); for (PsiParameter parameter : parameters) { if (parameter.getName().equals(name)) { reference = parameter; } } } final PsiElement resultReference = reference; return new PsiJavaReference() { @Override public PsiElement resolve() { return resultReference; } @Override @NotNull public String getCanonicalText() { return valueToken.getText(); } @Override public PsiElement handleElementRename(String newElementName) { final CharTable charTableByTree = SharedImplUtil.findCharTableByTree(getNode()); LeafElement newElement = Factory.createSingleLeafElement( JavaDocTokenType.DOC_TAG_VALUE_TOKEN, newElementName, charTableByTree, getManager()); replaceChild(valueToken, newElement); return PsiDocParamRef.this; } @Override public PsiElement bindToElement(@NotNull PsiElement element) throws IncorrectOperationException { if (isReferenceTo(element)) return PsiDocParamRef.this; if (!(element instanceof PsiParameter)) { throw new IncorrectOperationException("Unsupported operation"); } return handleElementRename(((PsiParameter) element).getName()); } @Override public boolean isReferenceTo(PsiElement element) { if (!(element instanceof PsiNamedElement)) return false; PsiNamedElement namedElement = (PsiNamedElement) element; if (!getCanonicalText().equals(namedElement.getName())) return false; return getManager().areElementsEquivalent(resolve(), element); } @Override @NotNull public PsiElement[] getVariants() { final PsiElement firstChild = getFirstChild(); Set<String> usedNames = new HashSet<String>(); for (PsiDocTag tag : comment.getTags()) { if (tag.getName().equals("param")) { PsiDocTagValue valueElement = tag.getValueElement(); if (valueElement != null) { usedNames.add(valueElement.getText()); } } } PsiNamedElement[] result = PsiNamedElement.EMPTY_ARRAY; if (firstChild instanceof PsiDocToken && ((PsiDocToken) firstChild) .getTokenType() .equals(JavaDocTokenType.DOC_TAG_VALUE_LT)) { result = ((PsiTypeParameterListOwner) owner).getTypeParameters(); } else if (owner instanceof PsiMethod) { result = ((PsiMethod) owner).getParameterList().getParameters(); } List<PsiElement> filtered = new ArrayList<PsiElement>(); for (PsiNamedElement namedElement : result) { if (!usedNames.contains(namedElement.getName())) { filtered.add(namedElement); } } return filtered.toArray(new PsiElement[filtered.size()]); } @Override public boolean isSoft() { return false; } @Override public TextRange getRangeInElement() { final int startOffsetInParent = valueToken.getPsi().getStartOffsetInParent(); return new TextRange(startOffsetInParent, startOffsetInParent + valueToken.getTextLength()); } @Override public PsiElement getElement() { return PsiDocParamRef.this; } @Override public void processVariants(PsiScopeProcessor processor) { for (final PsiElement element : getVariants()) { if (!processor.execute(element, ResolveState.initial())) { return; } } } @Override @NotNull public JavaResolveResult advancedResolve(boolean incompleteCode) { return resultReference == null ? JavaResolveResult.EMPTY : new CandidateInfo(resultReference, PsiSubstitutor.EMPTY); } @Override @NotNull public JavaResolveResult[] multiResolve(boolean incompleteCode) { return resultReference == null ? JavaResolveResult.EMPTY_ARRAY : new JavaResolveResult[] {new CandidateInfo(resultReference, PsiSubstitutor.EMPTY)}; } }; }
@Override public boolean equals(PsiTypeParameter element1, PsiTypeParameter element2) { return element1.getManager().areElementsEquivalent(element1, element2); }
@SuppressWarnings({"HardCodedStringLiteral"}) private static String generateClassInfo(PsiClass aClass) { StringBuilder buffer = new StringBuilder(); GroovyFile file = (GroovyFile) aClass.getContainingFile(); String packageName = file.getPackageName(); if (packageName.length() > 0) { buffer.append(packageName).append("\n"); } final String classString = aClass.isInterface() ? "interface" : aClass instanceof PsiTypeParameter ? "type parameter" : aClass.isEnum() ? "enum" : "class"; buffer.append(classString).append(" ").append(aClass.getName()); if (aClass.hasTypeParameters()) { PsiTypeParameter[] typeParameters = aClass.getTypeParameters(); buffer.append("<"); for (int i = 0; i < typeParameters.length; i++) { if (i > 0) buffer.append(", "); PsiTypeParameter tp = typeParameters[i]; buffer.append(tp.getName()); PsiClassType[] refs = tp.getExtendsListTypes(); if (refs.length > 0) { buffer.append(" extends "); for (int j = 0; j < refs.length; j++) { if (j > 0) buffer.append(" & "); appendTypeString(buffer, refs[j], aClass); } } } buffer.append(">"); } PsiClassType[] refs = aClass.getExtendsListTypes(); if (refs.length > 0 || !aClass.isInterface() && !CommonClassNames.JAVA_LANG_OBJECT.equals(aClass.getQualifiedName())) { buffer.append(" extends "); if (refs.length == 0) { buffer.append("Object"); } else { for (int i = 0; i < refs.length; i++) { if (i > 0) buffer.append(", "); appendTypeString(buffer, refs[i], aClass); } } } refs = aClass.getImplementsListTypes(); if (refs.length > 0) { buffer.append("\nimplements "); for (int i = 0; i < refs.length; i++) { if (i > 0) buffer.append(", "); appendTypeString(buffer, refs[i], aClass); } } return buffer.toString(); }