From b5ba8d0e3af729675677ef5b7e97b1650376d5b9 Mon Sep 17 00:00:00 2001
From: Jeff Johnston
Date: Fri, 7 Aug 2026 16:31:44 -0400
Subject: [PATCH] Fix overridden method inherited javadoc when markdown is used
- fix CoreJavadocAccess.javadoc2HTML to check if we have the default
rawjavadoc string and if we can inherit javadoc, if the overridden
method has markdown javadoc, then reset the rawjavadoc to the
default markdown string so that the markdown processors will be
used
- add newline after fetching main description in case we have
a markdown code block
- add new test to MarkdownCommentTests
- fixes #3101
---
.../internal/javadoc/CoreJavadocAccess.java | 36 ++++++++++++++++-
.../javadoc/CoreJavadocAccessImpl.java | 2 +-
.../ui/tests/hover/MarkdownCommentTests.java | 40 ++++++++++++++++++-
3 files changed, 73 insertions(+), 5 deletions(-)
diff --git a/org.eclipse.jdt.core.manipulation/common/org/eclipse/jdt/core/manipulation/internal/javadoc/CoreJavadocAccess.java b/org.eclipse.jdt.core.manipulation/common/org/eclipse/jdt/core/manipulation/internal/javadoc/CoreJavadocAccess.java
index 50038778607..472d6bd306e 100644
--- a/org.eclipse.jdt.core.manipulation/common/org/eclipse/jdt/core/manipulation/internal/javadoc/CoreJavadocAccess.java
+++ b/org.eclipse.jdt.core.manipulation/common/org/eclipse/jdt/core/manipulation/internal/javadoc/CoreJavadocAccess.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2008, 2023 IBM Corporation and others.
+ * Copyright (c) 2008, 2026 IBM Corporation and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
@@ -433,7 +433,39 @@ protected String javadoc2HTML(IMember member, IJavaElement element, String rawJa
}
if (CoreJavadocContentAccessUtility.canInheritJavadoc(member)) {
- IMethod method= (IMethod) member;
+ IMethod method= (IMethod)member;
+ IType declaringType= method.getDeclaringType();
+
+ IMethod overridden= null;
+ if (rawJavadoc.equals("/***/")) { //$NON-NLS-1$
+ try {
+ // we have assumed we have old-style Javadoc...check if
+ // we have an overridden method with Javadoc where we can check if
+ // it is markdown in which case, update rawJavadoc string and
+ // recalculate javadoc based on using a markdown processor
+ if (!method.isConstructor()) {
+ ITypeHierarchy hierarchy= SuperTypeHierarchyCache.getTypeHierarchy(declaringType);
+ MethodOverrideTester tester= new MethodOverrideTester(declaringType, hierarchy);
+ overridden= tester.findOverriddenMethod(method, true);
+ }
+ if (overridden != null) {
+ IBuffer buf= overridden.getOpenable().getBuffer();
+ if (buf != null) {
+ ISourceRange javadocRange= overridden.getJavadocRange();
+ if (javadocRange != null) {
+ String javadocStart= buf.getText(javadocRange.getOffset(), 3);
+ if (javadocStart.equals("///")) { //$NON-NLS-1$
+ rawJavadoc= "///\n"; //$NON-NLS-1$
+ javadoc= CoreJavadocContentAccessUtility.getJavadocNode(member, rawJavadoc);
+ }
+ }
+ }
+ }
+ } catch (JavaModelException e2) {
+ JavaManipulationPlugin.log(e2);
+ }
+ }
+
return this.fFactory.createJavadocAccess(element, javadoc, rawJavadoc, new JavadocLookup(method.getDeclaringType(), this.fFactory)).toHTML();
}
return this.fFactory.createJavadocAccess(element, javadoc, rawJavadoc, null).toHTML();
diff --git a/org.eclipse.jdt.core.manipulation/common/org/eclipse/jdt/core/manipulation/internal/javadoc/CoreJavadocAccessImpl.java b/org.eclipse.jdt.core.manipulation/common/org/eclipse/jdt/core/manipulation/internal/javadoc/CoreJavadocAccessImpl.java
index ef6536469a4..4b714fc20ef 100644
--- a/org.eclipse.jdt.core.manipulation/common/org/eclipse/jdt/core/manipulation/internal/javadoc/CoreJavadocAccessImpl.java
+++ b/org.eclipse.jdt.core.manipulation/common/org/eclipse/jdt/core/manipulation/internal/javadoc/CoreJavadocAccessImpl.java
@@ -578,7 +578,7 @@ public CharSequence getMainDescription() {
fBuf= null;
}
- return fMainDescription.length() > 0 ? fMainDescription : null;
+ return fMainDescription.length() > 0 ? fMainDescription.append("\n") : null; //$NON-NLS-1$
}
@Override
diff --git a/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/hover/MarkdownCommentTests.java b/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/hover/MarkdownCommentTests.java
index bd2e9b6fa69..25f0019d734 100644
--- a/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/hover/MarkdownCommentTests.java
+++ b/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/hover/MarkdownCommentTests.java
@@ -16,6 +16,7 @@
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
import static org.junit.jupiter.api.Assertions.fail;
import java.net.URI;
@@ -505,8 +506,8 @@ public void m(int i) {}
String superURI= makeEncodedClassUri("p", "Spec03Tags", "Super");
String superMURI= makeEncodedMethodUri(true, "p", "Spec03Tags", "Super","m", "I");
String expectedContent= """
- super doc
- In addition, this methods calls wait().
+ super doc
+ In addition, this methods calls wait().
- Parameters:
- i the index
"""
.replace("METHOD_URI", waitURI)
@@ -1114,4 +1115,39 @@ public class Markdown {}
assertEquals("sequence doesn't match", expectedContent, actualSnippet);
}
+ @Test
+ public void testInheritedMethod() throws CoreException {
+ String source= """
+ public class Base {
+ /// ## Title
+ /// *Some* `formatted` {@code text}
+ /// ```
+ /// block
+ /// ```
+ ///
+ void m() {}
+
+ class A1 extends Base {
+ @Override
+ void m() {}
+ }
+ }
+ """;
+ ICompilationUnit cu= getWorkingCopy("/TestSetupProject/src/p/Base.java", source, null);
+ assertNotNull("Base.java", cu);
+
+ String expectedContent= """
+ Some formatted text
+
+ block
+
+
+ """;
+ IType type0= cu.getType("Base");
+ IType type= type0.getType("A1");
+ IMethod method= type.getMethods()[0];
+ String actualHtmlContent= getHoverHtmlContent(cu, method);
+ assertTrue("Doesn't contain expected content", actualHtmlContent.contains(expectedContent));
+ }
+
}