@Override public String checkTagValue(PsiDocTagValue value) { if (value == null) return JavaErrorMessages.message("javadoc.param.tag.parameter.name.expected"); final ASTNode firstChildNode = value.getNode().getFirstChildNode(); if (firstChildNode != null && firstChildNode.getElementType().equals(JavaDocTokenType.DOC_TAG_VALUE_LT)) { if (value.getNode().findChildByType(JavaDocTokenType.DOC_TAG_VALUE_TOKEN) == null) { return JavaErrorMessages.message("javadoc.param.tag.type.parameter.name.expected"); } if (value.getNode().findChildByType(JavaDocTokenType.DOC_TAG_VALUE_GT) == null) { return JavaErrorMessages.message("javadoc.param.tag.type.parameter.gt.expected"); } } return null; }
@Nullable public String[] getSignature() { PsiElement element = getNameElement(); if (element == null) return null; element = element.getNextSibling(); while (element != null && !(element instanceof PsiDocTagValue)) { element = element.getNextSibling(); } if (element == null) return null; List<String> types = new ArrayList<String>(); for (PsiElement child = element.getFirstChild(); child != null; child = child.getNextSibling()) { if (child.getNode().getElementType() == DOC_TYPE_HOLDER) { final String[] typeStrings = child.getText().split("[, ]"); //avoid param types list parsing hmm method(paramType1, paramType2, ...) -> typeElement1, identifier2, ... for (String type : typeStrings) { if (!type.isEmpty()) { types.add(type); } } } } return ArrayUtil.toStringArray(types); }
private static DocTagLocator<PsiDocTag> parameterLocator(final String name) { return new DocTagLocator<PsiDocTag>() { @Override public PsiDocTag find(PsiDocComment comment) { if (comment == null) { return null; } PsiDocTag[] tags = comment.findTagsByName("param"); for (PsiDocTag tag : tags) { PsiDocTagValue value = tag.getValueElement(); if (value != null) { String text = value.getText(); if (text != null && text.equals(name)) { return tag; } } } return null; } }; }
private static DocTagLocator<PsiDocTag> exceptionLocator(final String name) { return new DocTagLocator<PsiDocTag>() { @Override public PsiDocTag find(PsiDocComment comment) { if (comment == null) { return null; } PsiDocTag[] tags = getThrowsTags(comment); for (PsiDocTag tag : tags) { PsiDocTagValue value = tag.getValueElement(); if (value != null) { String text = value.getText(); if (text != null && areWeakEqual(text, name)) { return tag; } } } return null; } }; }
private static String extractTagDescription(PsiDocTag tag) { StringBuilder buf = new StringBuilder(); PsiElement[] children = tag.getChildren(); for (PsiElement child : children) { if (child instanceof PsiDocToken) { PsiDocToken token = (PsiDocToken)child; if (token.getTokenType() == JavaDocTokenType.DOC_COMMENT_DATA) { buf.append(token.getText()); } } else if (child instanceof PsiDocTagValue) { buf.append(child.getText()); } else if (child instanceof PsiInlineDocTag) { buf.append(child.getText()); } } String s = buf.toString(); return s.trim(); }
private static PsiParameter getDocTagParam(PsiElement tag) { if(tag instanceof PsiDocTag && "param".equals(((PsiDocTag) tag).getName())) { PsiDocTagValue value = ((PsiDocTag) tag).getValueElement(); if(value instanceof PsiDocParamRef) { final PsiReference psiReference = value.getReference(); PsiElement target = psiReference != null ? psiReference.resolve() : null; if(target instanceof PsiParameter) { return (PsiParameter) target; } } } return null; }
private static void shortenReferences(final Project project, final Editor editor, InsertionContext context, int offset) { PsiDocumentManager.getInstance(project).commitDocument(editor.getDocument()); final PsiElement element = context.getFile().findElementAt(offset); final PsiDocComment docComment = PsiTreeUtil.getParentOfType(element, PsiDocComment.class); if(!JavaDocUtil.isInsidePackageInfo(docComment)) { final PsiDocTagValue tagValue = PsiTreeUtil.getParentOfType(element, PsiDocTagValue.class); if(tagValue != null) { try { JavaCodeStyleManager.getInstance(project).shortenClassReferences(tagValue); } catch(IncorrectOperationException e) { LOG.error(e); } } PsiDocumentManager.getInstance(context.getProject()).commitAllDocuments(); } }
@Override public void visitDocTagValue(PsiDocTagValue value) { PsiReference reference = value.getReference(); if(reference != null) { PsiElement element = reference.resolve(); final TextAttributesScheme colorsScheme = myHolder.getColorsScheme(); if(element instanceof PsiMethod) { PsiElement nameElement = ((PsiDocMethodOrFieldRef) value).getNameElement(); if(nameElement != null) { myHolder.add(HighlightNamesUtil.highlightMethodName((PsiMethod) element, nameElement, false, colorsScheme)); } } else if(element instanceof PsiParameter) { myHolder.add(HighlightNamesUtil.highlightVariableName((PsiVariable) element, value.getNavigationElement(), colorsScheme)); } } }
private static PsiDocTag getTagByName(@NotNull PsiDocTag[] tags, String name) { for(PsiDocTag tag : tags) { PsiDocTagValue value = tag.getValueElement(); if(value != null) { String text = value.getText(); if(text != null && text.equals(name)) { return tag; } } } return null; }
@Override public String checkTagValue(PsiDocTagValue value) { boolean hasReference = (value != null && value.getFirstChild() != null); if (hasReference) { if (!PsiUtil.isLanguageLevel5OrHigher(value)) { return JavaErrorMessages.message("javadoc.value.tag.jdk15.required"); } } if (value != null) { PsiReference reference = value.getReference(); if (reference != null) { PsiElement target = reference.resolve(); if (target != null) { if (!(target instanceof PsiField)) { return JavaErrorMessages.message("javadoc.value.field.required"); } PsiField field = (PsiField) target; if (!field.hasModifierProperty(PsiModifier.STATIC)) { return JavaErrorMessages.message("javadoc.value.static.field.required"); } if (field.getInitializer() == null || JavaConstantExpressionEvaluator.computeConstantExpression(field.getInitializer(), false) == null) { return JavaErrorMessages.message("javadoc.value.field.with.initializer.required"); } } } } return null; }
@Override public void annotate(@NotNull PsiElement element, @NotNull AnnotationHolder holder) { if (element instanceof PsiDocTag) { String name = ((PsiDocTag)element).getName(); if ("param".equals(name)) { PsiDocTagValue tagValue = ((PsiDocTag)element).getValueElement(); if (tagValue != null) { Annotation annotation = holder.createInfoAnnotation(tagValue, null); annotation.setTextAttributes(JavaHighlightingColors.DOC_COMMENT_TAG_VALUE); } } } }
@Override public void visitDocTagValue(PsiDocTagValue value) { PsiReference reference = value.getReference(); if (reference != null) { PsiElement element = reference.resolve(); final TextAttributesScheme colorsScheme = myHolder.getColorsScheme(); if (element instanceof PsiMethod) { myHolder.add(HighlightNamesUtil.highlightMethodName((PsiMethod)element, ((PsiDocMethodOrFieldRef)value).getNameElement(), false, colorsScheme)); } else if (element instanceof PsiParameter) { myHolder.add(HighlightNamesUtil.highlightVariableName((PsiVariable)element, value.getNavigationElement(), colorsScheme)); } } }
private static String getTextFromNode(final PsiElement node, String text1) { PsiElement nextSibling = node.getNextSibling(); if (nextSibling instanceof PsiDocTagValue) { text1 += nextSibling.getText(); nextSibling = nextSibling.getNextSibling(); if (nextSibling instanceof PsiDocToken && ((PsiDocToken)nextSibling).getTokenType() == JavaDocTokenType.DOC_COMMENT_DATA) { text1 += nextSibling.getText(); } } return text1; }
public DocValuesIterator(PsiElement start) { for(PsiElement e = start; e != null; e = e.getNextSibling()) { if (e instanceof PsiDocTagValue) tokens.add(e); else if (e instanceof PsiDocToken && ((PsiDocToken)e).getTokenType() == tokenType) { tokens.add(e); e = advanceToNext(e); } } }
static PsiElement advanceToNext(PsiElement e) { PsiElement nextSibling = e.getNextSibling(); if (nextSibling instanceof PsiDocTagValue) e = nextSibling; nextSibling = e.getNextSibling(); if (nextSibling instanceof PsiDocToken && ((PsiDocToken)nextSibling).getTokenType() == tokenType ) { e = nextSibling; } return e; }
private static void locateCaret(@NotNull PsiDocComment comment, @NotNull Editor editor, @NotNull PsiFile file) { Document document = editor.getDocument(); int lineToNavigate = -1; for (PsiDocTag tag : comment.getTags()) { PsiElement nameElement = tag.getNameElement(); if (nameElement == null || !CARET_ANCHOR_TAGS.contains(nameElement.getText())) { continue; } boolean good = false; PsiElement[] dataElements = tag.getDataElements(); if (dataElements != null) { PsiDocTagValue valueElement = tag.getValueElement(); for (PsiElement element : dataElements) { if (element == valueElement) { continue; } if (!StringUtil.isEmptyOrSpaces(element.getText())) { good = true; break; } } } if (!good) { int offset = tag.getTextRange().getEndOffset(); CharSequence text = document.getCharsSequence(); int i = CharArrayUtil.shiftBackward(text, offset - 1, " \t*"); if (i > 0 && text.charAt(i) == '\n') { offset = i - 1; } lineToNavigate = document.getLineNumber(offset); break; } } if (lineToNavigate >= 0) { editor.getCaretModel().moveToOffset(document.getLineEndOffset(lineToNavigate)); JavadocNavigationDelegate.navigateToLineEnd(editor, file); } }
@Nullable private static JavadocParameterInfo parse(@NotNull PsiElement element, @NotNull Editor editor) { final PsiDocTag tag = PsiTreeUtil.getParentOfType(element, PsiDocTag.class, false); if (tag == null || !PARAM_TEXT.equals(tag.getName())) { return null; } final PsiDocTagValue paramRef = PsiTreeUtil.getChildOfType(tag, PsiDocTagValue.class); if (paramRef == null) { return null; } for (PsiElement e = paramRef.getNextSibling(); e != null; e = e.getNextSibling()) { final ASTNode node = e.getNode(); if (node == null) { break; } final IElementType elementType = node.getElementType(); if (elementType == JavaDocTokenType.DOC_COMMENT_DATA) { return new JavadocParameterInfo( editor.offsetToLogicalPosition(paramRef.getTextRange().getEndOffset()), editor.offsetToLogicalPosition(e.getTextRange().getStartOffset()), editor.getDocument().getLineNumber(e.getTextRange().getEndOffset()) ); } else if (elementType == JavaDocTokenType.DOC_COMMENT_LEADING_ASTERISKS) { break; } } return new JavadocParameterInfo( editor.offsetToLogicalPosition(paramRef.getTextRange().getEndOffset()), null, editor.getDocument().getLineNumber(paramRef.getTextRange().getEndOffset()) ); }
void migrateMethodCallExpressions(final PsiType migrationType, final PsiParameter param, final PsiClass psiClass) { boolean checkNumberOfArguments = false; if (param.getType() instanceof PsiEllipsisType && !(migrationType instanceof PsiEllipsisType)) { checkNumberOfArguments = true; } final PsiType strippedType = migrationType instanceof PsiEllipsisType ? ((PsiEllipsisType)migrationType).getComponentType() : migrationType; final PsiMethod method = (PsiMethod)param.getDeclarationScope(); final PsiParameterList parameterList = method.getParameterList(); final int parametersCount = parameterList.getParametersCount(); final int index = parameterList.getParameterIndex(param); final List<PsiReference> refs = filterReferences(psiClass, ReferencesSearch.search(method, method.getUseScope().intersectWith(myRules.getSearchScope()), false)); for (PsiReference ref1 : refs) { final PsiElement ref = ref1.getElement(); final PsiElement parent = Util.getEssentialParent(ref); if (parent instanceof PsiCallExpression) { final PsiExpressionList argumentList = ((PsiCallExpression)parent).getArgumentList(); if (argumentList != null) { final PsiExpression[] expressions = argumentList.getExpressions(); if (checkNumberOfArguments && parametersCount != expressions.length) { markFailedConversion(Pair.create(param.getType(), migrationType), (PsiCallExpression)parent); } if (index > -1 && index < expressions.length) { for (int idx = index; idx < (param.isVarArgs() ? expressions.length : index + 1); idx++) { final PsiExpression actual = expressions[idx]; final PsiType type = getTypeEvaluator().evaluateType(actual); if (type != null) { migrateExpressionType(actual, strippedType, parent, TypeConversionUtil.isAssignable(strippedType, type), true); } } } } } else if (ref instanceof PsiDocTagValue) { myConversions.put(ref, method); } } }
public static boolean isApplicable(@NotNull PsiJavaCodeReferenceElement reference) { final PsiElement parent = reference.getParent(); final PsiElement grandParent = parent.getParent(); if (!(grandParent instanceof PsiMethod)) { return false; } final PsiMethod method = (PsiMethod)grandParent; final PsiDocComment docComment = method.getDocComment(); if (docComment == null) { return true; } final PsiElement throwsTarget = reference.resolve(); if (throwsTarget == null) { return true; } final PsiDocTag[] tags = docComment.findTagsByName("throws"); for (PsiDocTag tag : tags) { final PsiDocTagValue valueElement = tag.getValueElement(); if (valueElement == null) { continue; } final PsiElement child = valueElement.getFirstChild(); if (child == null) { continue; } final PsiElement grandChild = child.getFirstChild(); if (!(grandChild instanceof PsiJavaCodeReferenceElement)) { continue; } final PsiJavaCodeReferenceElement referenceElement = (PsiJavaCodeReferenceElement)grandChild; final PsiElement target = referenceElement.resolve(); if (throwsTarget.equals(target)) { return false; } } return true; }
@Nullable private Pair<PsiDocTag, InheritDocProvider<PsiDocTag>> findDocTag(final PsiDocTag[] localTags, final String paramName, final PsiMethod method) { Pair<PsiDocTag, InheritDocProvider<PsiDocTag>> parmTag = null; for (PsiDocTag localTag : localTags) { PsiDocTagValue value = localTag.getValueElement(); if (value != null) { String tagName = value.getText(); if (tagName != null && tagName.equals(paramName)) { parmTag = new Pair<PsiDocTag, InheritDocProvider<PsiDocTag>> (localTag, new InheritDocProvider<PsiDocTag>() { @Override public Pair<PsiDocTag, InheritDocProvider<PsiDocTag>> getInheritDoc() { return findInheritDocTag(method, parameterLocator(paramName)); } @Override public PsiClass getElement() { return method.getContainingClass(); } }); break; } } } if (parmTag == null) { parmTag = findInheritDocTag(method, parameterLocator(paramName)); } return parmTag; }
@Nullable public String[] getSignature() { PsiElement element = getNameElement(); if (element == null) return null; element = element.getNextSibling(); while (element != null && !(element instanceof PsiDocTagValue)) { element = element.getNextSibling(); } if (element == null) return null; List<String> types = new ArrayList<String>(); for (PsiElement child = element.getFirstChild(); child != null; child = child.getNextSibling()) { if (child.getNode().getElementType() == DOC_TYPE_HOLDER) { final String[] typeStrings = child.getText().split("[, ]"); //avoid param types list parsing hmm method(paramType1, paramType2, ...) -> typeElement1, identifier2, ... if (typeStrings != null) { for (String type : typeStrings) { if (type.length() > 0) { types.add(type); } } } } } return ArrayUtil.toStringArray(types); }
@Override public void annotate(@NotNull PsiElement element, @NotNull AnnotationHolder holder) { if (element instanceof PsiDocTag) { String name = ((PsiDocTag)element).getName(); if ("param".equals(name)) { PsiDocTagValue tagValue = ((PsiDocTag)element).getValueElement(); if (tagValue != null) { Annotation annotation = holder.createInfoAnnotation(tagValue, null); annotation.setTextAttributes(CodeInsightColors.DOC_COMMENT_TAG_VALUE); } } } }
void migrateMethodCallExpressions(final PsiType migrationType, final PsiParameter param, final PsiClass psiClass) { boolean checkNumberOfArguments = false; if (param.getType() instanceof PsiEllipsisType && !(migrationType instanceof PsiEllipsisType)) { checkNumberOfArguments = true; } final PsiType strippedType = migrationType instanceof PsiEllipsisType ? ((PsiEllipsisType)migrationType).getComponentType() : migrationType; final PsiMethod method = (PsiMethod)param.getDeclarationScope(); final PsiParameterList parameterList = method.getParameterList(); final int parametersCount = parameterList.getParametersCount(); final int index = parameterList.getParameterIndex(param); final List<PsiReference> refs = filterReferences(psiClass, ReferencesSearch.search(method, method.getUseScope().intersectWith(myRules.getSearchScope()), false)); for (PsiReference ref1 : refs) { final PsiElement ref = ref1.getElement(); final PsiElement parent = Util.getEssentialParent(ref); if (parent instanceof PsiCallExpression) { final PsiExpressionList argumentList = ((PsiCallExpression)parent).getArgumentList(); if (argumentList != null) { final PsiExpression[] expressions = argumentList.getExpressions(); if (checkNumberOfArguments && parametersCount != expressions.length) { markFailedConversion(new Pair<PsiType, PsiType>(param.getType(), migrationType), (PsiCallExpression)parent); } if (index > -1 && index < expressions.length) { for (int idx = index; idx < (param.isVarArgs() ? expressions.length : index + 1); idx++) { final PsiExpression actual = expressions[idx]; final PsiType type = getTypeEvaluator().evaluateType(actual); if (type != null) { migrateExpressionType(actual, strippedType, parent, TypeConversionUtil.isAssignable(strippedType, type), true); } } } } } else if (ref instanceof PsiDocTagValue) { myConversions.put(ref, method); } } }
public static boolean isFound(final PsiDocTag[] tags, final PsiElement param) { for (PsiDocTag tag : tags) { if ("param".equals(tag.getName())) { PsiDocTagValue value = tag.getValueElement(); if (value instanceof PsiDocParamRef) { PsiDocParamRef paramRef = (PsiDocParamRef)value; final PsiReference psiReference = paramRef.getReference(); if (psiReference != null && psiReference.isReferenceTo(param)) { return true; } } } } return false; }
private void processThrowsTags(final PsiDocTag[] tags, final Map<PsiClassType, PsiClass> declaredExceptions, final InspectionManager mananger, @NotNull final ArrayList<ProblemDescriptor> problems, boolean isOnTheFly) { for (PsiDocTag tag : tags) { if ("throws".equals(tag.getName()) || "exception".equals(tag.getName())) { final PsiDocTagValue value = tag.getValueElement(); if (value == null) continue; final PsiElement firstChild = value.getFirstChild(); if (firstChild == null) continue; final PsiElement psiElement = firstChild.getFirstChild(); if (!(psiElement instanceof PsiJavaCodeReferenceElement)) continue; final PsiJavaCodeReferenceElement ref = (PsiJavaCodeReferenceElement)psiElement; final PsiElement element = ref.resolve(); if (element instanceof PsiClass){ final PsiClass exceptionClass = (PsiClass)element; for (Iterator<PsiClassType> it = declaredExceptions.keySet().iterator(); it.hasNext();) { PsiClassType classType = it.next(); final PsiClass psiClass = declaredExceptions.get(classType); if (InheritanceUtil.isInheritorOrSelf(exceptionClass, psiClass, true)) { if (!myIgnoreEmptyDescriptions && extractThrowsTagDescription(tag).length() == 0) { problems.add(createDescriptor(tag.getNameElement(), InspectionsBundle.message("inspection.javadoc.method.problem.missing.tag.description", "<code>" + tag.getName() + "</code>"), mananger, isOnTheFly)); } it.remove(); } } } } } }
private void checkInlineTags(final InspectionManager inspectionManager, final ArrayList<ProblemDescriptor> problems, final PsiElement[] dataElements, final JavadocManager manager, boolean isOnTheFly) { for (PsiElement dataElement : dataElements) { if (dataElement instanceof PsiInlineDocTag) { final PsiInlineDocTag inlineDocTag = (PsiInlineDocTag)dataElement; final PsiElement nameElement = inlineDocTag.getNameElement(); if (manager.getTagInfo(inlineDocTag.getName()) == null) { checkTagInfo(inspectionManager, null, inlineDocTag, isOnTheFly, problems); } if (!IGNORE_POINT_TO_ITSELF) { final PsiDocTagValue value = inlineDocTag.getValueElement(); if (value != null) { final PsiReference reference = value.getReference(); if (reference != null) { final PsiElement ref = reference.resolve(); if (ref != null){ if (PsiTreeUtil.getParentOfType(inlineDocTag, PsiDocCommentOwner.class) == PsiTreeUtil.getParentOfType(ref, PsiDocCommentOwner.class, false)) { if (nameElement != null) { problems.add(createDescriptor(nameElement, InspectionsBundle.message("inspection.javadoc.problem.pointing.to.itself"), inspectionManager, isOnTheFly)); } } } } } } } } }
private static DocTagLocator<PsiDocTag> exceptionLocator(String name) { return new DocTagLocator<PsiDocTag>() { @Override public PsiDocTag find(PsiDocCommentOwner owner, PsiDocComment comment) { if(comment == null) { return null; } for(PsiDocTag tag : getThrowsTags(comment)) { PsiDocTagValue value = tag.getValueElement(); if(value != null) { String text = value.getText(); if(text != null && areWeakEqual(text, name)) { return tag; } } } return null; } }; }
@Override public void visitDocTagValue(PsiDocTagValue value) { mVisitor.report("PsiDocTagValue", value.getText(), value); super.visitElement(value); }