private void replaceDocComment( @Nullable String newCommentText, @NotNull final PsiDocCommentOwner psiDocCommentOwner) { final PsiDocComment oldComment = psiDocCommentOwner.getDocComment(); if (newCommentText != null) newCommentText = stripSpaces(newCommentText); if (newCommentText == null || oldComment == null || newCommentText.equals(oldComment.getText())) { return; } try { PsiComment newComment = JavaPsiFacade.getInstance(myProject) .getElementFactory() .createCommentFromText(newCommentText, null); final ASTNode oldNode = oldComment.getNode(); final ASTNode newNode = newComment.getNode(); assert oldNode != null && newNode != null; final ASTNode parent = oldNode.getTreeParent(); parent.replaceChild( oldNode, newNode); // important to replace with tree operation to avoid resolve and repository // update } catch (IncorrectOperationException e) { LOG.error(e); } }
@Nullable private ProblemDescriptor[] checkMember( final PsiDocCommentOwner docCommentOwner, final InspectionManager manager, final boolean isOnTheFly) { final ArrayList<ProblemDescriptor> problems = new ArrayList<ProblemDescriptor>(); final PsiDocComment docComment = docCommentOwner.getDocComment(); if (docComment == null) return null; final Set<PsiJavaCodeReferenceElement> references = new HashSet<PsiJavaCodeReferenceElement>(); docComment.accept(getVisitor(references, docCommentOwner, problems, manager, isOnTheFly)); for (PsiJavaCodeReferenceElement reference : references) { final List<PsiClass> classesToImport = new ImportClassFix(reference).getClassesToImport(); final PsiElement referenceNameElement = reference.getReferenceNameElement(); problems.add( manager.createProblemDescriptor( referenceNameElement != null ? referenceNameElement : reference, cannotResolveSymbolMessage("<code>" + reference.getText() + "</code>"), !isOnTheFly || classesToImport.isEmpty() ? null : new AddImportFix(classesToImport), ProblemHighlightType.LIKE_UNKNOWN_SYMBOL, isOnTheFly)); } return problems.isEmpty() ? null : problems.toArray(new ProblemDescriptor[problems.size()]); }
private static PsiDocTag getTextJavaDoc(@NotNull final PsiDocCommentOwner element) { final PsiDocComment docComment = element.getDocComment(); if (docComment != null) { return docComment.findTagByName("testng.test"); } return null; }
private static boolean isConfigMethod(PsiMethod method, String[] configAnnotationsFqn) { for (String fqn : configAnnotationsFqn) { if (AnnotationUtil.isAnnotated(method, fqn, false)) return true; } if (hasDocTagsSupport) { final PsiDocComment comment = method.getDocComment(); if (comment != null) { for (String javadocTag : CONFIG_JAVADOC_TAGS) { if (comment.findTagByName(javadocTag) != null) return true; } } } return false; }
private void fixJavadocForConstructor(PsiClass psiClass) { final PsiDocComment docComment = method.getDocComment(); if (docComment != null) { final List<PsiDocTag> mergedTags = new ArrayList<PsiDocTag>(); final PsiDocTag[] paramTags = docComment.findTagsByName("param"); for (PsiDocTag paramTag : paramTags) { final PsiElement[] dataElements = paramTag.getDataElements(); if (dataElements.length > 0) { if (dataElements[0] instanceof PsiDocParamRef) { final PsiReference reference = dataElements[0].getReference(); if (reference != null) { final PsiElement resolve = reference.resolve(); if (resolve instanceof PsiParameter) { final int parameterIndex = method.getParameterList().getParameterIndex((PsiParameter) resolve); if (ArrayUtil.find(paramsToMerge, parameterIndex) < 0) continue; } } } mergedTags.add((PsiDocTag) paramTag.copy()); } } PsiMethod compatibleParamObjectConstructor = null; if (myExistingClassCompatibleConstructor != null && myExistingClassCompatibleConstructor.getDocComment() == null) { compatibleParamObjectConstructor = myExistingClassCompatibleConstructor; } else if (!myUseExistingClass) { compatibleParamObjectConstructor = psiClass.getConstructors()[0]; } if (compatibleParamObjectConstructor != null) { PsiDocComment psiDocComment = JavaPsiFacade.getElementFactory(myProject).createDocCommentFromText("/**\n*/"); psiDocComment = (PsiDocComment) compatibleParamObjectConstructor.addBefore( psiDocComment, compatibleParamObjectConstructor.getFirstChild()); for (PsiDocTag tag : mergedTags) { psiDocComment.add(tag); } } } }
@Override public void invoke( @NotNull final Project project, final Editor editor, @NotNull final PsiElement element) throws IncorrectOperationException { PsiDocCommentOwner container = getContainer(element); assert container != null; if (!CodeInsightUtilBase.preparePsiElementForWrite(container)) return; if (use15Suppressions(container)) { final PsiModifierList modifierList = container.getModifierList(); if (modifierList != null) { addSuppressAnnotation(project, editor, container, container, getID(container)); } } else { PsiDocComment docComment = container.getDocComment(); PsiManager manager = PsiManager.getInstance(project); if (docComment == null) { String commentText = "/** @" + SuppressionUtil.SUPPRESS_INSPECTIONS_TAG_NAME + " " + getID(container) + "*/"; docComment = JavaPsiFacade.getInstance(manager.getProject()) .getElementFactory() .createDocCommentFromText(commentText); PsiElement firstChild = container.getFirstChild(); container.addBefore(docComment, firstChild); } else { PsiDocTag noInspectionTag = docComment.findTagByName(SuppressionUtil.SUPPRESS_INSPECTIONS_TAG_NAME); if (noInspectionTag != null) { String tagText = noInspectionTag.getText() + ", " + getID(container); noInspectionTag.replace( JavaPsiFacade.getInstance(manager.getProject()) .getElementFactory() .createDocTagFromText(tagText)); } else { String tagText = "@" + SuppressionUtil.SUPPRESS_INSPECTIONS_TAG_NAME + " " + getID(container); docComment.add( JavaPsiFacade.getInstance(manager.getProject()) .getElementFactory() .createDocTagFromText(tagText)); } } } DaemonCodeAnalyzer.getInstance(project).restart(); }
private static AllowedValues parseBeanInfo(@NotNull PsiModifierListOwner owner) { PsiMethod method = null; if (owner instanceof PsiParameter) { PsiParameter parameter = (PsiParameter) owner; PsiElement scope = parameter.getDeclarationScope(); if (!(scope instanceof PsiMethod)) return null; PsiElement nav = scope.getNavigationElement(); if (!(nav instanceof PsiMethod)) return null; method = (PsiMethod) nav; if (method.isConstructor()) { // not a property, try the @ConstructorProperties({"prop"}) PsiAnnotation annotation = AnnotationUtil.findAnnotation(method, "java.beans.ConstructorProperties"); if (annotation == null) return null; PsiAnnotationMemberValue value = annotation.findAttributeValue("value"); if (!(value instanceof PsiArrayInitializerMemberValue)) return null; PsiAnnotationMemberValue[] initializers = ((PsiArrayInitializerMemberValue) value).getInitializers(); PsiElement parent = parameter.getParent(); if (!(parent instanceof PsiParameterList)) return null; int index = ((PsiParameterList) parent).getParameterIndex(parameter); if (index >= initializers.length) return null; PsiAnnotationMemberValue initializer = initializers[index]; if (!(initializer instanceof PsiLiteralExpression)) return null; Object val = ((PsiLiteralExpression) initializer).getValue(); if (!(val instanceof String)) return null; PsiMethod setter = PropertyUtil.findPropertySetter( method.getContainingClass(), (String) val, false, false); if (setter == null) return null; // try the @beaninfo of the corresponding setter method = (PsiMethod) setter.getNavigationElement(); } } else if (owner instanceof PsiMethod) { PsiElement nav = owner.getNavigationElement(); if (!(nav instanceof PsiMethod)) return null; method = (PsiMethod) nav; } if (method == null) return null; PsiClass aClass = method.getContainingClass(); if (aClass == null) return null; if (PropertyUtil.isSimplePropertyGetter(method)) { List<PsiMethod> setters = PropertyUtil.getSetters(aClass, PropertyUtil.getPropertyNameByGetter(method)); if (setters.size() != 1) return null; method = setters.get(0); } if (!PropertyUtil.isSimplePropertySetter(method)) return null; PsiDocComment doc = method.getDocComment(); if (doc == null) return null; PsiDocTag beaninfo = doc.findTagByName("beaninfo"); if (beaninfo == null) return null; String data = StringUtil.join( beaninfo.getDataElements(), new Function<PsiElement, String>() { @Override public String fun(PsiElement element) { return element.getText(); } }, "\n"); int enumIndex = StringUtil.indexOfSubstringEnd(data, "enum:"); if (enumIndex == -1) return null; data = data.substring(enumIndex); int colon = data.indexOf(":"); int last = colon == -1 ? data.length() : data.substring(0, colon).lastIndexOf("\n"); data = data.substring(0, last); List<PsiAnnotationMemberValue> values = new ArrayList<PsiAnnotationMemberValue>(); for (String line : StringUtil.splitByLines(data)) { List<String> words = StringUtil.split(line, " ", true, true); if (words.size() != 2) continue; String ref = words.get(1); PsiExpression constRef = JavaPsiFacade.getElementFactory(aClass.getProject()) .createExpressionFromText(ref, aClass); if (!(constRef instanceof PsiReferenceExpression)) continue; PsiReferenceExpression expr = (PsiReferenceExpression) constRef; values.add(expr); } if (values.isEmpty()) return null; PsiAnnotationMemberValue[] array = values.toArray(new PsiAnnotationMemberValue[values.size()]); return new AllowedValues(array, false); }
@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)}; } }; }
public static boolean isDeprecatedByDocTag(@NotNull PsiDocCommentOwner owner) { PsiDocComment docComment = owner.getDocComment(); return docComment != null && docComment.findTagByName("deprecated") != null; }
public String generateDocumentationContentStub(PsiComment contextComment) { if (!(contextComment instanceof GrDocComment)) { return null; } final GrDocCommentOwner owner = GrDocCommentUtil.findDocOwner((GrDocComment) contextComment); if (owner == null) return null; Project project = contextComment.getProject(); final CodeDocumentationAwareCommenter commenter = (CodeDocumentationAwareCommenter) LanguageCommenters.INSTANCE.forLanguage(owner.getLanguage()); StringBuilder builder = StringBuilderSpinAllocator.alloc(); try { if (owner instanceof GrMethod) { final GrMethod method = (GrMethod) owner; final GrParameter[] parameters = method.getParameters(); final Map<String, String> param2Description = new HashMap<String, String>(); final PsiMethod[] superMethods = method.findSuperMethods(); for (PsiMethod superMethod : superMethods) { final PsiDocComment comment = superMethod.getDocComment(); if (comment != null) { final PsiDocTag[] params = comment.findTagsByName("param"); for (PsiDocTag param : params) { final PsiElement[] dataElements = param.getDataElements(); if (dataElements != null) { String paramName = null; for (PsiElement dataElement : dataElements) { if (dataElement instanceof PsiDocParamRef) { paramName = dataElement.getReference().getCanonicalText(); break; } } if (paramName != null) { param2Description.put(paramName, param.getText()); } } } } } for (PsiParameter parameter : parameters) { String description = param2Description.get(parameter.getName()); if (description != null) { builder.append(CodeDocumentationUtil.createDocCommentLine("", project, commenter)); if (description.indexOf('\n') > -1) description = description.substring(0, description.lastIndexOf('\n')); builder.append(description); } else { builder.append( CodeDocumentationUtil.createDocCommentLine(PARAM_TAG, project, commenter)); builder.append(parameter.getName()); } builder.append(LINE_SEPARATOR); } final PsiType returnType = method.getInferredReturnType(); if ((returnType != null || method.getModifierList().hasModifierProperty(GrModifier.DEF)) && returnType != PsiType.VOID) { builder.append( CodeDocumentationUtil.createDocCommentLine(RETURN_TAG, project, commenter)); builder.append(LINE_SEPARATOR); } final PsiClassType[] references = method.getThrowsList().getReferencedTypes(); for (PsiClassType reference : references) { builder.append( CodeDocumentationUtil.createDocCommentLine(THROWS_TAG, project, commenter)); builder.append(reference.getClassName()); builder.append(LINE_SEPARATOR); } } else if (owner instanceof GrTypeDefinition) { final PsiTypeParameterList typeParameterList = ((PsiClass) owner).getTypeParameterList(); if (typeParameterList != null) { createTypeParamsListComment(builder, project, commenter, typeParameterList); } } return builder.length() > 0 ? builder.toString() : null; } finally { StringBuilderSpinAllocator.dispose(builder); } }