From 48dbc5e378b93103dd12d3013df1483b1942ec9f Mon Sep 17 00:00:00 2001 From: "Maxim.Mossienko" Date: Thu, 11 Sep 2014 12:00:32 +0200 Subject: [PATCH] IDEA-89136 Constants in annotationvalues in javadoc should be clickable also show enum constant value in documentation --- .../javadoc/JavaDocInfoGenerator.java | 43 ++++++++++++++++++- .../javadocIG/clickableFieldReference.html | 3 ++ .../javadocIG/clickableFieldReference.java | 7 +++ .../javadocIG/enumConstantOrdinal.html | 5 +-- .../javadocIG/enumConstantOrdinal_quick.html | 3 ++ .../javadoc/JavaDocInfoGeneratorTest.java | 32 +++++++++----- 6 files changed, 79 insertions(+), 14 deletions(-) create mode 100644 java/java-tests/testData/codeInsight/javadocIG/clickableFieldReference.html create mode 100644 java/java-tests/testData/codeInsight/javadocIG/clickableFieldReference.java create mode 100644 java/java-tests/testData/codeInsight/javadocIG/enumConstantOrdinal_quick.html diff --git a/java/java-psi-impl/src/com/intellij/codeInsight/javadoc/JavaDocInfoGenerator.java b/java/java-psi-impl/src/com/intellij/codeInsight/javadoc/JavaDocInfoGenerator.java index 38df39381ef4..adcc5fddd1ab 100644 --- a/java/java-psi-impl/src/com/intellij/codeInsight/javadoc/JavaDocInfoGenerator.java +++ b/java/java-psi-impl/src/com/intellij/codeInsight/javadoc/JavaDocInfoGenerator.java @@ -501,6 +501,7 @@ public class JavaDocInfoGenerator { buffer.append(""); buffer.append(field.getName()); appendInitializer(buffer, field); + enumConstantOrdinal(buffer, field, field.getContainingClass(), "\n"); buffer.append(""); } @@ -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); } diff --git a/java/java-tests/testData/codeInsight/javadocIG/clickableFieldReference.html b/java/java-tests/testData/codeInsight/javadocIG/clickableFieldReference.html new file mode 100644 index 000000000000..28602edf96e3 --- /dev/null +++ b/java/java-tests/testData/codeInsight/javadocIG/clickableFieldReference.html @@ -0,0 +1,3 @@ +
@Bar(Baz.CONST value = {Baz.CONST}) 
+class Foo
+extends Object
\ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/javadocIG/clickableFieldReference.java b/java/java-tests/testData/codeInsight/javadocIG/clickableFieldReference.java new file mode 100644 index 000000000000..3f46d7e1d7ec --- /dev/null +++ b/java/java-tests/testData/codeInsight/javadocIG/clickableFieldReference.java @@ -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; +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/javadocIG/enumConstantOrdinal.html b/java/java-tests/testData/codeInsight/javadocIG/enumConstantOrdinal.html index 11d610085775..613de9167782 100644 --- a/java/java-tests/testData/codeInsight/javadocIG/enumConstantOrdinal.html +++ b/java/java-tests/testData/codeInsight/javadocIG/enumConstantOrdinal.html @@ -1,3 +1,2 @@ -E - E A -Enum constant ordinal: 0 \ No newline at end of file + E
E A
+Enum constant ordinal: 0
\ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/javadocIG/enumConstantOrdinal_quick.html b/java/java-tests/testData/codeInsight/javadocIG/enumConstantOrdinal_quick.html new file mode 100644 index 000000000000..11d610085775 --- /dev/null +++ b/java/java-tests/testData/codeInsight/javadocIG/enumConstantOrdinal_quick.html @@ -0,0 +1,3 @@ +E + E A +Enum constant ordinal: 0 \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/javadoc/JavaDocInfoGeneratorTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/javadoc/JavaDocInfoGeneratorTest.java index 8bac921916d3..409ebcc681c1 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/javadoc/JavaDocInfoGeneratorTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/javadoc/JavaDocInfoGeneratorTest.java @@ -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 {