fix(JDoc): Formatting and inspections issues

GitOrigin-RevId: 910e9b3335fa7c3967fb79893ecba7c69595a201
This commit is contained in:
Mathias Boulay
2024-08-14 18:24:38 +00:00
committed by intellij-monorepo-bot
parent 4766dcb03a
commit abd7b1dded
15 changed files with 254 additions and 153 deletions
@@ -2051,6 +2051,7 @@ use.of.clone.reference.problem.descriptor=Use of <code>#ref</code>
dangling.javadoc.display.name=Dangling Javadoc comment
dangling.javadoc.problem.descriptor=Dangling Javadoc comment #loc
dangling.javadoc.convert.quickfix=Replace with block comment
dangling.javadoc.convert.line.comment.quickfix=Replace with line comments
dangling.javadoc.delete.quickfix=Remove dangling comment
dangling.javadoc.ignore.copyright.option=Ignore file header comment in JavaDoc format
equals.replaceable.by.objects.call.display.name='equals()' expression replaceable by 'Objects.equals()' expression
@@ -1,4 +1,4 @@
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.siyeh.ig.javadoc;
import com.intellij.codeInsight.javadoc.JavaDocUtil;
@@ -6,14 +6,14 @@ import com.intellij.codeInspection.LocalQuickFix;
import com.intellij.codeInspection.options.OptPane;
import com.intellij.modcommand.ModPsiUpdater;
import com.intellij.modcommand.PsiUpdateModCommandQuickFix;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.project.Project;
import com.intellij.psi.*;
import com.intellij.openapi.util.TextRange;
import com.intellij.psi.JavaDocTokenType;
import com.intellij.psi.PsiElement;
import com.intellij.psi.javadoc.PsiDocComment;
import com.intellij.psi.javadoc.PsiDocToken;
import com.intellij.psi.templateLanguages.TemplateLanguageUtil;
import com.intellij.psi.tree.IElementType;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.util.PsiUtil;
import com.siyeh.InspectionGadgetsBundle;
import com.siyeh.ig.BaseInspection;
import com.siyeh.ig.BaseInspectionVisitor;
@@ -49,23 +49,34 @@ public final class DanglingJavadocInspection extends BaseInspection {
@Override
protected LocalQuickFix @NotNull [] buildFixes(Object... infos) {
boolean markdownComment = (boolean)infos[0];
return new LocalQuickFix[] {
new DeleteCommentFix(),
new ConvertCommentFix()
new ConvertCommentFix(markdownComment)
};
}
private static class ConvertCommentFix extends PsiUpdateModCommandQuickFix {
private final boolean myMarkdownComment;
ConvertCommentFix(boolean markdownComment) {
myMarkdownComment = markdownComment;
}
@Nls
@NotNull
@Override
public String getFamilyName() {
return InspectionGadgetsBundle.message("dangling.javadoc.convert.quickfix");
return myMarkdownComment
? InspectionGadgetsBundle.message("dangling.javadoc.convert.line.comment.quickfix")
: InspectionGadgetsBundle.message("dangling.javadoc.convert.quickfix");
}
@Override
protected void applyFix(@NotNull Project project, @NotNull PsiElement element, @NotNull ModPsiUpdater updater) {
final PsiElement docComment = element.getParent();
final PsiElement parent = element.getParent();
if (!(parent instanceof PsiDocComment docComment)) return;
boolean markdownComment = docComment.isMarkdownComment();
final StringBuilder newCommentText = new StringBuilder();
for (PsiElement child = docComment.getFirstChild(); child != null; child = child.getNextSibling()) {
if (child instanceof PsiDocToken docToken) {
@@ -76,7 +87,7 @@ public final class DanglingJavadocInspection extends BaseInspection {
else if (!JavaDocTokenType.DOC_COMMENT_LEADING_ASTERISKS.equals(tokenType)) {
newCommentText.append(child.getText());
}
else if (PsiUtil.isInMarkdownDocComment(docToken)) {
else if (markdownComment) {
newCommentText.append("//");
}
}
@@ -84,9 +95,10 @@ public final class DanglingJavadocInspection extends BaseInspection {
newCommentText.append(child.getText());
}
}
final PsiElementFactory factory = JavaPsiFacade.getElementFactory(project);
final PsiComment newComment = factory.createCommentFromText(newCommentText.toString(), element);
docComment.replace(newComment);
Document document = element.getContainingFile().getFileDocument();
TextRange range = docComment.getTextRange();
document.replaceString(range.getStartOffset(), range.getEndOffset(), newCommentText);
}
}
@@ -116,7 +128,7 @@ public final class DanglingJavadocInspection extends BaseInspection {
public void visitDocComment(@NotNull PsiDocComment comment) {
super.visitDocComment(comment);
if (JavaDocUtil.isDanglingDocComment(comment, ignoreCopyright)) {
registerError(comment.getFirstChild());
registerError(comment.getFirstChild(), comment.isMarkdownComment());
}
}
}
@@ -850,40 +850,45 @@ class _JavaDocLexer implements FlexLexer {
case 43: break;
case 4:
{ yybegin(COMMENT_DATA);
if(myMarkdownMode)
if(myMarkdownMode) {
return myTokenTypes.sharp();
}
return myTokenTypes.commentData();
}
// fall through
case 44: break;
case 5:
{ yybegin(COMMENT_DATA);
if(myMarkdownMode)
if(myMarkdownMode) {
return myTokenTypes.leftParenthesis();
}
return myTokenTypes.commentData();
}
// fall through
case 45: break;
case 6:
{ yybegin(COMMENT_DATA);
if(myMarkdownMode)
if(myMarkdownMode) {
return myTokenTypes.rightParenthesis();
}
return myTokenTypes.commentData();
}
// fall through
case 46: break;
case 7:
{ yybegin(COMMENT_DATA);
if(myMarkdownMode)
if(myMarkdownMode) {
return myTokenTypes.leftBracket();
}
return myTokenTypes.commentData();
}
// fall through
case 47: break;
case 8:
{ yybegin(COMMENT_DATA);
if(myMarkdownMode)
if(myMarkdownMode) {
return myTokenTypes.rightBracket();
}
return myTokenTypes.commentData();
}
// fall through
@@ -996,8 +1001,9 @@ class _JavaDocLexer implements FlexLexer {
// fall through
case 66: break;
case 27:
{ if (myMarkdownMode)
{ if (myMarkdownMode) {
return myTokenTypes.commentData();
}
return myTokenTypes.commentLeadingAsterisks();
}
// fall through
@@ -1029,8 +1035,9 @@ class _JavaDocLexer implements FlexLexer {
// fall through
case 71: break;
case 32:
{ if(myMarkdownMode)
{ if(myMarkdownMode) {
return myTokenTypes.commentData();
}
return myTokenTypes.commentEnd();
}
// fall through
@@ -1041,8 +1048,9 @@ class _JavaDocLexer implements FlexLexer {
// fall through
case 73: break;
case 34:
{ if(myMarkdownMode)
{ if(myMarkdownMode) {
return myTokenTypes.badCharacter();
}
yybegin(COMMENT_DATA_START);
return myTokenTypes.commentStart();
}
@@ -1059,15 +1067,17 @@ class _JavaDocLexer implements FlexLexer {
case 75: break;
case 36:
{ yybegin(COMMENT_DATA);
if(myMarkdownMode)
if(myMarkdownMode) {
return myTokenTypes.codeFence();
}
return myTokenTypes.commentData();
}
// fall through
case 76: break;
case 37:
{ if (myMarkdownMode)
{ if (myMarkdownMode) {
return myTokenTypes.commentLeadingAsterisks();
}
return myTokenTypes.commentData();
}
// fall through
@@ -79,8 +79,9 @@ LEADING_TOKEN_MARKDOWN="///"
%%
<YYINITIAL> {START_COMMENT_HTML} {
if(myMarkdownMode)
if(myMarkdownMode) {
return myTokenTypes.badCharacter();
}
yybegin(COMMENT_DATA_START);
return myTokenTypes.commentStart();
}
@@ -123,8 +124,9 @@ LEADING_TOKEN_MARKDOWN="///"
<COMMENT_DATA_START, COMMENT_DATA> {
{CODE_FENCE} {
yybegin(COMMENT_DATA);
if(myMarkdownMode)
if(myMarkdownMode) {
return myTokenTypes.codeFence();
}
return myTokenTypes.commentData();
}
@@ -136,33 +138,38 @@ LEADING_TOKEN_MARKDOWN="///"
"#" {
yybegin(COMMENT_DATA);
if(myMarkdownMode)
if(myMarkdownMode) {
return myTokenTypes.sharp();
}
return myTokenTypes.commentData();
}
\[ {
yybegin(COMMENT_DATA);
if(myMarkdownMode)
if(myMarkdownMode) {
return myTokenTypes.leftBracket();
}
return myTokenTypes.commentData();
}
\] {
yybegin(COMMENT_DATA);
if(myMarkdownMode)
if(myMarkdownMode) {
return myTokenTypes.rightBracket();
}
return myTokenTypes.commentData();
}
\( {
yybegin(COMMENT_DATA);
if(myMarkdownMode)
if(myMarkdownMode) {
return myTokenTypes.leftParenthesis();
}
return myTokenTypes.commentData();
}
\) {
yybegin(COMMENT_DATA);
if(myMarkdownMode)
if(myMarkdownMode) {
return myTokenTypes.rightParenthesis();
}
return myTokenTypes.commentData();
}
}
@@ -209,13 +216,15 @@ SNIPPET_ATTRIBUTE_VALUE_SINGLE_QUOTES, SNIPPET_TAG_COMMENT_DATA_UNTIL_COLON> "}"
: { yybegin(SNIPPET_TAG_BODY_DATA); return myTokenTypes.tagValueColon(); }
{LEADING_TOKEN_HTML} {
if (myMarkdownMode)
if (myMarkdownMode) {
return myTokenTypes.commentData();
}
return myTokenTypes.commentLeadingAsterisks();
}
{LEADING_TOKEN_MARKDOWN} {
if (myMarkdownMode)
if (myMarkdownMode) {
return myTokenTypes.commentLeadingAsterisks();
}
return myTokenTypes.commentData();
}
@@ -250,8 +259,9 @@ SNIPPET_ATTRIBUTE_VALUE_SINGLE_QUOTES, SNIPPET_TAG_COMMENT_DATA_UNTIL_COLON> "}"
<CODE_TAG, CODE_TAG_SPACE> {WHITE_DOC_SPACE_CHAR}+ { yybegin(CODE_TAG); return myTokenTypes.space(); }
"*"+"/" {
if(myMarkdownMode)
if(myMarkdownMode) {
return myTokenTypes.commentData();
}
return myTokenTypes.commentEnd();
}
[^] { return myTokenTypes.badCharacter(); }
@@ -163,116 +163,124 @@ public final class BasicJavaDocParser {
}
}
else if (tokenType == JavaDocTokenType.DOC_CODE_FENCE) {
if (getBraceScope(builder) > 0) {
builder.remapCurrentToken(JavaDocTokenType.DOC_COMMENT_DATA);
builder.advanceLexer();
return;
}
char fenceStart = builder.getOriginalText().charAt(builder.getCurrentOffset());
PsiBuilder.Marker tag = builder.mark();
while (!builder.eof()) {
builder.advanceLexer();
if (getTokenType(builder) == JavaDocTokenType.DOC_CODE_FENCE &&
builder.getOriginalText().charAt(builder.getCurrentOffset()) == fenceStart) {
break;
}
else {
builder.remapCurrentToken(JavaDocTokenType.DOC_COMMENT_DATA);
}
}
if (!builder.eof()) {
builder.advanceLexer();
}
tag.done(javaDocElementTypeContainer.DOC_MARKDOWN_CODE_BLOCK);
parseCodeBlock(builder, javaDocElementTypeContainer);
}
else if (tokenType == JavaDocTokenType.DOC_LBRACKET) {
builder.setDebugMode(true);
boolean hasLabel = true;
PsiBuilder.Marker tag = builder.mark();
// Step 1 ensure that we have a label
int leftBracketCount = 1;
int rightBracketCount = 0;
int startLabelOffset = builder.getCurrentOffset();
int endLabelOffset;
while (!builder.eof()) {
IElementType token = findInlineToken(builder, JavaDocTokenType.DOC_RBRACKET, JavaDocTokenType.DOC_LBRACKET, true);
if (token == JavaDocTokenType.DOC_LBRACKET) {
leftBracketCount++;
continue;
}
if (token == JavaDocTokenType.DOC_RBRACKET) {
rightBracketCount++;
if (leftBracketCount == rightBracketCount) break;
}
}
endLabelOffset = builder.getCurrentOffset();
boolean isShortRefEmpty = endLabelOffset - startLabelOffset <= 1;
if (leftBracketCount != rightBracketCount || isShortRefEmpty) {
tag.rollbackTo();
builder.advanceLexer();
return;
}
IElementType firstReferenceToken = findInlineToken(builder, JavaDocTokenType.DOC_LBRACKET, JavaDocTokenType.DOC_SPACE, false);
if (firstReferenceToken != JavaDocTokenType.DOC_LBRACKET) {
if (leftBracketCount > 1 || firstReferenceToken == JavaDocTokenType.DOC_LPAREN) {
tag.rollbackTo();
builder.advanceLexer();
return;
}
hasLabel = false;
}
// Step 2 get the reference for full reference link
if (hasLabel) {
if (findInlineToken(builder, JavaDocTokenType.DOC_RBRACKET, JavaDocTokenType.DOC_LBRACKET, true) != JavaDocTokenType.DOC_RBRACKET) {
if (leftBracketCount > 1) {
tag.rollbackTo();
builder.advanceLexer();
return;
}
hasLabel = false;
}
}
// Step 3, parse the content
tag.rollbackTo();
tag = builder.mark();
if (hasLabel) {
while (!builder.eof()) {
builder.advanceLexer();
if (builder.getCurrentOffset() < endLabelOffset) {
builder.remapCurrentToken(JavaDocTokenType.DOC_COMMENT_DATA);
}
else {
break;
}
}
builder.advanceLexer();
}
// Parse the reference itself
builder.advanceLexer();
parseMarkdownReference(builder, javaDocElementTypeContainer);
builder.advanceLexer();
tag.done(javaDocElementTypeContainer.DOC_MARKDOWN_REFERENCE_LINK);
parseMarkdownReferenceChecked(builder, javaDocElementTypeContainer);
}
else {
remapAndAdvance(builder);
}
}
private static void parseCodeBlock(PsiBuilder builder,
AbstractBasicJavaDocElementTypeFactory.@NotNull JavaDocElementTypeContainer javaDocElementTypeContainer) {
if (getBraceScope(builder) > 0) {
builder.remapCurrentToken(JavaDocTokenType.DOC_COMMENT_DATA);
builder.advanceLexer();
return;
}
// Store the fence type, a fenced code block can only be closed by the same fence type
char fenceStart = builder.getTokenText().charAt(0);
PsiBuilder.Marker tag = builder.mark();
// Look for the nearest closing code fence, converting everything inside as comment data
while (!builder.eof()) {
builder.advanceLexer();
if (getTokenType(builder) == JavaDocTokenType.DOC_CODE_FENCE && builder.getTokenText().charAt(0) == fenceStart) {
break;
}
builder.remapCurrentToken(JavaDocTokenType.DOC_COMMENT_DATA);
}
if (!builder.eof()) {
builder.advanceLexer();
}
tag.done(javaDocElementTypeContainer.DOC_MARKDOWN_CODE_BLOCK);
}
/** Ensure a reference link is good before parsing it */
private static void parseMarkdownReferenceChecked(PsiBuilder builder, @NotNull AbstractBasicJavaDocElementTypeFactory.JavaDocElementTypeContainer javaDocElementTypeContainer) {
boolean hasLabel = true;
PsiBuilder.Marker tag = builder.mark();
// Step 1 ensure that we have a label
int leftBracketCount = 1;
int rightBracketCount = 0;
int startLabelOffset = builder.getCurrentOffset();
int endLabelOffset;
// Labels are allowed balanced brackets, count each side
while (!builder.eof()) {
IElementType token = findInlineToken(builder, JavaDocTokenType.DOC_RBRACKET, JavaDocTokenType.DOC_LBRACKET, true);
if (token == JavaDocTokenType.DOC_LBRACKET) {
leftBracketCount++;
continue;
}
if (token == JavaDocTokenType.DOC_RBRACKET) {
rightBracketCount++;
if (leftBracketCount == rightBracketCount) break;
}
}
endLabelOffset = builder.getCurrentOffset();
boolean isShortRefEmpty = endLabelOffset - startLabelOffset <= 1;
if (leftBracketCount != rightBracketCount || isShortRefEmpty) {
// Stop if unbalanced brackets/empty reference
tag.rollbackTo();
builder.advanceLexer();
return;
}
IElementType firstReferenceToken = findInlineToken(builder, JavaDocTokenType.DOC_LBRACKET, JavaDocTokenType.DOC_SPACE, false);
if (firstReferenceToken != JavaDocTokenType.DOC_LBRACKET) {
hasLabel = false;
// The label is actually a reference, verify brackets balance or if we have a normal markdown link
if (leftBracketCount > 1 || firstReferenceToken == JavaDocTokenType.DOC_LPAREN) {
tag.rollbackTo();
builder.advanceLexer();
return;
}
}
// Step 2 get the reference for full reference link
if (hasLabel) {
if (findInlineToken(builder, JavaDocTokenType.DOC_RBRACKET, JavaDocTokenType.DOC_LBRACKET, true) != JavaDocTokenType.DOC_RBRACKET) {
hasLabel = false;
// The label is actually a reference, verify brackets balance
if (leftBracketCount > 1) {
tag.rollbackTo();
builder.advanceLexer();
return;
}
}
}
// Step 3, validity ensured, parse the link
tag.rollbackTo();
tag = builder.mark();
if (hasLabel) {
// Label range already known, mark it as comment data
while (!builder.eof()) {
builder.advanceLexer();
if (builder.getCurrentOffset() < endLabelOffset) {
builder.remapCurrentToken(JavaDocTokenType.DOC_COMMENT_DATA);
continue;
}
break;
}
builder.advanceLexer();
}
// Parse the reference itself
builder.advanceLexer();
parseMarkdownReference(builder, javaDocElementTypeContainer);
builder.advanceLexer();
tag.done(javaDocElementTypeContainer.DOC_MARKDOWN_REFERENCE_LINK);
}
private static void parseMarkdownReference(@NotNull PsiBuilder builder,
@NotNull AbstractBasicJavaDocElementTypeFactory.JavaDocElementTypeContainer javaDocElementTypeContainer) {
PsiBuilder.Marker refStart = builder.mark();
@@ -320,12 +328,18 @@ public final class BasicJavaDocParser {
refStart.drop();
}
/** Look for the token provided by `needle`, taking into account markdown line break rules */
/**
* Look for the token provided by `needle`, taking into account markdown line break rules
* @param travelToken The token that is either allowed or disallowed to encounter while looking for the `needle`
* @param isTravelTokenDisallowed When `true`, the `travelToken` will abort the search
* When `false`, encountering something other than `travelToken` or `needle` will abort the search
* @return The last token encountered during the search.
*/
@Contract(mutates = "param1")
private static @Nullable IElementType findInlineToken(@NotNull PsiBuilder builder,
IElementType needle,
IElementType travelToken,
boolean areDisallowed) {
boolean isTravelTokenDisallowed) {
IElementType token = null;
IElementType previousToken;
while (!builder.eof()) {
@@ -336,7 +350,7 @@ public final class BasicJavaDocParser {
return token;
}
boolean travelTokenFound = travelToken == token;
if ((areDisallowed && travelTokenFound) || (!areDisallowed && !travelTokenFound)) {
if ((isTravelTokenDisallowed && travelTokenFound) || (!isTravelTokenDisallowed && !travelTokenFound)) {
break;
}
@@ -525,7 +539,8 @@ public final class BasicJavaDocParser {
refStart.done(javaDocElementTypeContainer.DOC_METHOD_OR_FIELD_REF);
}
private static void parseParameterRef(@NotNull PsiBuilder builder, @NotNull AbstractBasicJavaDocElementTypeFactory.JavaDocElementTypeContainer javaDocElementTypeContainer) {
private static void parseParameterRef(@NotNull PsiBuilder builder,
@NotNull AbstractBasicJavaDocElementTypeFactory.JavaDocElementTypeContainer javaDocElementTypeContainer) {
PsiBuilder.Marker tagValue = builder.mark();
while (TAG_VALUES_SET.contains(getTokenType(builder))) builder.advanceLexer();
tagValue.done(javaDocElementTypeContainer.DOC_PARAMETER_REF);
@@ -8,12 +8,8 @@ import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.actionSystem.EditorActionHandler;
import com.intellij.openapi.util.Ref;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiMember;
import com.intellij.psi.PsiWhiteSpace;
import com.intellij.psi.*;
import com.intellij.psi.javadoc.PsiDocComment;
import com.intellij.psi.javadoc.PsiDocToken;
import com.intellij.psi.util.PsiTreeUtil;
import org.jetbrains.annotations.NotNull;
@@ -25,6 +21,7 @@ public class JavaDocMarkdownEnterHandler extends EnterHandlerDelegateAdapter {
@NotNull Ref<Integer> caretAdvance,
@NotNull DataContext dataContext,
EditorActionHandler originalHandler) {
if (!(file instanceof PsiJavaFile) || !file.isValid()) return Result.Continue;
PsiElement caretElement = file.findElementAt(caretOffset.get());
if (caretElement == null) return Result.Continue;
@@ -35,7 +32,7 @@ public class JavaDocMarkdownEnterHandler extends EnterHandlerDelegateAdapter {
currentElement = currentElement.getPrevSibling();
}
if (!((currentElement instanceof PsiDocToken token) && shouldInsertLeadingTokens(token))) {
if (!shouldInsertLeadingTokens(currentElement)) {
return Result.Continue;
}
Document document = editor.getDocument();
@@ -52,7 +49,7 @@ public class JavaDocMarkdownEnterHandler extends EnterHandlerDelegateAdapter {
* @param element a doc element found at the caret offset
* @return If the javadoc is tied to a method/a class it should return true otherwise false
*/
private static boolean shouldInsertLeadingTokens(PsiDocToken element) {
private static boolean shouldInsertLeadingTokens(PsiElement element) {
PsiDocComment docComment = PsiTreeUtil.getParentOfType(element, PsiDocComment.class, false, PsiMember.class);
if (docComment == null || !docComment.isMarkdownComment()) return false;
@@ -40,7 +40,7 @@ public final class JavadocSnippetEnterHandler extends EnterHandlerDelegateAdapte
final InjectedLanguageManager injectedLanguageManager = InjectedLanguageManager.getInstance(file.getProject());
final PsiSnippetDocTag host = ObjectUtils.tryCast(injectedLanguageManager.getInjectionHost(file), PsiSnippetDocTag.class);
return (host == null || PsiUtil.isInMarkdownDocComment(host)) ? Result.Continue : Result.Default;
return host == null ? Result.Continue : Result.Default;
}
@Override
@@ -60,7 +60,7 @@ public final class JavadocSnippetEnterHandler extends EnterHandlerDelegateAdapte
int firstNonWsLineOffset = CharArrayUtil.shiftForward(hostDocument.getText(), lineStartOffset, " \t");
if (hostDocument.getText().charAt(firstNonWsLineOffset) != '*') {
final String prefix = calcPrefix(host);
final String prefix = calcPrefix(host, PsiUtil.isInMarkdownDocComment(InjectedLanguageManager.getInstance(file.getProject()).getInjectionHost(file)));
hostDocument.insertString(lineStartOffset, prefix);
caretModelHost.moveToOffset(caretOffsetHost + prefix.length());
EditorModificationUtilEx.scrollToCaret(editor);
@@ -84,7 +84,7 @@ public final class JavadocSnippetEnterHandler extends EnterHandlerDelegateAdapte
return host;
}
private static String calcPrefix(PsiSnippetDocTag host) {
private static String calcPrefix(PsiSnippetDocTag host, boolean markdownComment) {
final PsiFile file = host.getContainingFile();
final String text = file.getText();
@@ -99,7 +99,7 @@ public final class JavadocSnippetEnterHandler extends EnterHandlerDelegateAdapte
final JavaCodeStyleSettings settings = CodeStyle.getCustomSettings(file, JavaCodeStyleSettings.class);
return settings.JD_LEADING_ASTERISKS_ARE_ENABLED ? whitespacesPrefix + "* " : whitespacesPrefix;
return (settings.JD_LEADING_ASTERISKS_ARE_ENABLED && !markdownComment) ? whitespacesPrefix + "* " : whitespacesPrefix;
}
}
@@ -8,6 +8,8 @@ import com.intellij.psi.JavaDocTokenType;
import com.intellij.psi.codeStyle.CommonCodeStyleSettings;
import com.intellij.psi.codeStyle.JavaCodeStyleSettings;
import com.intellij.psi.formatter.FormatterUtil;
import com.intellij.psi.tree.IElementType;
import com.intellij.psi.util.PsiUtil;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
@@ -30,8 +32,10 @@ public class DocCommentBlock extends AbstractJavaBlock{
final ArrayList<Block> result = new ArrayList<>();
ASTNode child = myNode.getFirstChildNode();
boolean isMarkdown = PsiUtil.isInMarkdownDocComment(child.getPsi());
while (child != null) {
if (child.getElementType() == JavaDocTokenType.DOC_COMMENT_START) {
IElementType type = child.getElementType();
if (type == JavaDocTokenType.DOC_COMMENT_START || (type == JavaDocTokenType.DOC_COMMENT_LEADING_ASTERISKS && isMarkdown)) {
result.add(createJavaBlock(child, mySettings, myJavaSettings, Indent.getNoneIndent(), null, AlignmentStrategy.getNullStrategy(), getFormattingMode()));
} else if (!FormatterUtil.containsWhiteSpacesOnly(child) && !child.getText().trim().isEmpty()){
result.add(createJavaBlock(child, mySettings, myJavaSettings, Indent.getSpaceIndent(1), null, AlignmentStrategy.getNullStrategy(), getFormattingMode()));
@@ -0,0 +1,8 @@
// "_ignore" "true"
/// - [the `java.util` package][java.util]
/// - [a class][String]
/// - [a field][String#CASE_INSENSITIVE_ORDER]
/// - [a method][String#chars()]
///<caret>
class C{}
@@ -0,0 +1,7 @@
// "_ignore" "true"
/// - [the `java.util` package][java.util]
/// - [a class][String]
/// - [a field][String#CASE_INSENSITIVE_ORDER]
/// - [a method][String#chars()]<caret>
class C{}
@@ -1 +1,2 @@
<html><head><base href="placeholder"></head><body><div class='definition'><pre><span style="color:#000080;font-weight:bold;">class</span> <span style="color:#000000;">MarkdownFeatures</span></pre></div><div class='content'><h1>Title1</h1><h2>Title2</h2><h3>Title 3</h3><p><em>italic</em> <strong>strong</strong> <code>code</code></p>Separate paragraph</div><table class='sections'><p></table>
<html><head><base href="placeholder"></head><body><div class='definition'><pre><span style="color:#000080;font-weight:bold;">class</span> <span style="color:#000000;">MarkdownFeatures</span></pre></div><div class='content'><h1>Title1</h1><h2>Title2</h2><h3>Title 3</h3><p><em>italic</em> <strong>strong</strong> <code>code</code></p><p>Separate paragraph</p> <pre><code><span style="">System.out.println(</span><span style="color:#008000;font-weight:bold;">"Hello&#32;there"</span><span style="">);</span></code></pre>
</div><table class='sections'><p></table>
@@ -6,4 +6,7 @@
/// *italic* **strong** `code`
///
/// Separate paragraph
/// ```JAVA
/// System.out.println("Hello there");
/// ```
class MarkdownFeatures {}
@@ -11,4 +11,8 @@ class DanglingJavadoc {
<warning descr="Dangling Javadoc comment">/**</warning>
* yada yada
*/
<warning descr="Dangling Javadoc comment">///</warning>
/// yada yada
///
}
@@ -9,4 +9,8 @@ package com.siyeh.igtest.javadoc.dangling_javadoc;
<warning descr="Dangling Javadoc comment">/**</warning>
oops
*/
*/
<warning descr="Dangling Javadoc comment">///</warning>
///oops
///
@@ -0,0 +1,25 @@
// Copyright 2000-2021 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.java.codeInsight.javadoc;
import com.intellij.codeInsight.daemon.quickFix.ActionHint;
import com.intellij.codeInsight.daemon.quickFix.LightQuickFixParameterizedTestCase;
import org.jetbrains.annotations.NotNull;
public class JavadocMarkdownEnterHandlerTest extends LightQuickFixParameterizedTestCase {
@Override
protected String getBasePath() {
return "/codeInsight/javadoc/markdown/enterhandler";
}
@Override
protected void doAction(@NotNull ActionHint actionHint, @NotNull String testFullPath, @NotNull String testName) {
executeAction("EditorEnter");
checkResult(testName);
}
private void checkResult(@NotNull final String testName) {
final String expectedFilePath = getBasePath() + "/after" + testName;
checkResultByFile("In file: " + expectedFilePath, expectedFilePath, false);
}
}