From 1d6f2daa8d789548ea2d9f5199be865149b683b9 Mon Sep 17 00:00:00 2001 From: Dmitry Batrak Date: Thu, 29 Sep 2016 10:57:29 +0300 Subject: [PATCH] IDEA-161410 Quick Documentation: double opening angle brackets are printed as single brackets --- .../lang/java/JavaDocumentationProvider.java | 13 ++++++- .../codeInsight/javadocIG/doubleLt.html | 3 ++ .../codeInsight/javadocIG/doubleLt.java | 4 +++ .../javadoc/JavaDocInfoGeneratorTest.java | 16 +++++++-- .../PlatformDocumentationUtil.java | 34 +++---------------- 5 files changed, 37 insertions(+), 33 deletions(-) create mode 100644 java/java-tests/testData/codeInsight/javadocIG/doubleLt.html create mode 100644 java/java-tests/testData/codeInsight/javadocIG/doubleLt.java diff --git a/java/java-impl/src/com/intellij/lang/java/JavaDocumentationProvider.java b/java/java-impl/src/com/intellij/lang/java/JavaDocumentationProvider.java index e8687987042c..a88239d002fa 100644 --- a/java/java-impl/src/com/intellij/lang/java/JavaDocumentationProvider.java +++ b/java/java-impl/src/com/intellij/lang/java/JavaDocumentationProvider.java @@ -549,13 +549,24 @@ public class JavaDocumentationProvider extends DocumentationProviderEx implement @Nullable public static String generateExternalJavadoc(@NotNull final PsiElement element) { + List docURLs = getExternalJavaDocUrl(element); + return generateExternalJavadoc(element, docURLs); + } + + @Nullable + public static String generateExternalJavadoc(@NotNull final PsiElement element, @Nullable List docURLs) { final JavaDocInfoGenerator javaDocInfoGenerator = JavaDocInfoGeneratorFactory.create(element.getProject(), element); - return generateExternalJavadoc(element, javaDocInfoGenerator); + return generateExternalJavadoc(javaDocInfoGenerator, docURLs); } @Nullable public static String generateExternalJavadoc(@NotNull final PsiElement element, @NotNull JavaDocInfoGenerator generator) { final List docURLs = getExternalJavaDocUrl(element); + return generateExternalJavadoc(generator, docURLs); + } + + @Nullable + private static String generateExternalJavadoc(@NotNull JavaDocInfoGenerator generator, @Nullable List docURLs) { return JavaDocExternalFilter.filterInternalDocInfo(generator.generateDocInfo(docURLs)); } diff --git a/java/java-tests/testData/codeInsight/javadocIG/doubleLt.html b/java/java-tests/testData/codeInsight/javadocIG/doubleLt.html new file mode 100644 index 000000000000..91861a2aca53 --- /dev/null +++ b/java/java-tests/testData/codeInsight/javadocIG/doubleLt.html @@ -0,0 +1,3 @@ +
class C
+extends Object
+ a << b \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/javadocIG/doubleLt.java b/java/java-tests/testData/codeInsight/javadocIG/doubleLt.java new file mode 100644 index 000000000000..7c30bf471f93 --- /dev/null +++ b/java/java-tests/testData/codeInsight/javadocIG/doubleLt.java @@ -0,0 +1,4 @@ +/** + * a << b + */ +class C {} \ 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 5ea7abfd4543..07eb77bbd6e3 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/javadoc/JavaDocInfoGeneratorTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/javadoc/JavaDocInfoGeneratorTest.java @@ -176,6 +176,10 @@ public class JavaDocInfoGeneratorTest extends CodeInsightTestCase { doTestField(); } + public void testDoubleLt() throws Exception { + doTestClass(); + } + public void testEnumConstantOrdinal() throws Exception { PsiClass psiClass = getTestClass(); PsiField field = psiClass.getFields() [0]; @@ -224,6 +228,11 @@ public class JavaDocInfoGeneratorTest extends CodeInsightTestCase { doTestLambdaParameter(); } + private void doTestClass() throws Exception { + PsiClass psiClass = getTestClass(); + verifyJavaDoc(psiClass); + } + private void doTestField() throws Exception { PsiClass psiClass = getTestClass(); PsiField field = psiClass.getFields() [0]; @@ -253,7 +262,7 @@ public class JavaDocInfoGeneratorTest extends CodeInsightTestCase { } private void verifyJavaDoc(final PsiElement field, List docUrls) throws IOException { - String docInfo = JavaDocInfoGeneratorFactory.create(getProject(), field).generateDocInfo(docUrls); + String docInfo = JavaDocumentationProvider.generateExternalJavadoc(field, docUrls); assertNotNull(docInfo); assertEquals(exampleHtmlFileText(getTestName(true)), replaceEnvironmentDependentContent(docInfo)); } @@ -262,7 +271,8 @@ public class JavaDocInfoGeneratorTest extends CodeInsightTestCase { final String path = JavaTestUtil.getJavaTestDataPath() + TEST_DATA_FOLDER; final String packageInfo = path + getTestName(true); PsiTestUtil.createTestProjectStructure(myProject, myModule, path, myFilesToDelete); - final String info = JavaDocInfoGeneratorFactory.create(getProject(), JavaPsiFacade.getInstance(getProject()).findPackage(getTestName(true))).generateDocInfo(null); + PsiPackage psiPackage = JavaPsiFacade.getInstance(getProject()).findPackage(getTestName(true)); + final String info = JavaDocumentationProvider.generateExternalJavadoc(psiPackage, (List)null); String htmlText = FileUtil.loadFile(new File(packageInfo + File.separator + "packageInfo.html")); assertNotNull(info); assertEquals(StringUtil.convertLineSeparators(htmlText.trim()), replaceEnvironmentDependentContent(info)); @@ -307,7 +317,7 @@ public class JavaDocInfoGeneratorTest extends CodeInsightTestCase { private void verifyJavadocFor(String className) throws IOException { PsiClass psiClass = JavaPsiFacade.getInstance(myProject).findClass(className, GlobalSearchScope.allScope(myProject)); assertNotNull(psiClass); - String doc = JavaDocInfoGeneratorFactory.create(myProject, psiClass).generateDocInfo(null); + String doc = JavaDocumentationProvider.generateExternalJavadoc(psiClass, (List)null); assertNotNull(doc); PsiDirectory dir = (PsiDirectory)psiClass.getParent().getParent(); PsiFile htmlFile = dir.findFile(psiClass.getName() + ".html"); diff --git a/platform/core-impl/src/com/intellij/codeInsight/documentation/PlatformDocumentationUtil.java b/platform/core-impl/src/com/intellij/codeInsight/documentation/PlatformDocumentationUtil.java index 895aca00ef71..4dcc0ed67262 100644 --- a/platform/core-impl/src/com/intellij/codeInsight/documentation/PlatformDocumentationUtil.java +++ b/platform/core-impl/src/com/intellij/codeInsight/documentation/PlatformDocumentationUtil.java @@ -25,17 +25,13 @@ import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.util.LinkedList; import java.util.List; -import java.util.Locale; -import java.util.regex.Matcher; import java.util.regex.Pattern; -import java.util.regex.PatternSyntaxException; public class PlatformDocumentationUtil { private static final Logger LOG = Logger.getInstance("#com.intellij.codeInsight.documentation.PlatformDocumentationUtil"); - private static final @NonNls Pattern ourLtFixupPattern = Pattern.compile("<([^/^\\w^!])"); + private static final @NonNls Pattern ourLtFixupPattern = Pattern.compile("<(?=[^/!\\p{Alpha}])"); private static final @NonNls Pattern ourToQuote = Pattern.compile("[\\\\\\.\\^\\$\\?\\*\\+\\|\\)\\}\\]\\{\\(\\[]"); private static final @NonNls String LT_ENTITY = "<"; @@ -76,30 +72,10 @@ public class PlatformDocumentationUtil { return x; } + /** + * Updates HTML contents for display in JEditorPane, which treats invalid HTML somewhat differently than popular browsers. + */ public static String fixupText(@NotNull CharSequence docText) { - Matcher fixupMatcher = ourLtFixupPattern.matcher(docText); - LinkedList secondSymbols = new LinkedList(); - - while (fixupMatcher.find()) { - String s = fixupMatcher.group(1); - - //[db] that's workaround to avoid internal bug - if (!s.equals("\\") && !secondSymbols.contains(s)) { - secondSymbols.addFirst(s); - } - } - - for (String s : secondSymbols) { - String pattern = "<" + quote(s); - - try { - docText = Pattern.compile(pattern).matcher(docText).replaceAll(LT_ENTITY + pattern); - } - catch (PatternSyntaxException e) { - LOG.error("Pattern syntax exception on " + pattern); - } - } - - return docText.toString(); + return ourLtFixupPattern.matcher(docText).replaceAll(LT_ENTITY); } }