diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/javadoc/PsiMarkdownReferenceLinkImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/javadoc/PsiMarkdownReferenceLinkImpl.java
index 7a7958df6af3..1afd55c55b1c 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/source/javadoc/PsiMarkdownReferenceLinkImpl.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/javadoc/PsiMarkdownReferenceLinkImpl.java
@@ -5,6 +5,7 @@ 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.TreeElement;
import com.intellij.psi.javadoc.PsiMarkdownReferenceLink;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -32,21 +33,28 @@ public class PsiMarkdownReferenceLinkImpl extends CompositePsiElement implements
@Override
public @Nullable PsiElement getLabel() {
- if (getChildren().length >= 1) {
- return getChildren()[1];
- }
- // malformed/incomplete link
- return null;
+ // returns `null` malformed/incomplete link
+ return getChildAt(1);
}
@Override
public boolean isShortLink() {
- return getChildren().length < 4;
+ return countChildren(null) < 5;
}
@Override
public @Nullable PsiElement getLinkElement() {
- if (isShortLink()) return getLabel();
- return getChildren()[4];
+ int childrenCount = countChildren(null);
+ return getChildAt(childrenCount - 2);
+ }
+
+ /// Utility function, get PsiElement at specific index (if it exists)
+ private @Nullable PsiElement getChildAt(int index) {
+ TreeElement child = getFirstChildNode();
+ for (int i = 0; i < index; i++) {
+ child = child.getTreeNext();
+ if (child == null) return null;
+ }
+ return child == null ? null : child.getPsi();
}
}
diff --git a/java/java-syntax/src/com/intellij/java/syntax/parser/JavaDocParser.kt b/java/java-syntax/src/com/intellij/java/syntax/parser/JavaDocParser.kt
index caa8ee1b4336..f223fcbe5c5c 100644
--- a/java/java-syntax/src/com/intellij/java/syntax/parser/JavaDocParser.kt
+++ b/java/java-syntax/src/com/intellij/java/syntax/parser/JavaDocParser.kt
@@ -320,7 +320,6 @@ class JavaDocParser(
}
private fun parseMarkdownReference() {
- val refStart = builder.mark()
val moduleMarker = parseModuleRef(builder.mark())
var referenceParsed = false
var referenceEnded = false
@@ -328,12 +327,12 @@ class JavaDocParser(
if (getTokenType() === JavaDocSyntaxTokenType.DOC_RBRACKET) {
if (moduleMarker == null) {
- refStart.drop()
return
- } else {
- referenceEnded = true
}
+ referenceEnded = true
}
+ moduleMarker?.done(JavaDocSyntaxElementType.DOC_TAG_VALUE_ELEMENT)
+ val refStart = builder.mark()
if (!referenceEnded && getTokenType() !== JavaDocSyntaxTokenType.DOC_SHARP && getTokenType() !== JavaDocSyntaxTokenType.DOC_DOUBLE_SHARP) {
builder.remapCurrentToken(JavaDocSyntaxElementType.DOC_REFERENCE_HOLDER)
@@ -395,8 +394,7 @@ class JavaDocParser(
}
}
- if (referenceParsed || moduleMarker != null) {
- moduleMarker?.done(JavaDocSyntaxElementType.DOC_TAG_VALUE_ELEMENT)
+ if (referenceParsed) {
when (fragmentReference) {
true -> refStart.done(JavaDocSyntaxElementType.DOC_FRAGMENT_REF)
false -> refStart.done(JavaDocSyntaxElementType.DOC_METHOD_OR_FIELD_REF)
diff --git a/java/java-tests/testData/codeInsight/javadocIG/markdownReferenceLink.html b/java/java-tests/testData/codeInsight/javadocIG/markdownReferenceLink.html
index e71c87cddeae..e53e588e421b 100644
--- a/java/java-tests/testData/codeInsight/javadocIG/markdownReferenceLink.html
+++ b/java/java-tests/testData/codeInsight/javadocIG/markdownReferenceLink.html
@@ -1 +1 @@
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/java/java-tests/testData/codeInsight/javadocIG/markdownReferenceLink.java b/java/java-tests/testData/codeInsight/javadocIG/markdownReferenceLink.java
index 3f7a22656621..2119a0992520 100644
--- a/java/java-tests/testData/codeInsight/javadocIG/markdownReferenceLink.java
+++ b/java/java-tests/testData/codeInsight/javadocIG/markdownReferenceLink.java
@@ -1,8 +1,12 @@
-
-
+/// [java.base/]
+///
+/// [java.base/java.lang.String]
+///
+/// [java.base/java.lang.String#toString()]
+///
/// [java.util.HashMap]
///
/// [The default empty collection][java.util.Collections#EMPTY_LIST]
-///
+///
/// [Test for context resolution][java.util.Collection#add(Object)]
class MarkdownCodeBlock {}
\ No newline at end of file
diff --git a/java/java-tests/testData/psi/parser-full/javadocParsing/LinkTag9Markdown.txt b/java/java-tests/testData/psi/parser-full/javadocParsing/LinkTag9Markdown.txt
index 8b751b7dcbf9..14226658a2dc 100644
--- a/java/java-tests/testData/psi/parser-full/javadocParsing/LinkTag9Markdown.txt
+++ b/java/java-tests/testData/psi/parser-full/javadocParsing/LinkTag9Markdown.txt
@@ -29,29 +29,29 @@ PsiJavaFile:LinkTag9Markdown.java
PsiDocToken:DOC_COMMENT_DATA('text for the link')
PsiDocToken:DOC_RBRACKET(']')
PsiDocToken:DOC_LBRACKET('[')
+ PsiElement(DOC_TAG_VALUE_ELEMENT)
+ PsiJavaModuleReference
+ PsiDocToken:DOC_COMMENT_DATA('java.base')
+ PsiDocToken:DOC_TAG_VALUE_SLASH('/')
PsiElement(DOC_FRAGMENT_REF)
- PsiElement(DOC_TAG_VALUE_ELEMENT)
- PsiJavaModuleReference
- PsiDocToken:DOC_COMMENT_DATA('java.base')
- PsiDocToken:DOC_TAG_VALUE_SLASH('/')
- PsiElement(DOC_REFERENCE_HOLDER)
- PsiJavaCodeReferenceElement:java.lang.String
- PsiJavaCodeReferenceElement:java.lang
- PsiJavaCodeReferenceElement:java
- PsiIdentifier:java('java')
- PsiReferenceParameterList
-
- PsiJavaToken:DOT('.')
- PsiIdentifier:lang('lang')
+ PsiElement(DOC_REFERENCE_HOLDER)
+ PsiJavaCodeReferenceElement:java.lang.String
+ PsiJavaCodeReferenceElement:java.lang
+ PsiJavaCodeReferenceElement:java
+ PsiIdentifier:java('java')
PsiReferenceParameterList
PsiJavaToken:DOT('.')
- PsiIdentifier:String('String')
+ PsiIdentifier:lang('lang')
PsiReferenceParameterList
- PsiDocToken:DOC_TAG_VALUE_DOUBLE_SHARP_TOKEN('##')
- PsiElement(DOC_FRAGMENT_NAME)
- PsiDocToken:DOC_COMMENT_DATA('fragment-name')
+ PsiJavaToken:DOT('.')
+ PsiIdentifier:String('String')
+ PsiReferenceParameterList
+
+ PsiDocToken:DOC_TAG_VALUE_DOUBLE_SHARP_TOKEN('##')
+ PsiElement(DOC_FRAGMENT_NAME)
+ PsiDocToken:DOC_COMMENT_DATA('fragment-name')
PsiDocToken:DOC_RBRACKET(']')
PsiWhiteSpace('\n')
PsiModifierList:public
diff --git a/java/java-tests/testData/psi/parser-full/javadocParsing/LinkTag9Markdown_node.txt b/java/java-tests/testData/psi/parser-full/javadocParsing/LinkTag9Markdown_node.txt
index 111934a0cec1..8623231ff4e8 100644
--- a/java/java-tests/testData/psi/parser-full/javadocParsing/LinkTag9Markdown_node.txt
+++ b/java/java-tests/testData/psi/parser-full/javadocParsing/LinkTag9Markdown_node.txt
@@ -29,19 +29,15 @@ java.FILE
DOC_COMMENT_DATA
DOC_RBRACKET
DOC_LBRACKET
+ DOC_TAG_VALUE_ELEMENT
+ MODULE_REFERENCE
+ DOC_COMMENT_DATA
+ DOC_TAG_VALUE_SLASH
DOC_FRAGMENT_REF
- DOC_TAG_VALUE_ELEMENT
- MODULE_REFERENCE
- DOC_COMMENT_DATA
- DOC_TAG_VALUE_SLASH
- DOC_REFERENCE_HOLDER
+ DOC_REFERENCE_HOLDER
+ JAVA_CODE_REFERENCE
JAVA_CODE_REFERENCE
JAVA_CODE_REFERENCE
- JAVA_CODE_REFERENCE
- IDENTIFIER
- REFERENCE_PARAMETER_LIST
-
- DOT
IDENTIFIER
REFERENCE_PARAMETER_LIST
@@ -49,9 +45,13 @@ java.FILE
IDENTIFIER
REFERENCE_PARAMETER_LIST
- DOC_TAG_VALUE_DOUBLE_SHARP_TOKEN
- DOC_FRAGMENT_NAME
- DOC_COMMENT_DATA
+ DOT
+ IDENTIFIER
+ REFERENCE_PARAMETER_LIST
+
+ DOC_TAG_VALUE_DOUBLE_SHARP_TOKEN
+ DOC_FRAGMENT_NAME
+ DOC_COMMENT_DATA
DOC_RBRACKET
WHITE_SPACE
MODIFIER_LIST
diff --git a/java/java-tests/testData/psi/parser-full/javadocParsing/ReferenceLinkMarkdown13.java b/java/java-tests/testData/psi/parser-full/javadocParsing/ReferenceLinkMarkdown13.java
index 04ad718779de..813663ccc2ff 100644
--- a/java/java-tests/testData/psi/parser-full/javadocParsing/ReferenceLinkMarkdown13.java
+++ b/java/java-tests/testData/psi/parser-full/javadocParsing/ReferenceLinkMarkdown13.java
@@ -1,2 +1,2 @@
-/// [link to module][java.base/]
+/// [link to module][java.base/String#toString()]
class C {}
\ No newline at end of file
diff --git a/java/java-tests/testData/psi/parser-full/javadocParsing/ReferenceLinkMarkdown13.txt b/java/java-tests/testData/psi/parser-full/javadocParsing/ReferenceLinkMarkdown13.txt
index 90bc309d4c15..c3d53b31072f 100644
--- a/java/java-tests/testData/psi/parser-full/javadocParsing/ReferenceLinkMarkdown13.txt
+++ b/java/java-tests/testData/psi/parser-full/javadocParsing/ReferenceLinkMarkdown13.txt
@@ -11,11 +11,22 @@ PsiJavaFile:ReferenceLinkMarkdown13.java
PsiDocToken:DOC_COMMENT_DATA('link to module')
PsiDocToken:DOC_RBRACKET(']')
PsiDocToken:DOC_LBRACKET('[')
+ PsiElement(DOC_TAG_VALUE_ELEMENT)
+ PsiJavaModuleReference
+ PsiDocToken:DOC_COMMENT_DATA('java.base')
+ PsiDocToken:DOC_TAG_VALUE_SLASH('/')
PsiElement(DOC_METHOD_OR_FIELD_REF)
+ PsiElement(DOC_REFERENCE_HOLDER)
+ PsiJavaCodeReferenceElement:String
+ PsiIdentifier:String('String')
+ PsiReferenceParameterList
+
+ PsiDocToken:DOC_TAG_VALUE_SHARP_TOKEN('#')
+ PsiDocToken:DOC_TAG_VALUE_TOKEN('toString')
+ PsiDocToken:DOC_LPAREN('(')
PsiElement(DOC_TAG_VALUE_ELEMENT)
- PsiJavaModuleReference
- PsiDocToken:DOC_COMMENT_DATA('java.base')
- PsiDocToken:DOC_TAG_VALUE_SLASH('/')
+
+ PsiDocToken:DOC_RPAREN(')')
PsiDocToken:DOC_RBRACKET(']')
PsiWhiteSpace('\n')
PsiModifierList:
diff --git a/java/java-tests/testData/psi/parser-full/javadocParsing/ReferenceLinkMarkdown13_node.txt b/java/java-tests/testData/psi/parser-full/javadocParsing/ReferenceLinkMarkdown13_node.txt
index cf3649452e9c..ff552bc56b1a 100644
--- a/java/java-tests/testData/psi/parser-full/javadocParsing/ReferenceLinkMarkdown13_node.txt
+++ b/java/java-tests/testData/psi/parser-full/javadocParsing/ReferenceLinkMarkdown13_node.txt
@@ -11,11 +11,22 @@ java.FILE
DOC_COMMENT_DATA
DOC_RBRACKET
DOC_LBRACKET
+ DOC_TAG_VALUE_ELEMENT
+ MODULE_REFERENCE
+ DOC_COMMENT_DATA
+ DOC_TAG_VALUE_SLASH
DOC_METHOD_OR_FIELD_REF
+ DOC_REFERENCE_HOLDER
+ JAVA_CODE_REFERENCE
+ IDENTIFIER
+ REFERENCE_PARAMETER_LIST
+
+ DOC_TAG_VALUE_SHARP_TOKEN
+ DOC_TAG_VALUE_TOKEN
+ DOC_LPAREN
DOC_TAG_VALUE_ELEMENT
- MODULE_REFERENCE
- DOC_COMMENT_DATA
- DOC_TAG_VALUE_SLASH
+
+ DOC_RPAREN
DOC_RBRACKET
WHITE_SPACE
MODIFIER_LIST
diff --git a/java/openapi/resources/messages/JavaBundle.properties b/java/openapi/resources/messages/JavaBundle.properties
index e106387c74db..56b134be6e79 100644
--- a/java/openapi/resources/messages/JavaBundle.properties
+++ b/java/openapi/resources/messages/JavaBundle.properties
@@ -1174,7 +1174,7 @@ quickfix.family.avoid.mutation.using.stream.api=Avoid mutation using Stream API
quickfix.family.change.javadoc.to=Change to \u2026
quickfix.family.find.cause=Find cause
quickfix.family.remove.javadoc.tag=Remove tag
-quickfix.family.remove.javadoc.reference=Remove tag
+quickfix.family.remove.javadoc.reference=Remove reference
quickfix.family.remove.redundant.parameter=Remove redundant parameter
quickfix.family.remove.redundant.parameter.types=Remove redundant parameter types
quickfix.family.replace.cast.type=Replace cast type
@@ -1195,7 +1195,7 @@ quickfix.text.0.may.not.work.before.jdk.11.0.2={0} (may not work before JDK 11.0
quickfix.text.avoid.mutation.using.stream.api.0.operation=Avoid mutation using Stream API ''{0}()'' operation
quickfix.text.remove.javadoc.0=Remove ''@{0}'' tag
quickfix.text.remove.javadoc.0.1=Remove @{0} {1}
-quickfix.text.remove.javadoc.reference=Remove ''@{0}'' reference
+quickfix.text.remove.javadoc.reference=Remove ''{0}'' reference
quickfix.text.remove.not.null.annotation=Remove non-null annotation
quickfix.text.replace.0.stream.with.1.2=Replace {0}.stream() with {1}.{2}()
quickfix.text.replace.collect.0.with.1.2=Replace ''collect({0}())'' with ''{1}''{2}