diff --git a/java/java-impl/src/com/intellij/codeInsight/javadoc/JavaDocInfoGenerator.java b/java/java-impl/src/com/intellij/codeInsight/javadoc/JavaDocInfoGenerator.java index fa7a896ee127..0e939455677a 100644 --- a/java/java-impl/src/com/intellij/codeInsight/javadoc/JavaDocInfoGenerator.java +++ b/java/java-impl/src/com/intellij/codeInsight/javadoc/JavaDocInfoGenerator.java @@ -53,7 +53,6 @@ import com.intellij.psi.impl.source.tree.JavaElementType; import com.intellij.psi.javadoc.*; import com.intellij.psi.search.GlobalSearchScope; import com.intellij.psi.tree.IElementType; -import com.intellij.psi.tree.TokenSet; import com.intellij.psi.util.*; import com.intellij.psi.xml.XmlAttribute; import com.intellij.psi.xml.XmlAttributeValue; @@ -62,7 +61,6 @@ import com.intellij.ui.ColorUtil; import com.intellij.util.ArrayUtil; import com.intellij.util.ArrayUtilRt; import com.intellij.util.IncorrectOperationException; -import com.intellij.util.ObjectUtils; import com.intellij.util.containers.ContainerUtil; import com.intellij.xml.util.XmlStringUtil; import kotlin.text.StringsKt; @@ -426,7 +424,7 @@ public class JavaDocInfoGenerator { LOG.debug(e); result.replace(result.length() - 6, result.length(), "wrong-href=\""); // display text instead of link } - result.append(ObjectUtils.notNull(reference, href)); + result.append(reference == null ? href : reference); lastRef = groupEnd; } } @@ -594,17 +592,13 @@ public class JavaDocInfoGenerator { if (generatePrologue) generatePrologue(buffer); generateVariableDefinition(buffer, recordComponent, true); - PsiRecordHeader recordHeader = ObjectUtils.tryCast(recordComponent.getParent(), PsiRecordHeader.class); - if (recordHeader == null) return; - PsiRecordComponent[] components = recordHeader.getRecordComponents(); - int recordIndex = ArrayUtil.indexOf(components, recordComponent); + if (!(recordComponent.getParent() instanceof PsiRecordHeader recordHeader)) return; + int recordIndex = ArrayUtil.indexOf(recordHeader.getRecordComponents(), recordComponent); PsiClass recordClass = recordComponent.getContainingClass(); if (recordClass == null) return; String recordComponentJavadoc = getRecordComponentJavadocFromParameterTag(recordIndex, recordClass); if (recordComponentJavadoc != null) { - buffer.append(DocumentationMarkup.CONTENT_START); - buffer.append(recordComponentJavadoc); - buffer.append(DocumentationMarkup.CONTENT_END); + buffer.append(DocumentationMarkup.CONTENT_START).append(recordComponentJavadoc).append(DocumentationMarkup.CONTENT_END); } } @@ -614,13 +608,10 @@ public class JavaDocInfoGenerator { String docForPattern = getDocForPattern(variable); if (docForPattern != null) { - buffer.append(DocumentationMarkup.CONTENT_START); - buffer.append(docForPattern); - buffer.append(DocumentationMarkup.CONTENT_END); + buffer.append(DocumentationMarkup.CONTENT_START).append(docForPattern).append(DocumentationMarkup.CONTENT_END); } } - private @Nullable String getDocForPattern(@NotNull PsiPatternVariable variable) { PsiPattern pattern = variable.getPattern(); PsiElement parent = pattern.getParent(); @@ -2631,8 +2622,7 @@ public class JavaDocInfoGenerator { } if (pair != null) { - startHeaderSection(buffer, CodeInsightBundle.message("javadoc.returns")) - .append("
"); + startHeaderSection(buffer, CodeInsightBundle.message("javadoc.returns")).append("
");
generateValue(buffer, pair.first.getDataElements(), mapProvider(pair.second, false));
buffer.append(DocumentationMarkup.SECTION_END);
}
@@ -2651,77 +2641,36 @@ public class JavaDocInfoGenerator {
private void generateThrowsSection(StringBuilder buffer, PsiMethod method, PsiDocComment comment) {
final PsiDocTag[] throwsJavadocTags = getThrowsTags(comment);
-
- final PsiJavaCodeReferenceElement[] methodThrows = isRendered() ? PsiJavaCodeReferenceElement.EMPTY_ARRAY
- : method.getThrowsList().getReferenceElements();
-
- final int totalThrowsToDocument = throwsJavadocTags.length + methodThrows.length;
- if (totalThrowsToDocument == 0) return;
-
- final class Data {
- final @NotNull PsiJavaCodeReferenceElement ref;
- final @Nullable PsiDocTag tag;
-
- private Data(@NotNull PsiJavaCodeReferenceElement ref, @Nullable PsiDocTag tag) {
- this.ref = ref;
- this.tag = tag;
- }
- }
-
- final Map<@NotNull String, @NotNull Data> throwTags = new LinkedHashMap<>(totalThrowsToDocument, 1.0f);
-
- for (PsiDocTag tag : throwsJavadocTags) {
- final PsiDocTagValue value = tag.getValueElement();
- if (value == null) continue;
-
- final ASTNode[] children = value.getNode().getChildren(TokenSet.create(JavaDocElementType.DOC_REFERENCE_HOLDER));
- if (children.length != 1) continue;
-
- final PsiJavaCodeReferenceElement element = ObjectUtils.tryCast(children[0].getFirstChildNode(), PsiJavaCodeReferenceElement.class);
- if (element != null) {
- throwTags.put(element.getQualifiedName(), new Data(element, tag));
- }
- }
-
- Arrays.stream(methodThrows)
- .filter(e -> !throwTags.containsKey(e.getQualifiedName()))
- .forEach(e -> throwTags.put(e.getQualifiedName(), new Data(e, null)));
-
- if (throwTags.isEmpty()) return;
+ final PsiJavaCodeReferenceElement[] methodThrows = isRendered()
+ ? PsiJavaCodeReferenceElement.EMPTY_ARRAY
+ : method.getThrowsList().getReferenceElements();
+ if (throwsJavadocTags.length + methodThrows.length == 0) return;
startHeaderSection(buffer, CodeInsightBundle.message("javadoc.throws"));
-
- for (Map.Entry ");
-
- final PsiElement[] elements = tag != null ? tag.getDataElements() : PsiElement.EMPTY_ARRAY;
-
- if (target != null) {
+ PsiElement[] dataElements = tag.getDataElements();
+ if (dataElements.length == 0) continue;
+ PsiElement grandChild = dataElements[0].getFirstChild().getFirstChild();
+ if (!(grandChild instanceof PsiJavaCodeReferenceElement reference)) continue;
+ if (reference.resolve() instanceof PsiClass target) {
generateLink(buffer, target);
}
- else if (elements.length != 0) {
- generateLink(buffer, elements[0].getText(), null, method, false);
- }
else {
- generateUnresolvedLink(buffer, exceptionType);
+ generateLink(buffer, dataElements[0].getText(), null, method, false);
}
-
- if (elements.length < 2) continue;
+ documentedExceptions.add(reference.getQualifiedName());
+ if (dataElements.length < 2) continue;
buffer.append(" – ");
final Pair ");
+ if (exception.resolve() instanceof PsiClass target) generateLink(buffer, target);
+ else generateLink(buffer, exception.getText(), null, method, false);
+ }
buffer.append(DocumentationMarkup.SECTION_END);
}
- private void generateUnresolvedLink(StringBuilder buffer, @NotNull PsiJavaCodeReferenceElement exceptionType) {
- final String label = JavaDocUtil.getLabelText(exceptionType.getProject(),
- exceptionType.getManager(),
- exceptionType.getQualifiedName(),
- exceptionType);
- appendMaybeUnresolvedLink(buffer, null, label, myProject, false);
- }
-
@Contract(mutates = "param1")
private void generateLink(@NotNull StringBuilder buffer, @NotNull PsiClass target) {
final String label = JavaDocUtil.getLabelText(target.getProject(), target.getManager(), target.getName(), target);
appendMaybeUnresolvedLink(buffer, target, label, target.getProject(), false);
}
- private static @Nullable @NlsSafe String generateLink(@NotNull PsiElement element,
- String label) {
+ private static @Nullable @NlsSafe String generateLink(@NotNull PsiElement element, String label) {
String refText = JavaDocUtil.getReferenceText(element.getProject(), element);
if (refText != null) {
StringBuilder linkBuilder = new StringBuilder();
diff --git a/java/java-tests/testData/codeInsight/javadocIG/multipleThrowsSameType.html b/java/java-tests/testData/codeInsight/javadocIG/multipleThrowsSameType.html
new file mode 100644
index 000000000000..0130e00e2b62
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/javadocIG/multipleThrowsSameType.html
@@ -0,0 +1,2 @@
+ Throws:public void method(
int a,
+ int b
)
\ No newline at end of file
diff --git a/java/java-tests/testData/codeInsight/javadocIG/multipleThrowsSameType.java b/java/java-tests/testData/codeInsight/javadocIG/multipleThrowsSameType.java
new file mode 100644
index 000000000000..5ea76594a57c
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/javadocIG/multipleThrowsSameType.java
@@ -0,0 +1,7 @@
+class A {
+ /**
+ * @throws java.lang.IllegalArgumentException if a is negative
+ * @throws java.lang.IllegalArgumentException if b is negative
+ */
+ public void method(int a, int b) {}
+}
\ No newline at end of file
diff --git a/java/java-tests/testSrc/com/intellij/java/codeInsight/javadoc/JavaDocInfoGeneratorTest.java b/java/java-tests/testSrc/com/intellij/java/codeInsight/javadoc/JavaDocInfoGeneratorTest.java
index 8497b42fd796..c2656f06e0e2 100644
--- a/java/java-tests/testSrc/com/intellij/java/codeInsight/javadoc/JavaDocInfoGeneratorTest.java
+++ b/java/java-tests/testSrc/com/intellij/java/codeInsight/javadoc/JavaDocInfoGeneratorTest.java
@@ -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.intellij.java.codeInsight.javadoc;
import com.intellij.JavaTestUtil;
@@ -81,6 +81,7 @@ public class JavaDocInfoGeneratorTest extends JavaCodeInsightTestCase {
public void testMethodTypeParameter3() { doTestAtCaret(); }
public void testInheritedDocInThrows() { doTestMethod(); }
public void testInheritedDocInThrows1() { doTestMethod(); }
+ public void testMultipleThrowsSameType() { doTestMethod(); }
public void testEscapeValues() { doTestClass(); }
public void testClassTypeParameter() { doTestClass(); }
public void testClassTypeParameter1() { doTestClass(); }
IllegalArgumentException – if a is negative IllegalArgumentException – if b is negative