IDEA-89136 Constants in annotationvalues in javadoc should be clickable

also show enum constant value in documentation
This commit is contained in:
Maxim.Mossienko
2014-09-11 12:02:42 +02:00
parent e49b7f2494
commit 48dbc5e378
6 changed files with 79 additions and 14 deletions
@@ -501,6 +501,7 @@ public class JavaDocInfoGenerator {
buffer.append("<b>");
buffer.append(field.getName());
appendInitializer(buffer, field);
enumConstantOrdinal(buffer, field, field.getContainingClass(), "\n");
buffer.append("</b>");
}
@@ -754,7 +755,20 @@ public class JavaDocInfoGenerator {
}
final PsiAnnotationMemberValue value = pair.getValue();
if (value != null) {
buffer.append(XmlStringUtil.escapeString(value.getText()));
if (value instanceof PsiArrayInitializerMemberValue) {
buffer.append("{");
boolean firstMember = true;
for(PsiAnnotationMemberValue memberValue:((PsiArrayInitializerMemberValue)value).getInitializers()) {
if (!firstMember) buffer.append(",");
firstMember = false;
appendLinkOrText(buffer, owner, memberValue, generateLink);
}
buffer.append("}");
} else {
appendLinkOrText(buffer, owner, value, generateLink);
}
}
}
buffer.append(")");
@@ -778,6 +792,33 @@ public class JavaDocInfoGenerator {
}
}
private static void appendLinkOrText(StringBuilder buffer, PsiModifierListOwner owner, PsiAnnotationMemberValue memberValue, boolean generateLink) {
boolean linkGenerated = !generateLink;
if (!linkGenerated && memberValue instanceof PsiQualifiedReferenceElement) {
String text = ((PsiQualifiedReferenceElement)memberValue).getCanonicalText();
PsiElement resolve = ((PsiQualifiedReferenceElement)memberValue).resolve();
if (resolve instanceof PsiField) {
PsiField field = (PsiField)resolve;
PsiClass aClass = field.getContainingClass();
int startOfPropertyNamePosition = text.lastIndexOf('.');
if (startOfPropertyNamePosition != -1) {
text = text.substring(0, startOfPropertyNamePosition) + '#' + text.substring(startOfPropertyNamePosition + 1);
}
else {
if (aClass != null) text = aClass.getQualifiedName() + '#' + field.getName();
}
generateLink(buffer, text, aClass != null? aClass.getName() + '.' + field.getName():null, memberValue, false);
linkGenerated = true;
}
}
if (!linkGenerated) {
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);
}
@@ -0,0 +1,3 @@
<html><head> <style type="text/css"> #error { background-color: #eeeeee; margin-bottom: 10px; } p { margin: 5px 0; } </style></head><body><PRE>@<a href="psi_element://Bar"><code>Bar</code></a>(<a href="psi_element://Baz#CONST"><code>Baz.CONST</code></a>&nbsp;value = {<a href="psi_element://Baz#CONST"><code>Baz.CONST</code></a>})&nbsp;
class <b>Foo</b>
extends <a href="psi_element://java.lang.Object"><code>Object</code></a></PRE></body></html>
@@ -0,0 +1,7 @@
import java.lang.annotation.Documented;
class Text { Foo foo; }
@Bar(Baz.CONST, value = {Baz.CONST}) class Foo {}
@Documented @interface Bar {}
class Baz {
static int CONST;
}
@@ -1,3 +1,2 @@
E
E A
Enum constant ordinal: 0
<html><head> <style type="text/css"> #error { background-color: #eeeeee; margin-bottom: 10px; } p { margin: 5px 0; } </style></head><body><small><b><a href="psi_element://E"><code>E</code></a></b></small><PRE><a href="psi_element://E"><code>E</code></a> <b>A
Enum constant ordinal: 0</b></PRE></body></html>
@@ -0,0 +1,3 @@
E
E A
Enum constant ordinal: 0
@@ -99,11 +99,26 @@ public class JavaDocInfoGeneratorTest extends CodeInsightTestCase {
public void testEnumConstantOrdinal() throws Exception {
PsiClass psiClass = getTestClass();
PsiField field = psiClass.getFields() [0];
final File htmlPath = new File(JavaTestUtil.getJavaTestDataPath() + "/codeInsight/javadocIG/" + getTestName(true) + ".html");
String htmlText = FileUtil.loadFile(htmlPath);
String docInfo = new JavaDocumentationProvider().getQuickNavigateInfo(field, field);
String docInfo = new JavaDocumentationProvider().generateDoc(field, field);
assertNotNull(docInfo);
assertEquals(StringUtil.convertLineSeparators(htmlText.trim()), StringUtil.convertLineSeparators(docInfo.trim()));
assertEquals(exampleHtmlFileText(getTestName(true)), StringUtil.convertLineSeparators(docInfo.trim()));
docInfo = new JavaDocumentationProvider().getQuickNavigateInfo(field, field);
assertNotNull(docInfo);
assertEquals(exampleHtmlFileText(getTestName(true) + "_quick"), StringUtil.convertLineSeparators(docInfo.trim()));
}
public void testClickableFieldReference() throws Exception {
PsiClass aClass = getTestClass();
PsiTypeElement element = aClass.getFields()[0].getTypeElement();
String docInfo = new JavaDocumentationProvider().generateDoc(element.getInnermostComponentReferenceElement().resolve(), element);
assertNotNull(docInfo);
assertEquals(exampleHtmlFileText(getTestName(true)), StringUtil.convertLineSeparators(docInfo.trim()));
}
private static String exampleHtmlFileText(String name) throws IOException {
final File htmlPath = new File(JavaTestUtil.getJavaTestDataPath() + "/codeInsight/javadocIG/" + name + ".html");
return StringUtil.convertLineSeparators(FileUtil.loadFile(htmlPath).trim());
}
public void testClassTypeParamsPresentation() throws Exception {
@@ -111,11 +126,10 @@ public class JavaDocInfoGeneratorTest extends CodeInsightTestCase {
final PsiReferenceList extendsList = psiClass.getExtendsList();
final PsiJavaCodeReferenceElement referenceElement = extendsList.getReferenceElements()[0];
final PsiClass superClass = extendsList.getReferencedTypes()[0].resolve();
final File htmlPath = new File(JavaTestUtil.getJavaTestDataPath() + "/codeInsight/javadocIG/" + getTestName(true) + ".html");
String htmlText = FileUtil.loadFile(htmlPath);
String docInfo = new JavaDocumentationProvider().getQuickNavigateInfo(superClass, referenceElement);
assertNotNull(docInfo);
assertEquals(StringUtil.convertLineSeparators(htmlText.trim()), StringUtil.convertLineSeparators(docInfo.trim()));
assertEquals(exampleHtmlFileText(getTestName(true)), StringUtil.convertLineSeparators(docInfo.trim()));
}
private void doTestField() throws Exception {
@@ -136,11 +150,9 @@ public class JavaDocInfoGeneratorTest extends CodeInsightTestCase {
}
private void verifyJavaDoc(final PsiElement field) throws IOException {
final File htmlPath = new File(JavaTestUtil.getJavaTestDataPath() + "/codeInsight/javadocIG/" + getTestName(true) + ".html");
String htmlText = FileUtil.loadFile(htmlPath);
String docInfo = new JavaDocInfoGenerator(getProject(), field).generateDocInfo(null);
assertNotNull(docInfo);
assertEquals(StringUtil.convertLineSeparators(htmlText.trim()), StringUtil.convertLineSeparators(docInfo.trim()));
assertEquals(exampleHtmlFileText(getTestName(true)), StringUtil.convertLineSeparators(docInfo.trim()));
}
public void testPackageInfo() throws Exception {