Skip to content

GROOVY-11988: Add support for {@inheritDoc} in external JDK classes#2512

Open
daniellansun wants to merge 1 commit intomasterfrom
GROOVY-11988
Open

GROOVY-11988: Add support for {@inheritDoc} in external JDK classes#2512
daniellansun wants to merge 1 commit intomasterfrom
GROOVY-11988

Conversation

@daniellansun
Copy link
Copy Markdown
Contributor

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR implements GROOVY-11988 by extending groovydoc’s {@inheritDoc} expansion so it can resolve documentation from external JDK classes/interfaces (by reading the local JDK src.zip), and adds regression tests covering common JDK inheritance scenarios (e.g., Writer, Object.clone(), Map).

Changes:

  • Add ExternalJavadocSupport to parse JDK sources from src.zip, materialize external GroovyMethodDocs, and expand external {@inheritDoc} recursively with cache-session lifecycle management.
  • Update groovydoc rendering/inheritDoc resolution to better handle external owners and additional inline tags (e.g., {@linkplain}, {@index}) while rendering.
  • Add new tests and fixtures verifying external-JDK inheritDoc expansion in generated HTML and verifying cache session behavior.

Reviewed changes

Copilot reviewed 9 out of 9 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
subprojects/groovy-groovydoc/src/main/java/org/codehaus/groovy/tools/groovydoc/ExternalJavadocSupport.java New implementation to load/parse external JDK Javadoc from src.zip, expand {@inheritDoc}, and manage caching via sessions.
subprojects/groovy-groovydoc/src/main/java/org/codehaus/groovy/tools/groovydoc/ExternalGroovyClassDoc.java Enhance external class model (real superclass semantics, interfaces, modifiers, methods via ExternalJavadocSupport).
subprojects/groovy-groovydoc/src/main/java/org/codehaus/groovy/tools/groovydoc/GroovyDocTool.java Wrap render in an external-javadoc cache session so repeated lookups are efficient and then released.
subprojects/groovy-groovydoc/src/main/java/org/codehaus/groovy/tools/groovydoc/SimpleGroovyClassDoc.java Extend internal class resolution to attempt nested-class lookup paths.
subprojects/groovy-groovydoc/src/main/java/org/codehaus/groovy/tools/groovydoc/TagRenderer.java Extend known inline-tag handling and adjust inheritDoc rendering/method matching logic to support external sources.
subprojects/groovy-groovydoc/src/test/groovy/org/codehaus/groovy/tools/groovydoc/GroovyDocToolTest.java Add regression tests for external JDK inheritDoc expansion and cache lifecycle semantics.
subprojects/groovy-groovydoc/src/test/groovy/org/codehaus/groovy/tools/groovydoc/testfiles/JavaExtendsWriterInheritDoc.java Test fixture: {@inheritDoc} inherited from java.io.Writer.
subprojects/groovy-groovydoc/src/test/groovy/org/codehaus/groovy/tools/groovydoc/testfiles/JavaObjectCloneInheritDocChild.java Test fixture: {@inheritDoc} inherited from java.lang.Object#clone.
subprojects/groovy-groovydoc/src/test/groovy/org/codehaus/groovy/tools/groovydoc/testfiles/JavaImplementsMapInheritDoc.java Test fixture: {@inheritDoc} inherited from Map and Object methods.

Comment on lines 859 to +871
String targetClassName = null;
String nestedBaseName = baseName.replace('.', '$');
if (aliases.containsKey(baseName)) {
targetClassName = aliases.get(baseName);
} else if (baseName.contains(".")) {
int dot = baseName.indexOf('.');
String outerName = baseName.substring(0, dot);
String nestedSuffix = baseName.substring(dot).replace('.', '$');
if (importName.endsWith("/" + outerName)) {
targetClassName = importName + nestedSuffix;
} else if (importName.endsWith("/*")) {
targetClassName = importName.substring(0, importName.length() - 1) + nestedBaseName;
}
Comment on lines +900 to +901
String candidate = baseName.contains(".") ? baseName.replace('.', '$') : baseName;
return ((SimpleGroovyRootDoc)rootDoc).classNamedExact(pkg + candidate);
Comment on lines +905 to +910
if (rootDoc == null || fullPathName == null || !fullPathName.contains("$")) return null;
String nestedSuffix = baseName.replace('.', '$');
String current = fullPathName;
while (current.contains("$")) {
current = current.substring(0, current.lastIndexOf('$'));
GroovyClassDoc doc = ((SimpleGroovyRootDoc) rootDoc).classNamedExact(current + "$" + nestedSuffix);
Comment on lines 969 to +976
if (!(memberDoc instanceof GroovyMethodDoc thisMethod)) return null;
if (classDoc == null) return null;
if (classDoc == null) return "";
if (visited == null) visited = new HashSet<>();
if (!visited.add(thisMethod)) return ""; // cycle: suppress literal {@inheritDoc}

GroovyMethodDoc parent = findInheritedMethod(thisMethod, classDoc, new HashSet<>());
if (parent == null) return null;
if (parent instanceof SimpleGroovyMemberDoc parentMember
&& parentMember.belongsToClass instanceof SimpleGroovyClassDoc parentClassDoc) {
if (parent == null) return "";
if (parent instanceof SimpleGroovyMemberDoc parentMember) {
@codecov-commenter
Copy link
Copy Markdown

codecov-commenter commented May 4, 2026

Codecov Report

❌ Patch coverage is 61.34663% with 155 lines in your changes missing coverage. Please review.
✅ Project coverage is 67.3260%. Comparing base (36870fa) to head (1a2646c).
⚠️ Report is 1 commits behind head on master.

Files with missing lines Patch % Lines
...groovy/tools/groovydoc/ExternalJavadocSupport.java 65.6827% 52 Missing and 41 partials ⚠️
...g/codehaus/groovy/tools/groovydoc/TagRenderer.java 38.3333% 17 Missing and 20 partials ⚠️
...groovy/tools/groovydoc/ExternalGroovyClassDoc.java 39.3939% 18 Missing and 2 partials ⚠️
...s/groovy/tools/groovydoc/SimpleGroovyClassDoc.java 89.2857% 1 Missing and 2 partials ⚠️
...codehaus/groovy/tools/groovydoc/GroovyDocTool.java 77.7778% 1 Missing and 1 partial ⚠️
Additional details and impacted files

Impacted file tree graph

@@                Coverage Diff                 @@
##               master      #2512        +/-   ##
==================================================
- Coverage     67.3329%   67.3260%   -0.0069%     
- Complexity      32276      32358        +82     
==================================================
  Files            1490       1491         +1     
  Lines          125080     125436       +356     
  Branches        22525      22631       +106     
==================================================
+ Hits            84220      84451       +231     
- Misses          33535      33605        +70     
- Partials         7325       7380        +55     
Files with missing lines Coverage Δ
...codehaus/groovy/tools/groovydoc/GroovyDocTool.java 80.3279% <77.7778%> (+0.3279%) ⬆️
...s/groovy/tools/groovydoc/SimpleGroovyClassDoc.java 83.3984% <89.2857%> (+1.9170%) ⬆️
...groovy/tools/groovydoc/ExternalGroovyClassDoc.java 32.6087% <39.3939%> (+0.0786%) ⬆️
...g/codehaus/groovy/tools/groovydoc/TagRenderer.java 69.7466% <38.3333%> (-3.2437%) ⬇️
...groovy/tools/groovydoc/ExternalJavadocSupport.java 65.6827% <65.6827%> (ø)

... and 7 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants