mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
IDEA-169520 Flow annotations visible in Collections interface methods
This commit is contained in:
+1
-1
@@ -486,7 +486,7 @@ public class MethodParameterInfoHandler implements ParameterInfoHandlerWithTabAc
|
||||
if (element != null) {
|
||||
final PsiElement resolved = element.resolve();
|
||||
if (resolved instanceof PsiClass &&
|
||||
(!JavaDocInfoGenerator.isDocumentedAnnotationType(resolved) ||
|
||||
(!JavaDocInfoGenerator.isDocumentedAnnotationType((PsiClass)resolved) ||
|
||||
AnnotationTargetUtil.findAnnotationTarget((PsiClass)resolved, PsiAnnotation.TargetType.TYPE_USE) != null)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -55,6 +55,7 @@ import com.intellij.util.IncorrectOperationException;
|
||||
import com.intellij.util.ObjectUtils;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.xml.util.XmlStringUtil;
|
||||
import org.intellij.lang.annotations.Flow;
|
||||
import org.jdom.Document;
|
||||
import org.jdom.Element;
|
||||
import org.jdom.JDOMException;
|
||||
@@ -908,6 +909,8 @@ public class JavaDocInfoGenerator {
|
||||
final PsiJavaCodeReferenceElement nameReferenceElement = annotation.getNameReferenceElement();
|
||||
if (nameReferenceElement == null) continue;
|
||||
final PsiElement resolved = nameReferenceElement.resolve();
|
||||
if (isNonDocumentedAnnotation(annotation, resolved)) continue;
|
||||
|
||||
boolean inferred = AnnotationUtil.isInferredAnnotation(annotation);
|
||||
String qualifiedName = annotation.getQualifiedName();
|
||||
if (!(shownAnnotations.add(qualifiedName) || isRepeatableAnnotationType(resolved))) {
|
||||
@@ -917,50 +920,18 @@ public class JavaDocInfoGenerator {
|
||||
if (resolved instanceof PsiClass &&
|
||||
qualifiedName != null && JavaDocUtil.findReferenceTarget(owner.getManager(), qualifiedName, owner) != null) {
|
||||
final PsiClass annotationType = (PsiClass)resolved;
|
||||
if (isDocumentedAnnotationType(annotationType)) {
|
||||
if (inferred) buffer.append("<i>");
|
||||
final PsiClassType type = JavaPsiFacade.getInstance(manager.getProject()).getElementFactory().createType(annotationType, PsiSubstitutor.EMPTY);
|
||||
buffer.append("@");
|
||||
if (inferred && !generateLink) {
|
||||
buffer.append(type.getPresentableText());
|
||||
}
|
||||
else {
|
||||
generateType(buffer, type, owner, generateLink, useShortNames && !external);
|
||||
}
|
||||
final PsiNameValuePair[] attributes = annotation.getParameterList().getAttributes();
|
||||
if (attributes.length > 0) {
|
||||
buffer.append("(");
|
||||
boolean first = true;
|
||||
for (PsiNameValuePair pair : attributes) {
|
||||
if (!first) buffer.append(", ");
|
||||
first = false;
|
||||
final String name = pair.getName();
|
||||
if (name != null) {
|
||||
buffer.append(name);
|
||||
buffer.append(" = ");
|
||||
}
|
||||
final PsiAnnotationMemberValue value = pair.getValue();
|
||||
if (value != null) {
|
||||
if (value instanceof PsiArrayInitializerMemberValue) {
|
||||
buffer.append("{");
|
||||
boolean firstMember = true;
|
||||
for(PsiAnnotationMemberValue memberValue:((PsiArrayInitializerMemberValue)value).getInitializers()) {
|
||||
if (!firstMember) buffer.append(",");
|
||||
firstMember = false;
|
||||
appendLinkOrText(buffer, memberValue, generateLink);
|
||||
}
|
||||
buffer.append("}");
|
||||
}
|
||||
else {
|
||||
appendLinkOrText(buffer, value, generateLink);
|
||||
}
|
||||
}
|
||||
}
|
||||
buffer.append(")");
|
||||
}
|
||||
if (inferred) buffer.append("</i>");
|
||||
buffer.append(" ");
|
||||
if (inferred) buffer.append("<i>");
|
||||
final PsiClassType type = JavaPsiFacade.getInstance(manager.getProject()).getElementFactory().createType(annotationType, PsiSubstitutor.EMPTY);
|
||||
buffer.append("@");
|
||||
if (inferred && !generateLink) {
|
||||
buffer.append(type.getPresentableText());
|
||||
}
|
||||
else {
|
||||
generateType(buffer, type, owner, generateLink, useShortNames && !external);
|
||||
}
|
||||
generateAnnotationAttributes(buffer, generateLink, annotation);
|
||||
if (inferred) buffer.append("</i>");
|
||||
buffer.append(" ");
|
||||
}
|
||||
else if (external) {
|
||||
if (inferred) buffer.append("<i>");
|
||||
@@ -980,6 +951,45 @@ public class JavaDocInfoGenerator {
|
||||
}
|
||||
}
|
||||
|
||||
private static void generateAnnotationAttributes(StringBuilder buffer, boolean generateLink, PsiAnnotation annotation) {
|
||||
final PsiNameValuePair[] attributes = annotation.getParameterList().getAttributes();
|
||||
if (attributes.length > 0) {
|
||||
buffer.append("(");
|
||||
boolean first = true;
|
||||
for (PsiNameValuePair pair : attributes) {
|
||||
if (!first) buffer.append(", ");
|
||||
first = false;
|
||||
generateAnnotationAttribute(buffer, generateLink, pair);
|
||||
}
|
||||
buffer.append(")");
|
||||
}
|
||||
}
|
||||
|
||||
private static void generateAnnotationAttribute(StringBuilder buffer, boolean generateLink, PsiNameValuePair pair) {
|
||||
final String name = pair.getName();
|
||||
if (name != null) {
|
||||
buffer.append(name);
|
||||
buffer.append(" = ");
|
||||
}
|
||||
final PsiAnnotationMemberValue value = pair.getValue();
|
||||
if (value != null) {
|
||||
if (value instanceof PsiArrayInitializerMemberValue) {
|
||||
buffer.append("{");
|
||||
boolean firstMember = true;
|
||||
for(PsiAnnotationMemberValue memberValue:((PsiArrayInitializerMemberValue)value).getInitializers()) {
|
||||
if (!firstMember) buffer.append(",");
|
||||
firstMember = false;
|
||||
appendLinkOrText(buffer, memberValue, generateLink);
|
||||
}
|
||||
buffer.append("}");
|
||||
}
|
||||
else {
|
||||
appendLinkOrText(buffer, value, generateLink);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static void appendLinkOrText(StringBuilder buffer,
|
||||
PsiAnnotationMemberValue memberValue,
|
||||
boolean generateLink) {
|
||||
@@ -1006,8 +1016,18 @@ public class JavaDocInfoGenerator {
|
||||
buffer.append(XmlStringUtil.escapeString(memberValue.getText()));
|
||||
}
|
||||
|
||||
public static boolean isDocumentedAnnotationType(@Nullable PsiElement annotationType) {
|
||||
return annotationType instanceof PsiClass && AnnotationUtil.isAnnotated((PsiClass)annotationType, "java.lang.annotation.Documented", false);
|
||||
private static boolean isNonDocumentedAnnotation(@NotNull PsiAnnotation annotation, @Nullable PsiElement resolved) {
|
||||
return resolved instanceof PsiClass
|
||||
? !isDocumentedAnnotationType((PsiClass)resolved)
|
||||
: isKnownNonDocumented(annotation.getQualifiedName());
|
||||
}
|
||||
|
||||
private static boolean isKnownNonDocumented(String annoQName) {
|
||||
return Flow.class.getName().equals(annoQName);
|
||||
}
|
||||
|
||||
public static boolean isDocumentedAnnotationType(@NotNull PsiClass resolved) {
|
||||
return AnnotationUtil.isAnnotated(resolved, "java.lang.annotation.Documented", false);
|
||||
}
|
||||
|
||||
public static boolean isRepeatableAnnotationType(@Nullable PsiElement annotationType) {
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
<html><head><base href="placeholder"> <style type="text/css"> #error { background-color: #eeeeee; margin-bottom: 10px; } p { margin: 5px 0; } </style></head><body><PRE>class <b>Test</b>
|
||||
extends <a href="psi_element://java.lang.Object"><code>Object</code></a></PRE> <pre>abc</pre></body></html>
|
||||
@@ -1,4 +1,3 @@
|
||||
<html><head><base href="placeholder"> <style type="text/css"> #error { background-color: #eeeeee; margin-bottom: 10px; } p { margin: 5px 0; } </style></head><body><PRE>
|
||||
public void <b>foo</b>()</PRE><DD><DL><DT><b>Description copied from interface:</b> <a href="psi_element://Foo"><code>Foo</code></a><br>
|
||||
<html><head><base href="placeholder"> <style type="text/css"> #error { background-color: #eeeeee; margin-bottom: 10px; } p { margin: 5px 0; } </style></head><body><PRE>public void <b>foo</b>()</PRE><DD><DL><DT><b>Description copied from interface:</b> <a href="psi_element://Foo"><code>Foo</code></a><br>
|
||||
some javadoc
|
||||
</DD></DL></DD><DD><DL><DT><b>Specified by:</b><DD><a href="psi_element://Foo#foo()"><code>foo</code></a> in interface <a href="psi_element://Foo"><code>Foo</code></a></DD></DL></DD></body></html>
|
||||
@@ -1,2 +1 @@
|
||||
<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://Bar"><code>Bar</code></a></b></small><PRE>
|
||||
void <b>m</b>(int bar)</PRE><DD><DL><DT><b>Overrides:</b><DD><a href="psi_element://Foo#m(int)"><code>m</code></a> in class <a href="psi_element://Foo"><code>Foo</code></a></DD></DL></DD><DD><DL><DT><b>Parameters:</b><DD><code>bar</code> - description</DD></DL></DD></body></html>
|
||||
<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://Bar"><code>Bar</code></a></b></small><PRE>void <b>m</b>(int bar)</PRE><DD><DL><DT><b>Overrides:</b><DD><a href="psi_element://Foo#m(int)"><code>m</code></a> in class <a href="psi_element://Foo"><code>Foo</code></a></DD></DL></DD><DD><DL><DT><b>Parameters:</b><DD><code>bar</code> - description</DD></DL></DD></body></html>
|
||||
+1
-2
@@ -1,2 +1 @@
|
||||
<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://Bar"><code>Bar</code></a></b></small><PRE>
|
||||
<U> void <b>m</b>(U u)</PRE><DD><DL><DT><b>Overrides:</b><DD><a href="psi_element://Foo#m(java.lang.Object)"><code>m</code></a> in class <a href="psi_element://Foo"><code>Foo</code></a></DD></DL></DD><DD><DL><DT><b>Type parameters:</b><DD><code><U></code> - description</DD></DL></DD></body></html>
|
||||
<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://Bar"><code>Bar</code></a></b></small><PRE><U> void <b>m</b>(U u)</PRE><DD><DL><DT><b>Overrides:</b><DD><a href="psi_element://Foo#m(java.lang.Object)"><code>m</code></a> in class <a href="psi_element://Foo"><code>Foo</code></a></DD></DL></DD><DD><DL><DT><b>Type parameters:</b><DD><code><U></code> - description</DD></DL></DD></body></html>
|
||||
+27
-1
@@ -16,6 +16,7 @@
|
||||
package com.intellij.codeInsight.javadoc;
|
||||
|
||||
import com.intellij.JavaTestUtil;
|
||||
import com.intellij.codeInsight.AnnotationUtil;
|
||||
import com.intellij.codeInsight.CodeInsightTestCase;
|
||||
import com.intellij.codeInsight.JavaExternalDocumentationTest;
|
||||
import com.intellij.lang.java.JavaDocumentationProvider;
|
||||
@@ -23,6 +24,7 @@ import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.module.Module;
|
||||
import com.intellij.openapi.module.ModuleManager;
|
||||
import com.intellij.openapi.projectRoots.Sdk;
|
||||
import com.intellij.openapi.projectRoots.SdkModificator;
|
||||
import com.intellij.openapi.roots.ModuleRootModificationUtil;
|
||||
import com.intellij.openapi.roots.OrderRootType;
|
||||
import com.intellij.openapi.roots.libraries.Library;
|
||||
@@ -35,6 +37,8 @@ import com.intellij.psi.search.GlobalSearchScope;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.testFramework.IdeaTestUtil;
|
||||
import com.intellij.testFramework.PsiTestUtil;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import org.intellij.lang.annotations.Flow;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
@@ -349,7 +353,29 @@ public class JavaDocInfoGeneratorTest extends CodeInsightTestCase {
|
||||
useJava7();
|
||||
verifyJavaDoc(getTestClass());
|
||||
}
|
||||
|
||||
|
||||
public void testHideNonDocumentedFlowAnnotations() throws IOException {
|
||||
ModuleRootModificationUtil.setModuleSdk(myModule, removeAnnotationsJar(PsiTestUtil.addJdkAnnotations(IdeaTestUtil.getMockJdk17())));
|
||||
|
||||
PsiMethod mapPut = myJavaFacade.findClass(CommonClassNames.JAVA_UTIL_MAP, GlobalSearchScope.allScope(myProject))
|
||||
.findMethodsByName("put", false)[0];
|
||||
|
||||
PsiAnnotation annotation = AnnotationUtil.findAnnotation(mapPut, Flow.class.getName());
|
||||
assertNotNull(annotation);
|
||||
assertNull(annotation.getNameReferenceElement().resolve());
|
||||
|
||||
String doc = JavaDocumentationProvider.generateExternalJavadoc(mapPut);
|
||||
assertFalse(doc, doc.contains("Flow"));
|
||||
}
|
||||
|
||||
private static Sdk removeAnnotationsJar(Sdk sdk) {
|
||||
SdkModificator modificator = sdk.getSdkModificator();
|
||||
VirtualFile annotationsJar = ContainerUtil.find(modificator.getRoots(OrderRootType.CLASSES), r -> r.getName().contains("annotations"));
|
||||
modificator.removeRoot(annotationsJar, OrderRootType.CLASSES);
|
||||
modificator.commitChanges();
|
||||
return sdk;
|
||||
}
|
||||
|
||||
public void testMatchingParameterNameFromParent() throws Exception {
|
||||
configureByFile();
|
||||
PsiClass psiClass = ((PsiJavaFile)myFile).getClasses()[1];
|
||||
|
||||
Reference in New Issue
Block a user