mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-01-04 17:20:55 +07:00
feat(javadoc): early markdown support part 2
GitOrigin-RevId: 74093daa489fda535b3951828d6617519e5d293f
This commit is contained in:
committed by
intellij-monorepo-bot
parent
0ccfb8e55f
commit
6ebdc205ef
@@ -12,10 +12,8 @@ import com.intellij.psi.impl.source.javadoc.PsiDocMethodOrFieldRef;
|
||||
import com.intellij.psi.javadoc.PsiDocComment;
|
||||
import com.intellij.psi.javadoc.PsiDocTagValue;
|
||||
import com.intellij.psi.search.GlobalSearchScope;
|
||||
import com.intellij.psi.util.MethodSignature;
|
||||
import com.intellij.psi.util.MethodSignatureUtil;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
import com.intellij.psi.util.TypeConversionUtil;
|
||||
import com.intellij.psi.templateLanguages.TemplateLanguageUtil;
|
||||
import com.intellij.psi.util.*;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
@@ -421,4 +419,19 @@ public final class JavaDocUtil {
|
||||
public static boolean isInsidePackageInfo(@Nullable PsiDocComment containingComment) {
|
||||
return containingComment != null && containingComment.getOwner() == null && containingComment.getParent() instanceof PsiJavaFile;
|
||||
}
|
||||
|
||||
public static boolean isDanglingDocComment(@NotNull PsiDocComment comment, boolean ignoreCopyright) {
|
||||
if (comment.getOwner() != null || TemplateLanguageUtil.isInsideTemplateFile(comment)) {
|
||||
return false;
|
||||
}
|
||||
if (isInsidePackageInfo(comment) &&
|
||||
PsiTreeUtil.skipWhitespacesAndCommentsForward(comment) instanceof PsiPackageStatement &&
|
||||
"package-info.java".equals(comment.getContainingFile().getName())) {
|
||||
return false;
|
||||
}
|
||||
if (ignoreCopyright && comment.getPrevSibling() == null && comment.getParent() instanceof PsiFile) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,14 +2,17 @@
|
||||
package com.intellij.psi.impl.source.javadoc;
|
||||
|
||||
import com.intellij.lang.ASTNode;
|
||||
import com.intellij.lang.Language;
|
||||
import com.intellij.psi.JavaDocTokenType;
|
||||
import com.intellij.psi.JavaElementVisitor;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiElementVisitor;
|
||||
import com.intellij.psi.impl.source.tree.CompositePsiElement;
|
||||
import com.intellij.psi.impl.source.tree.JavaDocElementType;
|
||||
import com.intellij.psi.javadoc.PsiMarkdownCodeBlock;
|
||||
import com.intellij.psi.tree.IElementType;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public class PsiMarkdownCodeBlockImpl extends CompositePsiElement implements PsiMarkdownCodeBlock {
|
||||
public PsiMarkdownCodeBlockImpl() {
|
||||
@@ -18,7 +21,7 @@ public class PsiMarkdownCodeBlockImpl extends CompositePsiElement implements Psi
|
||||
|
||||
@Override
|
||||
public void accept(@NotNull PsiElementVisitor visitor) {
|
||||
if(visitor instanceof JavaElementVisitor){
|
||||
if (visitor instanceof JavaElementVisitor) {
|
||||
((JavaElementVisitor)visitor).visitMarkdownCodeBlock(this);
|
||||
return;
|
||||
}
|
||||
@@ -30,15 +33,43 @@ public class PsiMarkdownCodeBlockImpl extends CompositePsiElement implements Psi
|
||||
return "PsiMarkdownCodeBlock:";
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable Language getCodeLanguage() {
|
||||
String languageInfo = getLanguageInfo();
|
||||
if (languageInfo == null) return getLanguage();
|
||||
return Language.findLanguageByID(languageInfo);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull String getCodeText() {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
for (ASTNode child = getFirstChildNode(); child != null; child = child.getTreeNext()) {
|
||||
|
||||
ASTNode child = getFirstChildNode().getTreeNext();
|
||||
if (hasLanguageInfo() && child != null) {
|
||||
child = child.getTreeNext();
|
||||
}
|
||||
|
||||
while (child != null) {
|
||||
IElementType i = child.getElementType();
|
||||
if (i != JavaDocTokenType.DOC_CODE_FENCE && i != JavaDocTokenType.DOC_COMMENT_LEADING_ASTERISKS) {
|
||||
builder.append(child.getText());
|
||||
}
|
||||
child = child.getTreeNext();
|
||||
}
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
private @Nullable String getLanguageInfo() {
|
||||
if (!hasLanguageInfo()) return null;
|
||||
return getChildren()[1].getText().trim();
|
||||
}
|
||||
|
||||
/** @return True if the block has language info. It doesn't always translate to a {@link com.intellij.lang.Language} */
|
||||
private boolean hasLanguageInfo() {
|
||||
PsiElement[] children = getChildren();
|
||||
if (children.length < 2) return false;
|
||||
PsiElement languageInfoChild = children[1];
|
||||
if (languageInfoChild.getNode().getElementType() != JavaDocTokenType.DOC_COMMENT_DATA) return false;
|
||||
return !languageInfoChild.getText().trim().isEmpty();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,6 +12,7 @@ import com.intellij.psi.javadoc.PsiSnippetDocTag;
|
||||
import com.intellij.psi.javadoc.PsiSnippetDocTagBody;
|
||||
import com.intellij.psi.javadoc.PsiSnippetDocTagValue;
|
||||
import com.intellij.psi.tree.TokenSet;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import com.intellij.util.text.CharArrayUtil;
|
||||
import org.jetbrains.annotations.Contract;
|
||||
@@ -85,6 +86,7 @@ public class PsiSnippetDocTagImpl extends CompositePsiElement implements PsiSnip
|
||||
|
||||
@Contract(pure = true)
|
||||
public @NotNull List<@NotNull TextRange> getContentRanges() {
|
||||
boolean isMarkdown = PsiUtil.isInMarkdownDocComment(this);
|
||||
final PsiSnippetDocTagValue valueElement = getValueElement();
|
||||
if (valueElement == null) return Collections.emptyList();
|
||||
|
||||
@@ -104,15 +106,15 @@ public class PsiSnippetDocTagImpl extends CompositePsiElement implements PsiSnip
|
||||
final String[] lines = snippetBodyTextRangeRelativeToSnippetTag.substring(getText()).split("\n");
|
||||
if (lines.length == 0) return Collections.singletonList(snippetBodyTextRangeRelativeToSnippetTag);
|
||||
|
||||
return getRanges(snippetBodyTextRangeRelativeToSnippetTag, lines);
|
||||
return getRanges(snippetBodyTextRangeRelativeToSnippetTag, lines, isMarkdown);
|
||||
}
|
||||
|
||||
@Contract(pure = true)
|
||||
private static @NotNull List<@NotNull TextRange> getRanges(@NotNull TextRange snippetBodyTextRangeRelativeToSnippet, String@NotNull [] lines) {
|
||||
final int firstLine = getFirstNonEmptyLine(lines);
|
||||
final int lastLine = getLastNonEmptyLine(lines);
|
||||
private static @NotNull List<@NotNull TextRange> getRanges(@NotNull TextRange snippetBodyTextRangeRelativeToSnippet, String@NotNull [] lines, boolean isMarkdown) {
|
||||
final int firstLine = getFirstNonEmptyLine(lines, isMarkdown);
|
||||
final int lastLine = getLastNonEmptyLine(lines, isMarkdown);
|
||||
|
||||
int totalMinIndent = getIndent(lines, firstLine, lastLine);
|
||||
int totalMinIndent = getIndent(lines, firstLine, lastLine, isMarkdown);
|
||||
|
||||
int startOffset = getStartOffsetOfFirstNonEmptyLine(snippetBodyTextRangeRelativeToSnippet, lines, firstLine);
|
||||
|
||||
@@ -166,16 +168,16 @@ public class PsiSnippetDocTagImpl extends CompositePsiElement implements PsiSnip
|
||||
}
|
||||
|
||||
@Contract(pure = true)
|
||||
private static @Range(from = 0, to = Integer.MAX_VALUE) int getIndent(String@NotNull [] lines, int firstLine, int lastLine) {
|
||||
private static @Range(from = 0, to = Integer.MAX_VALUE) int getIndent(String@NotNull [] lines, int firstLine, int lastLine, boolean isMarkdown) {
|
||||
int minIndent = Integer.MAX_VALUE;
|
||||
for (int i = firstLine; i <= lastLine && i < lines.length; i++) {
|
||||
String line = lines[i];
|
||||
final int indentLength;
|
||||
if (isEmptyOrSpacesWithLeadingAsterisksOnly(line)) {
|
||||
if (isEmptyOrSpacesWithLeadingAsterisksOnly(line, isMarkdown)) {
|
||||
indentLength = line.length();
|
||||
}
|
||||
else {
|
||||
indentLength = calculateIndent(line);
|
||||
indentLength = calculateIndent(line, isMarkdown);
|
||||
}
|
||||
if (minIndent > indentLength) minIndent = indentLength;
|
||||
}
|
||||
@@ -184,33 +186,33 @@ public class PsiSnippetDocTagImpl extends CompositePsiElement implements PsiSnip
|
||||
}
|
||||
|
||||
@Contract(pure = true)
|
||||
private static @Range(from = 0, to = Integer.MAX_VALUE) int getLastNonEmptyLine(String@NotNull[] lines) {
|
||||
private static @Range(from = 0, to = Integer.MAX_VALUE) int getLastNonEmptyLine(String@NotNull[] lines, boolean isMarkdown) {
|
||||
int lastLine = lines.length - 1;
|
||||
while (lastLine > 0 && isEmptyOrSpacesWithLeadingAsterisksOnly(lines[lastLine])) {
|
||||
while (lastLine > 0 && isEmptyOrSpacesWithLeadingAsterisksOnly(lines[lastLine], isMarkdown)) {
|
||||
lastLine --;
|
||||
}
|
||||
return lastLine;
|
||||
}
|
||||
|
||||
@Contract(pure = true)
|
||||
private static @Range(from = 0, to = Integer.MAX_VALUE) int getFirstNonEmptyLine(String@NotNull[] lines) {
|
||||
private static @Range(from = 0, to = Integer.MAX_VALUE) int getFirstNonEmptyLine(String@NotNull[] lines, boolean isMarkdown) {
|
||||
int firstLine = 0;
|
||||
while (firstLine < lines.length && isEmptyOrSpacesWithLeadingAsterisksOnly(lines[firstLine])) {
|
||||
while (firstLine < lines.length && isEmptyOrSpacesWithLeadingAsterisksOnly(lines[firstLine], isMarkdown)) {
|
||||
firstLine ++;
|
||||
}
|
||||
return firstLine;
|
||||
}
|
||||
|
||||
@Contract(pure = true)
|
||||
private static boolean isEmptyOrSpacesWithLeadingAsterisksOnly(@NotNull String lines) {
|
||||
private static boolean isEmptyOrSpacesWithLeadingAsterisksOnly(@NotNull String lines, boolean isMarkdown) {
|
||||
if (lines.isEmpty()) return true;
|
||||
return lines.matches("^\\s*\\**\\s*$");
|
||||
return lines.matches(isMarkdown ? "^\\s*///\\s*$" : "^\\s*\\**\\s*$");
|
||||
}
|
||||
|
||||
@Contract(pure = true)
|
||||
private static @Range(from = 0, to = Integer.MAX_VALUE) int calculateIndent(@NotNull String content) {
|
||||
private static @Range(from = 0, to = Integer.MAX_VALUE) int calculateIndent(@NotNull String content, boolean isMarkdown) {
|
||||
if (content.isEmpty()) return 0;
|
||||
final String noIndent = content.replaceAll("^\\s*\\*\\s*", "");
|
||||
final String noIndent = content.replaceAll(isMarkdown ? "^\\s*///\\s*" : "^\\s*\\*\\s*", "");
|
||||
return content.length() - noIndent.length();
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user