mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-01-04 17:20:55 +07:00
javadoc: include all throws unchecked exceptions from all super methods (IDEA-152938)
This commit is contained in:
@@ -15,10 +15,7 @@
|
||||
*/
|
||||
package com.intellij.codeInsight.javadoc;
|
||||
|
||||
import com.intellij.codeInsight.AnnotationUtil;
|
||||
import com.intellij.codeInsight.CodeInsightBundle;
|
||||
import com.intellij.codeInsight.ExternalAnnotationsManager;
|
||||
import com.intellij.codeInsight.InferredAnnotationsManager;
|
||||
import com.intellij.codeInsight.*;
|
||||
import com.intellij.codeInsight.documentation.DocumentationManagerProtocol;
|
||||
import com.intellij.codeInsight.documentation.DocumentationManagerUtil;
|
||||
import com.intellij.javadoc.JavadocGeneratorRunProfile;
|
||||
@@ -1723,11 +1720,36 @@ public class JavaDocInfoGenerator {
|
||||
|
||||
private void generateThrowsSection(StringBuilder buffer, PsiMethod method, PsiDocComment comment) {
|
||||
PsiDocTag[] localTags = getThrowsTags(comment);
|
||||
PsiDocTag[] thrownTags = localTags;
|
||||
JavaPsiFacade psiFacade = JavaPsiFacade.getInstance(method.getProject());
|
||||
|
||||
Set<PsiClass> reported = new HashSet<>();
|
||||
for (HierarchicalMethodSignature signature : method.getHierarchicalMethodSignature().getSuperSignatures()) {
|
||||
PsiMethod superMethod = ObjectUtils.tryCast(signature.getMethod().getNavigationElement(), PsiMethod.class);
|
||||
PsiDocComment docComment = superMethod != null ? superMethod.getDocComment() : null;
|
||||
if (docComment != null) {
|
||||
PsiDocTag[] uncheckedExceptions = Arrays.stream(getThrowsTags(docComment)).filter(tag -> {
|
||||
PsiDocTagValue valueElement = tag.getValueElement();
|
||||
if (valueElement == null) return false;
|
||||
if (Arrays.stream(localTags)
|
||||
.map(PsiDocTag::getValueElement)
|
||||
.map(ObjectUtils::notNull)
|
||||
.anyMatch(docTagValue -> areWeakEqual(docTagValue.getText(), valueElement.getText()))) {
|
||||
return false;
|
||||
}
|
||||
PsiClass exClass = psiFacade.getResolveHelper().resolveReferencedClass(valueElement.getText(), docComment);
|
||||
if (exClass == null) return false;
|
||||
return ExceptionUtil.isUncheckedException(exClass) && reported.add(exClass);
|
||||
}).toArray(PsiDocTag[]::new);
|
||||
thrownTags = ArrayUtil.mergeArrays(thrownTags, uncheckedExceptions);
|
||||
}
|
||||
}
|
||||
|
||||
LinkedList<Pair<PsiDocTag, InheritDocProvider<PsiDocTag>>> collectedTags = new LinkedList<>();
|
||||
List<PsiClassType> declaredThrows = new ArrayList<>(Arrays.asList(method.getThrowsList().getReferencedTypes()));
|
||||
|
||||
for (int i = localTags.length - 1; i > -1; i--) {
|
||||
PsiDocTagValue valueElement = localTags[i].getValueElement();
|
||||
for (int i = thrownTags.length - 1; i > -1; i--) {
|
||||
PsiDocTagValue valueElement = thrownTags[i].getValueElement();
|
||||
|
||||
if (valueElement != null) {
|
||||
for (Iterator<PsiClassType> iterator = declaredThrows.iterator(); iterator.hasNext();) {
|
||||
@@ -1740,7 +1762,7 @@ public class JavaDocInfoGenerator {
|
||||
}
|
||||
|
||||
Pair<PsiDocTag, InheritDocProvider<PsiDocTag>> tag = findInheritDocTag(method, exceptionLocator(valueElement.getText()));
|
||||
collectedTags.addFirst(new Pair<>(localTags[i], new InheritDocProvider<PsiDocTag>() {
|
||||
collectedTags.addFirst(new Pair<>(thrownTags[i], new InheritDocProvider<PsiDocTag>() {
|
||||
@Override
|
||||
public Pair<PsiDocTag, InheritDocProvider<PsiDocTag>> getInheritDoc() {
|
||||
return tag;
|
||||
@@ -1759,7 +1781,7 @@ public class JavaDocInfoGenerator {
|
||||
String paramName = trouser.getCanonicalText();
|
||||
Pair<PsiDocTag, InheritDocProvider<PsiDocTag>> parmTag = null;
|
||||
|
||||
for (PsiDocTag localTag : localTags) {
|
||||
for (PsiDocTag localTag : thrownTags) {
|
||||
PsiDocTagValue value = localTag.getValueElement();
|
||||
if (value != null) {
|
||||
String tagName = value.getText();
|
||||
@@ -1779,7 +1801,7 @@ public class JavaDocInfoGenerator {
|
||||
}
|
||||
else {
|
||||
try {
|
||||
PsiDocTag tag = JavaPsiFacade.getInstance(method.getProject()).getElementFactory().createDocTagFromText("@exception " + paramName);
|
||||
PsiDocTag tag = psiFacade.getElementFactory().createDocTagFromText("@exception " + paramName);
|
||||
collectedTags.addLast(Pair.create(tag, ourEmptyProvider));
|
||||
}
|
||||
catch (IncorrectOperationException e) {
|
||||
|
||||
@@ -705,6 +705,11 @@ public class ExceptionUtil {
|
||||
return InheritanceUtil.isInheritor(type, CommonClassNames.JAVA_LANG_RUNTIME_EXCEPTION) || InheritanceUtil.isInheritor(type, CommonClassNames.JAVA_LANG_ERROR);
|
||||
}
|
||||
|
||||
public static boolean isUncheckedException(@NotNull PsiClass psiClass) {
|
||||
return InheritanceUtil.isInheritor(psiClass, CommonClassNames.JAVA_LANG_RUNTIME_EXCEPTION) ||
|
||||
InheritanceUtil.isInheritor(psiClass, CommonClassNames.JAVA_LANG_ERROR);
|
||||
}
|
||||
|
||||
public static boolean isUncheckedExceptionOrSuperclass(@NotNull final PsiClassType type) {
|
||||
return isGeneralExceptionType(type) || isUncheckedException(type);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
<html><head><base href="placeholder"> <style type="text/css"> #error { background-color: #eeeeee; margin-bottom: 10px; } p { margin: 5px 0; } </style></head><body><small><b><a href="psi_element://java.util.Collection"><code>java.util.Collection</code></a></b></small><PRE>public abstract boolean <b>contains</b>(<a href="psi_element://java.lang.Object"><code>Object</code></a> o)</PRE>
|
||||
Returns <tt>true</tt> if this collection contains the specified
|
||||
element. More formally, returns <tt>true</tt> if and only if this
|
||||
collection contains at least one element <tt>e</tt> such that
|
||||
<tt>(o==null ? e==null : o.equals(e))</tt>.
|
||||
|
||||
<DD><DL><DT><b>Parameters:</b><DD><code>o</code> - element whose presence in this collection is to be tested. </DD></DL></DD><DD><DL><DT><b>Returns:</b><DD><tt>true</tt> if this collection contains the specified element </DD></DL></DD><DD><DL><DT><b>Throws:</b><DD><a href="psi_element://java.lang.ClassCastException"><code>ClassCastException</code></a> - if the type of the specified element is incompatible with this collection (optional). <DD><a href="psi_element://java.lang.NullPointerException"><code>NullPointerException</code></a> - if the specified element is null and this collection does not support null elements (optional).</DD></DL></DD></body></html>
|
||||
@@ -0,0 +1,13 @@
|
||||
interface I {
|
||||
/**
|
||||
* @throws NullPointerException blah-blah
|
||||
*/
|
||||
boolean contains(Object o) {}
|
||||
}
|
||||
interface My extends java.util.Collection, I {}
|
||||
class C {
|
||||
{
|
||||
My m = null;
|
||||
m.<caret>contains(null);
|
||||
}
|
||||
}
|
||||
@@ -401,6 +401,10 @@ public class JavaDocInfoGeneratorTest extends CodeInsightTestCase {
|
||||
doTestAtCaret();
|
||||
}
|
||||
|
||||
public void testDocumentationForUncheckedExceptionsInSupers() throws Exception {
|
||||
doTestAtCaret();
|
||||
}
|
||||
|
||||
public void testDumbMode() throws Exception {
|
||||
DumbServiceImpl.getInstance(myProject).setDumb(true);
|
||||
try {
|
||||
|
||||
Reference in New Issue
Block a user