diff --git a/org.eclipse.jdt.ls.core/src/org/eclipse/jdt/ls/core/internal/javadoc/JavadocContentAccess2.java b/org.eclipse.jdt.ls.core/src/org/eclipse/jdt/ls/core/internal/javadoc/JavadocContentAccess2.java index 3b48e8eee0..08454bffe3 100644 --- a/org.eclipse.jdt.ls.core/src/org/eclipse/jdt/ls/core/internal/javadoc/JavadocContentAccess2.java +++ b/org.eclipse.jdt.ls.core/src/org/eclipse/jdt/ls/core/internal/javadoc/JavadocContentAccess2.java @@ -166,8 +166,10 @@ private static void collectTagElements(String content, IJavaElement element, Tag while (!queue.isEmpty()) { ASTNode e = queue.pop(); if (e instanceof TagElement t) { - if ("@link".equals(t.getTagName()) || "@linkplain".equals(t.getTagName())) { + if (TagElement.TAG_LINK.equals(t.getTagName()) || TagElement.TAG_LINKPLAIN.equals(t.getTagName())) { collectLinkedTag(element, t, buf); + } else if (TagElement.TAG_CODE.equals(t.getTagName()) || TagElement.TAG_LITERAL.equals(t.getTagName())) { + collectCodeAndLiteralTag(element, t, buf); } else { collectTagElements(content, element, t, buf); } @@ -195,6 +197,41 @@ private static void collectTagElements(String content, IJavaElement element, Tag } } + private static void collectCodeAndLiteralTag(IJavaElement element, TagElement t, StringBuilder buf) { + if (t.fragments().size() > 0) { + try { + if (t.fragments().size() > 0) { + if (TagElement.TAG_CODE.equals(t.getTagName())) { + if (t.fragments().size() == 1) { + buf.append("`" + ((TextElement) t.fragments().get(0)).getText().strip() + "`"); + } else { + String code; + for (int i = 0; i < t.fragments().size(); i++) { + code = ((TextElement) t.fragments().get(i)).getText().strip(); + if (i == 0) { + buf.append("`" + code); + } else if (i == (t.fragments().size() - 1)) { + buf.append(code + "`"); + } else { + buf.append(code); + } + } + } + } else if (TagElement.TAG_LITERAL.equals(t.getTagName())) { + String code; + for (int i = 0; i < t.fragments().size(); i++) { + code = ((TextElement) t.fragments().get(i)).getText().strip(); + code = code.replaceAll("([<>*^&\\\\`\\[\\]])", "\\\\$1"); + buf.append(code); + } + } + } + } catch (Exception e) { + JavaManipulationPlugin.log(e); + } + } + } + private static void collectLinkedTag(IJavaElement element, TagElement t, StringBuilder buf) { @SuppressWarnings("unchecked") List children = t.fragments(); diff --git a/org.eclipse.jdt.ls.tests/src/org/eclipse/jdt/ls/core/internal/handlers/HoverHandlerTest.java b/org.eclipse.jdt.ls.tests/src/org/eclipse/jdt/ls/core/internal/handlers/HoverHandlerTest.java index b8c07c5e71..97f6a34df6 100644 --- a/org.eclipse.jdt.ls.tests/src/org/eclipse/jdt/ls/core/internal/handlers/HoverHandlerTest.java +++ b/org.eclipse.jdt.ls.tests/src/org/eclipse/jdt/ls/core/internal/handlers/HoverHandlerTest.java @@ -1050,4 +1050,118 @@ public class Meh {} actual = ResourceUtils.dos2Unix(actual); assertEquals(expectedJavadoc, actual, "Unexpected hover "); } + + @Test + public void testHoverMarkdownWithCodeTag_01() throws Exception { + String name = "java25"; + importProjects("eclipse/" + name); + IProject project = getProject(name); + IJavaProject javaProject = JavaCore.create(project); + IPackageFragmentRoot packageFragmentRoot = javaProject.getPackageFragmentRoot(project.getFolder("src/main/java")); + IPackageFragment pack1 = packageFragmentRoot.createPackageFragment("test", false, null); + StringBuilder buf = new StringBuilder(); + //@formatter:off + buf.append("package test;\n" + + "/// {@code List}\n" + + "public class Markdown{}\n"); + //@formatter:on + ICompilationUnit cu = pack1.createCompilationUnit("Test.java", buf.toString(), false, null); + Hover hover = getHover(cu, 2, 14); + assertNotNull(hover); + assertEquals(2, hover.getContents().getLeft().size()); + StringBuilder expectedJavadoc = new StringBuilder(); + //@formatter:off + expectedJavadoc.append("`List` "); + //@formatter:on + String actual = hover.getContents().getLeft().get(1).getLeft(); + actual = ResourceUtils.dos2Unix(actual); + assertEquals(expectedJavadoc.toString(), actual, "Unexpected hover "); + } + + @Test + public void testHoverMarkdownWithCodeTag_02() throws Exception { + String name = "java25"; + importProjects("eclipse/" + name); + IProject project = getProject(name); + IJavaProject javaProject = JavaCore.create(project); + IPackageFragmentRoot packageFragmentRoot = javaProject.getPackageFragmentRoot(project.getFolder("src/main/java")); + IPackageFragment pack1 = packageFragmentRoot.createPackageFragment("test", false, null); + StringBuilder buf = new StringBuilder(); + //@formatter:off + buf.append("package test;\n" + + "/// {@literal List <>*^&`[]}\n" + + "public class Markdown{}\n"); + //@formatter:on + ICompilationUnit cu = pack1.createCompilationUnit("Test.java", buf.toString(), false, null); + Hover hover = getHover(cu, 2, 14); + assertNotNull(hover); + assertEquals(2, hover.getContents().getLeft().size()); + StringBuilder expectedJavadoc = new StringBuilder(); + //@formatter:off + expectedJavadoc.append("List\\ \\<\\>\\*\\^\\&\\`\\[\\] "); + //@formatter:on + String actual = hover.getContents().getLeft().get(1).getLeft(); + actual = ResourceUtils.dos2Unix(actual); + assertEquals(expectedJavadoc.toString(), actual, "Unexpected hover "); + } + + @Test + public void testHoverMarkdownWithCodeTag_03() throws Exception { + String name = "java25"; + importProjects("eclipse/" + name); + IProject project = getProject(name); + IJavaProject javaProject = JavaCore.create(project); + IPackageFragmentRoot packageFragmentRoot = javaProject.getPackageFragmentRoot(project.getFolder("src/main/java")); + IPackageFragment pack1 = packageFragmentRoot.createPackageFragment("test", false, null); + StringBuilder buf = new StringBuilder(); + //@formatter:off + buf.append("package test;\n" + + "/// Here's some code {@code \n" + + "/// List list = List.of(\"Hello World!\");\n" + + "/// } \n" + + "/// that does something.\n" + + "public class Markdown{}\n"); + //@formatter:on + ICompilationUnit cu = pack1.createCompilationUnit("Test.java", buf.toString(), false, null); + Hover hover = getHover(cu, 5, 14); + assertNotNull(hover); + assertEquals(2, hover.getContents().getLeft().size()); + //@formatter:off + StringBuilder expectedJavadoc = new StringBuilder(); + expectedJavadoc.append("Here's some code `List list = List.of(\"Hello World!\");` that does something."); + //@formatter:on + String actual = hover.getContents().getLeft().get(1).getLeft(); + actual = ResourceUtils.dos2Unix(actual); + assertEquals(expectedJavadoc.toString(), actual, "Unexpected hover "); + } + + @Test + public void testHoverMarkdownWithCodeTag_04() throws Exception { + String name = "java25"; + importProjects("eclipse/" + name); + IProject project = getProject(name); + IJavaProject javaProject = JavaCore.create(project); + IPackageFragmentRoot packageFragmentRoot = javaProject.getPackageFragmentRoot(project.getFolder("src/main/java")); + IPackageFragment pack1 = packageFragmentRoot.createPackageFragment("test", false, null); + StringBuilder buf = new StringBuilder(); + //@formatter:off + buf.append("package test;\n" + + "/// Here's some code {@literal \n" + + "/// List list = List.of(\"Hello World!\");\n" + + "/// } \n" + + "/// that does something.\n" + + "public class Markdown{}\n"); + //@formatter:on + ICompilationUnit cu = pack1.createCompilationUnit("Test.java", buf.toString(), false, null); + Hover hover = getHover(cu, 5, 14); + assertNotNull(hover); + assertEquals(2, hover.getContents().getLeft().size()); + //@formatter:off + StringBuilder expectedJavadoc = new StringBuilder(); + expectedJavadoc.append("Here's some code List\\ list = List.of(\"Hello World!\");} that does something."); + //@formatter:on + String actual = hover.getContents().getLeft().get(1).getLeft(); + actual = ResourceUtils.dos2Unix(actual); + assertEquals(expectedJavadoc.toString(), actual, "Unexpected hover "); + } }