Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

JDK-8263507: Improve structure of package summary pages #3413

Closed
wants to merge 8 commits into from

Conversation

hns
Copy link
Member

@hns hns commented Apr 9, 2021

This adds a feature to add sub-navigation links to the package summary page, but ended up more like a refactoring of the code to generate sub-navigation links. The reason for this is that generation of these links was highly idiosyncratic. Every writer class that wanted to create sub-nav links deposited something of itself in the Navigation instance which was then responsible for generating these links. The new code introduces a Navigation.SubNavLinks interface that allows writers to provide a list of links into their page content.

As for the new feature in the package summary page itself, I chose an approach that is a bit different from the one we use for other types of pages. Instead of displaying the inactive label instead of the link when a section is not present on the page, only the active links are displayed. The reason for this is that the package summary page contains so many potential summary tables that the sub-nav area gets quite crowded if they are all shown. Just showing the actually present pieces looked better to me.

Like in other sub-nav sections, the link labels sometimes use abbreviated terms such as "RELATED" instead of "RELATED PACKAGES" and "ENUMS" instead of "ENUM CLASSES". The full list of potential package sub-nav links is as follows:

Package: Description | Related | Interfaces | Classes | Enums | Records | Exceptions | Errors | Annotations

An important implementation note is that I moved the code to compute package summary contents from PackageSummaryBuilder to PackageWriterImpl. The reason for this is that the contents are required to determine which links to create, and I didn't want to re-compute this information that was previously computed on the fly in the builder class. The various summary items are now stored in collection fields in the writer class.

I have tried to add all the new properties and constants in a sensible place, which usually means alphabetic order within the sub-group of related entries.

I chose to keep the markup structure of the package summary page mostly unchanged, adding only id attributes to the existing <li> elements for each summary table. I decided against adding class attributes as well as it seems very unlikely to me that somebody would want to apply different styles to the various summary tables. Even without them, it could be done using the ids.


Progress

  • Change must not contain extraneous whitespace
  • Commit message must refer to an issue
  • Change must be properly reviewed

Issue

  • JDK-8263507: Improve structure of package summary pages

Reviewers

Reviewing

Using git

Checkout this PR locally:
$ git fetch https://git.openjdk.java.net/jdk pull/3413/head:pull/3413
$ git checkout pull/3413

Update a local copy of the PR:
$ git checkout pull/3413
$ git pull https://git.openjdk.java.net/jdk pull/3413/head

Using Skara CLI tools

Checkout this PR locally:
$ git pr checkout 3413

View PR using the GUI difftool:
$ git pr show -t 3413

Using diff file

Download this PR as a diff file:
https://git.openjdk.java.net/jdk/pull/3413.diff

@bridgekeeper
Copy link

@bridgekeeper bridgekeeper bot commented Apr 9, 2021

👋 Welcome back hannesw! A progress list of the required criteria for merging this PR into master will be added to the body of your pull request. There are additional pull request commands available for use with this pull request.

@openjdk
Copy link

@openjdk openjdk bot commented Apr 9, 2021

@hns The following label will be automatically applied to this pull request:

  • javadoc

When this pull request is ready to be reviewed, an "RFR" email will be sent to the corresponding mailing list. If you would like to change these labels, use the /label pull request command.

@openjdk openjdk bot added the javadoc label Apr 9, 2021
@hns hns marked this pull request as ready for review Apr 9, 2021
@openjdk openjdk bot added the rfr label Apr 9, 2021
@mlbridge
Copy link

@mlbridge mlbridge bot commented Apr 9, 2021

Webrevs

@mlbridge
Copy link

@mlbridge mlbridge bot commented Apr 9, 2021

Mailing list message from Jonathan Gibbons on javadoc-dev:

Hannes,

Reading your email, and the comments about the number of tables, reminds
me of the suggestion to merge most of the tables (all those for
different kinds of classes and interfaces) into a single tabbed table,
as is now becoming more prevalent through the rest of the output.? This
would simplify the package summary page to two(?) tables, one for
"related packages" (no tabs) and one for "classes and interfaces" (with
tabs for the kind)

This is not meant to invalidate the general work you have done to
improve the code in Navigation, but it might simplify the use of the new
code.? The package sub-nav would have 3(?) entries, for Description,
Related, Classes-and-Interfaces

-- Jon

On 4/9/21 7:29 AM, Hannes Walln?fer wrote:

@mlbridge
Copy link

@mlbridge mlbridge bot commented Apr 9, 2021

Mailing list message from Hannes Wallnoefer on javadoc-dev:

Am 09.04.2021 um 17:22 schrieb Jonathan Gibbons <jonathan.gibbons at oracle.com>:

Hannes,

Reading your email, and the comments about the number of tables, reminds me of the suggestion to merge most of the tables (all those for different kinds of classes and interfaces) into a single tabbed table, as is now becoming more prevalent through the rest of the output. This would simplify the package summary page to two(?) tables, one for "related packages" (no tabs) and one for "classes and interfaces" (with tabs for the kind)

This is not meant to invalidate the general work you have done to improve the code in Navigation, but it might simplify the use of the new code. The package sub-nav would have 3(?) entries, for Description, Related, Classes-and-Interfaces

Excellent idea! I wonder how this didn?t occur to me while working on the code. I?m not worried about the work I?ve done, as it will only reduce the number of links/ids.

Should this be done as part of this change, or filed as separate issue?

Hannes

-- Jon

On 4/9/21 7:29 AM, Hannes Walln?fer wrote:

@mlbridge
Copy link

@mlbridge mlbridge bot commented Apr 10, 2021

Mailing list message from Jonathan Gibbons on javadoc-dev:

On 4/9/21 12:59 PM, Hannes Wallnoefer wrote:

Am 09.04.2021 um 17:22 schrieb Jonathan Gibbons <jonathan.gibbons at oracle.com>:

Hannes,

Reading your email, and the comments about the number of tables, reminds me of the suggestion to merge most of the tables (all those for different kinds of classes and interfaces) into a single tabbed table, as is now becoming more prevalent through the rest of the output. This would simplify the package summary page to two(?) tables, one for "related packages" (no tabs) and one for "classes and interfaces" (with tabs for the kind)

This is not meant to invalidate the general work you have done to improve the code in Navigation, but it might simplify the use of the new code. The package sub-nav would have 3(?) entries, for Description, Related, Classes-and-Interfaces

Excellent idea! I wonder how this didn?t occur to me while working on the code. I?m not worried about the work I?ve done, as it will only reduce the number of links/ids.

Should this be done as part of this change, or filed as separate issue?

I think that's your call.

I think there are 2 JBS issues, but you could do a single PR for both,
if that would be easier.

As two issues, maybe it would make sense to do the tabbed table first,
followed by the subnav work, since that avoids an interim step with lots
of links in the subnav.

-- Jon

Hannes

-- Jon

On 4/9/21 7:29 AM, Hannes Walln?fer wrote:

@mlbridge
Copy link

@mlbridge mlbridge bot commented Apr 10, 2021

Mailing list message from Jonathan Gibbons on javadoc-dev:

On 4/9/21 12:59 PM, Hannes Wallnoefer wrote:

Am 09.04.2021 um 17:22 schrieb Jonathan Gibbons <jonathan.gibbons at oracle.com>:

Hannes,

Reading your email, and the comments about the number of tables, reminds me of the suggestion to merge most of the tables (all those for different kinds of classes and interfaces) into a single tabbed table, as is now becoming more prevalent through the rest of the output. This would simplify the package summary page to two(?) tables, one for "related packages" (no tabs) and one for "classes and interfaces" (with tabs for the kind)

This is not meant to invalidate the general work you have done to improve the code in Navigation, but it might simplify the use of the new code. The package sub-nav would have 3(?) entries, for Description, Related, Classes-and-Interfaces

Excellent idea! I wonder how this didn?t occur to me while working on the code. I?m not worried about the work I?ve done, as it will only reduce the number of links/ids.

I see we already have a similar table in the All Classes page. Looking
at that page I would suggest the following:

* Change the page heading to "All Classes and Interfaces"
* Change the first tab from "All Classes" to "All"
* Drop the word "Summary" from the other tabs
* Maybe pluralize all the tab names

-- Jon

Should this be done as part of this change, or filed as separate issue?

Hannes

-- Jon

On 4/9/21 7:29 AM, Hannes Walln?fer wrote:

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.java.net/pipermail/javadoc-dev/attachments/20210410/13873030/attachment-0001.htm>

@mlbridge
Copy link

@mlbridge mlbridge bot commented Apr 12, 2021

Mailing list message from Hannes Wallnoefer on javadoc-dev:

I have imlemented the tabbed classes and interfaces table and playing around with the wording.

It looks like dropping the word ?Summary? would give us enough space to actually expand the first ?All Classes? tab to ?All Classes and Interfaces?, which I find more meaningful and correct. That is even with adding a ?Record Classes? tab which is currently missing on the ?All Classes? index page.

Below is.a screenshot of how that would look like:

[cid:CAA503F9-C160-4CA0-9439-2A5258DDD406 at fritz.box]

I would also suggest to use the same wording for the tabs on the ?All Classes? index page and the package summary pages, as I don?t see why they should be different.

Hannes

Am 10.04.2021 um 17:55 schrieb Jonathan Gibbons <jonathan.gibbons at oracle.com<mailto:jonathan.gibbons at oracle.com>>:

I see we already have a similar table in the All Classes page. Looking at that page I would suggest the following:

? Change the page heading to "All Classes and Interfaces"
? Change the first tab from "All Classes" to "All"
? Drop the word "Summary" from the other tabs
? Maybe pluralize all the tab names
-- Jon

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.java.net/pipermail/javadoc-dev/attachments/20210412/8f2341bc/attachment-0001.htm>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: PastedGraphic-1.png
Type: image/png
Size: 39044 bytes
Desc: PastedGraphic-1.png
URL: <https://mail.openjdk.java.net/pipermail/javadoc-dev/attachments/20210412/8f2341bc/PastedGraphic-1-0001.png>

@mlbridge
Copy link

@mlbridge mlbridge bot commented Apr 13, 2021

Mailing list message from Jonathan Gibbons on javadoc-dev:

Looks good.

Agreed that the terminology and appearance should be the same on the
"All Classes" page as on a package page.

If space becomes an issue, I think the first tab could be reduced to
"All" provided there is a suitable heading above the table, such as "All
Classes and Interfaces" /"Classes and Interfaces in Package ..."
although even there, you could drop "in Package ..." given the context
of the package page.

Agreed that "All Classes" is less than ideal. It should either be "All
Classes and Interfaces" or just "All".

Just asking: does the "Classes" tab refer to "all classes, including
enum classes, record classes, exceptions and errors", or "all classes
except enum classes, record classes, exceptions and errors" ?

-- jon

On 4/12/21 8:59 AM, Hannes Wallnoefer wrote:

I have imlemented the tabbed classes and interfaces table and playing
around with the wording.

It looks like dropping the word ?Summary? would give us enough space
to actually expand the first ?All Classes? tab to ?All Classes and
Interfaces?, which I find more meaningful and correct. That is even
with adding a ?Record Classes? tab which is currently missing on the
?All Classes? index page.

Below is.a screenshot of how that would look like:

I would also suggest to use the same wording for the tabs on the ?All
Classes? index page and the package summary pages, as I don?t see why
they should be different.

Hannes

Am 10.04.2021 um 17:55 schrieb Jonathan Gibbons
<jonathan.gibbons at oracle.com <mailto:jonathan.gibbons at oracle.com>>:

I see we already have a similar table in the All Classes
page.??Looking at that page I would suggest the following:

? Change the page heading to "All Classes and Interfaces"
? Change the first tab from "All Classes" to "All"
? Drop the word "Summary" from the other tabs
? Maybe pluralize all the tab names
-- Jon

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.java.net/pipermail/javadoc-dev/attachments/20210412/b6a97086/attachment-0001.htm>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: PastedGraphic-1.png
Type: image/png
Size: 39044 bytes
Desc: not available
URL: <https://mail.openjdk.java.net/pipermail/javadoc-dev/attachments/20210412/b6a97086/PastedGraphic-1-0001.png>

@mlbridge
Copy link

@mlbridge mlbridge bot commented Apr 13, 2021

Mailing list message from Hannes Wallnoefer on javadoc-dev:

Am 13.04.2021 um 07:22 schrieb Jonathan Gibbons <jonathan.gibbons at oracle.com>:

Just asking: does the "Classes" tab refer to "all classes, including enum classes, record classes, exceptions and errors", or "all classes except enum classes, record classes, exceptions and errors" ?

It just includes ?ordinary? classes as identified by Utils.isOrdinaryClass(TypeElement), so interfaces, enum classes, exceptions, errors and annotation interfaces are excluded. But I just discovered record classes are not (matching the fact that there is currently no ?Record Classes? tab in the All Classes page).

Hannes

-- jon

@hns hns changed the title JDK-8263507: Add links to page sections in sub-navigation of package summaries JDK-8263507: Improve structure of package summary pages Apr 19, 2021
@hns
Copy link
Member Author

@hns hns commented Apr 19, 2021

I opted for doing the summary table merge within this same PR. I couldn't find an existing JBS issue for it, and splitting the work into two changesets and reverse their order seemed like a non-trivial amount of work.

I have updated the JBS summary to "Improve structure of package summary pages" to reflect the broader scope.

Copy link
Contributor

@jonathan-gibbons jonathan-gibbons left a comment

I've read the source changes, but only skimmed through the tests at this point.

Various suggestions for your consideration or feedback.

.setDefaultTab(contents.allClassesAndInterfaces)
.addTab(contents.interfacesString, utils::isInterface)
.addTab(contents.classesString, e -> utils.isOrdinaryClass((TypeElement)e))
.addTab(contents.enumsString, utils::isEnum)
.addTab(contents.recordsString, e -> utils.isRecord((TypeElement)e))
.addTab(contents.exceptionsString, e -> utils.isException((TypeElement)e))
.addTab(contents.errorsString, e -> utils.isError((TypeElement)e))
.addTab(contents.annotationTypesString, utils::isAnnotationType);
Copy link
Contributor

@jonathan-gibbons jonathan-gibbons Apr 30, 2021

Choose a reason for hiding this comment

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

I can't say I'm a big fan of the new-style String suffix, but I guess it is OK for now; we need a cleanup on the names of members in Contents anyway. More comments in Contents.

public final String allClassesAndInterfaces;
public final String annotationTypesString;
public final String classesString;
public final String enumsString;
public final String errorsString;
public final String exceptionsString;
public final String interfacesString;
public final String packageSummary;
public final String recordSummary;
public final String recordsString;
Copy link
Contributor

@jonathan-gibbons jonathan-gibbons Apr 30, 2021

Choose a reason for hiding this comment

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

The new-style String suffix looks weird, and it's unexpected to see String constants here, but, I see the constants were there before, and (worse) I added them!
I guess we generally need to separate these names from equivalent Content objects. OK for now, but worth re-examining in a future cleanup.

{ "doclet.Annotation_Types_Summary", "doclet.Annotation_Interfaces_Summary" },
{ "doclet.Enum_Summary", "doclet.Enum_Class_Summary" },
Copy link
Contributor

@jonathan-gibbons jonathan-gibbons Apr 30, 2021

Choose a reason for hiding this comment

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

given you're changing this table, you should at least check manually if not in a test that you get old-style terminology with --release 16 or older, and new-style terminology with --release 17 or later.

.setSubNavLinks(() -> List.of(
HtmlTree.LI(links.createLink(HtmlIds.MODULE_DESCRIPTION, contents.navDescription,
!utils.getFullBody(mdle).isEmpty() && !options.noComment())),
HtmlTree.LI(links.createLink(HtmlIds.MODULES, contents.navModules,
display(requires) || display(indirectModules))),
HtmlTree.LI(links.createLink(HtmlIds.PACKAGES, contents.navPackages,
display(packages) || display(indirectPackages) || display(indirectOpenPackages))),
HtmlTree.LI(links.createLink(HtmlIds.SERVICES, contents.navServices,
displayServices(uses, usesTrees) || displayServices(provides.keySet(), providesTrees)))
));
Copy link
Contributor

@jonathan-gibbons jonathan-gibbons Apr 30, 2021

Choose a reason for hiding this comment

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

In general, I like the new .setSubNavLinks method. :-)
Do you need the HtmlTree.LI wrappers, or is it enough to pass in a list of links.createLink calls?
The HtmlTree.LI are really internal detail of the subnavbar implementation ... i.e. a ul of li elements.

* Links should be wrapped in {@code HtmlTree.LI} elements as they are
* displayed within an unordered list.
Copy link
Contributor

@jonathan-gibbons jonathan-gibbons Apr 30, 2021

Choose a reason for hiding this comment

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

As noted above, this class could do the wrapping with LI elements.

// add subpackages unless there are very many of them
Pattern subPattern = Pattern.compile(pkgName.replace(".", "\\.") + "\\.\\w+");
List<PackageElement> subpackages = filterPackages(
p -> subPattern.matcher(p.getQualifiedName().toString()).matches());
if (subpackages.size() <= MAX_SUBPACKAGES) {
packages.addAll(subpackages);
}

// only add sibling packages if we are beneath threshold, and number of siblings is beneath threshold as well
if (pkgPrefix != null && packages.size() <= MAX_SIBLING_PACKAGES) {
Pattern siblingPattern = Pattern.compile(pkgPrefix.replace(".", "\\.") + "\\.\\w+");

List<PackageElement> siblings = filterPackages(
p -> siblingPattern.matcher(p.getQualifiedName().toString()).matches());
if (siblings.size() <= MAX_SIBLING_PACKAGES) {
packages.addAll(siblings);
}
}
Copy link
Contributor

@jonathan-gibbons jonathan-gibbons Apr 30, 2021

Choose a reason for hiding this comment

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

Hmmm, I foresee downstream JBS issues ... "javadoc bug: I added a package to my code and the table disappeared". Should there be a warning and a way to change the limit? (Eventually?)

.addTab(contents.interfacesString, utils::isInterface)
.addTab(contents.classesString, e -> utils.isOrdinaryClass((TypeElement)e))
.addTab(contents.enumsString, utils::isEnum)
.addTab(contents.recordsString, e -> utils.isRecord((TypeElement)e))
.addTab(contents.exceptionsString, e -> utils.isException((TypeElement)e))
.addTab(contents.errorsString, e -> utils.isError((TypeElement)e))
.addTab(contents.annotationTypesString, utils::isAnnotationType);
Copy link
Contributor

@jonathan-gibbons jonathan-gibbons Apr 30, 2021

Choose a reason for hiding this comment

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

should we normalize the utils.is... methods so that we do not need the casts?

void addInterfaceSummary(SortedSet<TypeElement> interfaces, Content summaryContentTree);

/**
* Adds the table of classes to the documentation tree.
*
* @param classes the classes to document.
* @param summaryContentTree the content tree to which the summaries will be added
*/
void addClassSummary(SortedSet<TypeElement> classes, Content summaryContentTree);

/**
* Adds the table of enums to the documentation tree.
*
* @param enums the enums to document.
* @param summaryContentTree the content tree to which the summaries will be added
*/
void addEnumSummary(SortedSet<TypeElement> enums, Content summaryContentTree);

/**
* Adds the table of records to the documentation tree.
*
* @param records the records to document.
* @param summaryContentTree the content tree to which the summaries will be added
*/
void addRecordSummary(SortedSet<TypeElement> records, Content summaryContentTree);

/**
* Adds the table of exceptions to the documentation tree.
*
* @param exceptions the exceptions to document.
* @param summaryContentTree the content tree to which the summaries will be added
*/
void addExceptionSummary(SortedSet<TypeElement> exceptions, Content summaryContentTree);

/**
* Adds the table of errors to the documentation tree.
*
* @param errors the errors to document.
* @param summaryContentTree the content tree to which the summaries will be added
*/
void addErrorSummary(SortedSet<TypeElement> errors, Content summaryContentTree);

/**
* Adds the table of annotation types to the documentation tree.
*
* @param annoTypes the annotation types to document.
* @param summaryContentTree the content tree to which the summaries will be added
*/
void addAnnotationTypeSummary(SortedSet<TypeElement> annoTypes, Content summaryContentTree);
Copy link
Contributor

@jonathan-gibbons jonathan-gibbons Apr 30, 2021

Choose a reason for hiding this comment

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

Nice cleanup!

public static final EnumSet<Kind> summarySet = EnumSet.range(INNER_CLASSES, METHODS);
public static final EnumSet<Kind> detailSet = EnumSet.range(ENUM_CONSTANTS, METHODS);
private static final EnumSet<Kind> defaultSummarySet = EnumSet.of(
INNER_CLASSES, FIELDS, CONSTRUCTORS, METHODS);
Copy link
Contributor

@jonathan-gibbons jonathan-gibbons Apr 30, 2021

Choose a reason for hiding this comment

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

Picky, maybe for another time: the correct term is probably NESTED_CLASSES. Inner classes are a subset of nested classes that have an outer instance. (i.e. they're not static nested classes.

private static final EnumSet<Kind> enumSummarySet = EnumSet.of(
INNER_CLASSES, ENUM_CONSTANTS, FIELDS, METHODS);
private static final EnumSet<Kind> annotationSummarySet = EnumSet.of(
FIELDS, ANNOTATION_TYPE_MEMBER_OPTIONAL, ANNOTATION_TYPE_MEMBER_REQUIRED);
private static final EnumSet<Kind> defaultDetailSet = EnumSet.of(
FIELDS, CONSTRUCTORS, METHODS);
private static final EnumSet<Kind> enumDetailSet = EnumSet.of(
ENUM_CONSTANTS, FIELDS, METHODS);
Copy link
Contributor

@jonathan-gibbons jonathan-gibbons Apr 30, 2021

Choose a reason for hiding this comment

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

I'm a bit surprised by this, if only because we've had problems with tables like this in the past.

Is it possible to have a single combined list where some of the entries will give effectively empty tables which can be suppressed?

Case in point for an issue: why does enumSummarySet have INNER_CLASSES but annotationSummarySet does not.

Copy link
Contributor

@jonathan-gibbons jonathan-gibbons left a comment

Generally good.
There are some minor suggestions for additional cleanup, but we could file those for later and declare victory.

.setDefaultTab(contents.allClassesAndInterfacesLabel.toString())
.addTab(contents.interfaces.toString(), utils::isInterface)
.addTab(contents.classes.toString(), e -> utils.isOrdinaryClass((TypeElement)e))
.addTab(contents.enums.toString(), utils::isEnum)
.addTab(contents.records.toString(), e -> utils.isRecord((TypeElement)e))
.addTab(contents.exceptions.toString(), e -> utils.isException((TypeElement)e))
.addTab(contents.errors.toString(), e -> utils.isError((TypeElement)e))
.addTab(contents.annotationTypes.toString(), utils::isAnnotationType);
Copy link
Contributor

@jonathan-gibbons jonathan-gibbons May 6, 2021

Choose a reason for hiding this comment

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

Maybe the *Tab methods could be overloaded to accept Content ? Maybe later cleanup?
What does .toString() do in the malformed case of providing an HtmlTree ... should there be a method on Content? Maybe later cleanup?

Copy link
Member Author

@hns hns May 7, 2021

Choose a reason for hiding this comment

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

The *Tab methods could and should be converted to accept Content. I didn't want to pack too many unrelated changes into this issue so I have filed a separate one for it:

https://bugs.openjdk.java.net/browse/JDK-8266651

@@ -95,7 +95,7 @@ protected void buildAllPackagesFile() throws DocFileIOException {
*/
protected void addPackages(Content content) {
Table table = new Table(HtmlStyle.summaryTable)
.setCaption(Text.of(contents.packageSummary))
.setCaption(Text.of(contents.packageSummaryLabel.toString()))
Copy link
Contributor

@jonathan-gibbons jonathan-gibbons May 6, 2021

Choose a reason for hiding this comment

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

This seems a weird round trip: Text.of(contents.packageSummaryLabel.toString()

public final String annotationTypeSummary;
public final String classSummary;
public final String enumSummary;
public final String errorSummary;
public final String exceptionSummary;
public final String interfaceSummary;
public final String packageSummary;
public final String recordSummary;

Copy link
Contributor

@jonathan-gibbons jonathan-gibbons May 6, 2021

Choose a reason for hiding this comment

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

👍

@@ -603,7 +603,7 @@ public boolean isNoType(TypeMirror t) {
}

public boolean isOrdinaryClass(TypeElement te) {
if (isEnum(te) || isInterface(te) || isAnnotationType(te)) {
if (isEnum(te) || isInterface(te) || isAnnotationType(te) || isRecord(te)) {
Copy link
Contributor

@jonathan-gibbons jonathan-gibbons May 6, 2021

Choose a reason for hiding this comment

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

For your consideration ... thinking aloud, this could be done in a way that is better protected against future changes by

if (elementUtils.isClass(te) && te.getKind() != ElementKind.CLASS
        || elementUtils.isInterface(te) && te.getKind() != ElementKind.INTERFACE)
    return false;
} 

@openjdk
Copy link

@openjdk openjdk bot commented May 6, 2021

@hns This change now passes all automated pre-integration checks.

ℹ️ This project also has non-automated pre-integration requirements. Please see the file CONTRIBUTING.md for details.

After integration, the commit message for the final commit will be:

8263507: Improve structure of package summary pages

Reviewed-by: jjg

You can use pull request commands such as /summary, /contributor and /issue to adjust it as needed.

At the time when this comment was updated there had been 31 new commits pushed to the master branch:

  • 2dcbedf: 8266044: Nested class summary should show kind of class or interface
  • e840597: 8266460: java.io tests fail on null stream with upgraded jtreg/TestNG
  • fcedfc8: 8266579: Update test/jdk/java/lang/ProcessHandle/PermissionTest.java & test/jdk/java/sql/testng/util/TestPolicy.java
  • c665dba: 8266561: Remove Compile::_save_argument_registers
  • 47d4438: 8266426: ZHeapIteratorOopClosure does not handle native access properly
  • 2438498: 8252758: Lanai: Optimize index calculation while copying glyphs
  • eb3b96d: 8266496: WBIsKlassAliveClosure.do_klass() fails for hidden classes
  • 51f5adf: 8265047: Inconsistent warning message in jcmd VM.log
  • ea30bd6: 8263362: Avoid division by 0 in java/awt/font/TextJustifier.java justify
  • 0f9852c: 8266168: -Wmaybe-uninitialized happens in check_code.c
  • ... and 21 more: https://git.openjdk.java.net/jdk/compare/82768d9a31edcfe5b27e75d681d3592c8f4a2ece...master

As there are no conflicts, your changes will automatically be rebased on top of these commits when integrating. If you prefer to avoid this automatic rebasing, please check the documentation for the /integrate command for further details.

➡️ To integrate this PR with the above commit message to the master branch, type /integrate in a new comment.

@openjdk openjdk bot added the ready label May 6, 2021
@hns
Copy link
Member Author

@hns hns commented May 7, 2021

/integrate

@openjdk openjdk bot closed this May 7, 2021
@openjdk openjdk bot added the integrated label May 7, 2021
@openjdk openjdk bot removed ready rfr labels May 7, 2021
@openjdk
Copy link

@openjdk openjdk bot commented May 7, 2021

@hns Since your change was applied there have been 44 commits pushed to the master branch:

  • a65021e: 8266618: Remove broken -XX:-OptoRemoveUseless
  • 94c6177: 8266536: Provide a variant of os::iso8601_time which works with arbitrary timestamps
  • 71b8ad4: 8266609: AArch64: include FP/LR space in LIR_Assembler::initial_frame_size_in_bytes()
  • ebb68d2: 8049700: Deprecate obsolete classes and methods in javax/swing/plaf/basic
  • 3a474d9: 8265612: revise the help info for jmap histo command
  • c97f56c: 8266172: -Wstringop-overflow happens in vmError.cpp
  • 43ad24f: 8265465: jcmd VM.cds should keep already dumped archive when exception happens
  • 66191ff: 8266193: BasicJMapTest does not include testHistoParallel methods
  • 36e5ad6: 8263236: runtime/os/TestTracePageSizes.java fails on old kernels
  • 0ca86da: 8266002: vmTestbase/nsk/jvmti/ClassPrepare/classprep001 should skip events for unexpected classes
  • ... and 34 more: https://git.openjdk.java.net/jdk/compare/82768d9a31edcfe5b27e75d681d3592c8f4a2ece...master

Your commit was automatically rebased without conflicts.

Pushed as commit d2b5350.

💡 You may see a message that your pull request was closed with unmerged commits. This can be safely ignored.

@mlbridge
Copy link

@mlbridge mlbridge bot commented May 14, 2021

Mailing list message from Hannes Wallnoefer on javadoc-dev:

Thanks for the reivew, Jon. Comments inline below.

Am 30.04.2021 um 06:33 schrieb Jonathan Gibbons <jjg at openjdk.java.net>:

On Mon, 19 Apr 2021 09:45:27 GMT, Hannes Walln?fer <hannesw at openjdk.org> wrote:

This adds a feature to add sub-navigation links to the package summary page, but ended up more like a refactoring of the code to generate sub-navigation links. The reason for this is that generation of these links was highly idiosyncratic. Every writer class that wanted to create sub-nav links deposited something of itself in the `Navigation` instance which was then responsible for generating these links. The new code introduces a `Navigation.SubNavLinks` interface that allows writers to provide a list of links into their page content.

As for the new feature in the package summary page itself, I chose an approach that is a bit different from the one we use for other types of pages. Instead of displaying the inactive label instead of the link when a section is not present on the page, only the active links are displayed. The reason for this is that the package summary page contains so many potential summary tables that the sub-nav area gets quite crowded if they are all shown. Just showing the actually present pieces looked better to me.

Like in other sub-nav sections, the link labels sometimes use abbreviated terms such as "RELATED" instead of "RELATED PACKAGES" and "ENUMS" instead of "ENUM CLASSES". The full list of potential package sub-nav links is as follows:

Package: Description | Related | Interfaces | Classes | Enums | Records | Exceptions | Errors | Annotations

An important implementation note is that I moved the code to compute package summary contents from `PackageSummaryBuilder` to `PackageWriterImpl`. The reason for this is that the contents are required to determine which links to create, and I didn't want to re-compute this information that was previously computed on the fly in the builder class. The various summary items are now stored in collection fields in the writer class.

I have tried to add all the new properties and constants in a sensible place, which usually means alphabetic order within the sub-group of related entries.

I chose to keep the markup structure of the package summary page mostly unchanged, adding only `id` attributes to the existing `<li>` elements for each summary table. I decided against adding `class` attributes as well as it seems very unlikely to me that somebody would want to apply different styles to the various summary tables. Even without them, it could be done using the `id`s.

Hannes Walln?fer has updated the pull request incrementally with one additional commit since the last revision:

JDK-8263507: Update JBS summary

I've read the source changes, but only skimmed through the tests at this point.

Various suggestions for your consideration or feedback.

src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/AllClassesIndexWriter.java line 125:

123: .addTab(contents.exceptionsString, e -> utils.isException((TypeElement)e))
124: .addTab(contents.errorsString, e -> utils.isError((TypeElement)e))
125: .addTab(contents.annotationTypesString, utils::isAnnotationType);

I can't say I'm a big fan of the new-style `String` suffix, but I guess it is OK for now; we need a cleanup on the names of members in `Contents` anyway. More comments in `Contents`.

src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/Contents.java line 194:

192: public final String interfacesString;
193: public final String packageSummary;
194: public final String recordsString;

The new-style `String` suffix looks weird, and iut's unexpected to see `String` constants here, but, I see the constants were there before, and (worse) I added them!
I guess we generally need to separate these names from equivalent `Content` objects. OK for now, but worth re-examining in a future cleanup.

I pushed a follow-up commit to change all the String constants in Contents.java to Content objects. These constants are used for tab contents in Table.java which take String arguments. For now I just added a #toString() conversion for these usages, but I can file a JBS issue to convert these parameter types to `Content`, which is what they are converted to anyway.

src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlDoclet.java line 143:

141: // in doclets.properties
142: { "doclet.Annotation_Types_Summary", "doclet.Annotation_Interfaces_Summary" },
143: { "doclet.Enum_Summary", "doclet.Enum_Class_Summary" },

given you're changing this table, you should at least check manually if not in a test that you get old-style terminology with `--release 16` or older, and new-style terminology with `--release 17` or later.

Instead of the removed messages we are now using the pre-existing messages in plural form without the ?Summary? suffix (e.g. ?Enum Classes? instead of ?Enum Class Summary". The test that checks for correct terminology (TestTerminology.java) only covers the singular form of these messages (e.g. ?Enum Class?) so it only makes sure the mechanism is working, not that each and every use in the docs is correct. I manually checked to make sure the correct terminology is used in the affected summary tables.

src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ModuleWriterImpl.java line 209:

207: HtmlTree.LI(links.createLink(HtmlIds.SERVICES, contents.navServices,
208: displayServices(uses, usesTrees) || displayServices(provides.keySet(), providesTrees)))
209: ));

In general, I like the new `.setSubNavLinks` method. :-)
Do you need the `HtmlTree.LI` wrappers, or is it enough to pass in a list of `links.createLink` calls?
The `HtmlTree.LI` are really internal detail of the subnavbar implementation ... i.e. a `ul` of `li` elements.

src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/Navigation.java line 107:

105: * {@return a list of links to display in the sub-navigation area}
106: * Links should be wrapped in {@code HtmlTree.LI} elements as they are
107: * displayed within an unordered list.

As noted above, this class could do the wrapping with `LI` elements.

Done.

src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/Navigation.java line 144:

142: }
143:
144: public Navigation setMemberSummaryBuilder(MemberSummaryBuilder memberSummaryBuilder) {

General comment for this and all the following red lines: yay!

src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/Navigation.java line 343:

341: case PACKAGE:
342: case CLASS:
343: case HELP:

style comment ... since you're using new-style switch, do you want to do so here as well?

Will do.

src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/Navigation.java line 344:

342: case CLASS:
343: case HELP:
344: List<Content> listContents = subNavLinks.getSubNavLinks();

I think this looks like where you could stream the list, wrap the entries in `LI` and convert back to a list.

src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/PackageWriterImpl.java line 186:

184: packages.addAll(siblings);
185: }
186: }

Hmmm, I foresee downstream JBS issues ... "javadoc bug: I added a package to my code and the table disappeared". Should there be a warning and a way to change the limit? (Eventually?)

Quite possible. Different issue though.

src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/PackageWriterImpl.java line 260:

258: .addTab(contents.exceptionsString, e -> utils.isException((TypeElement)e))
259: .addTab(contents.errorsString, e -> utils.isError((TypeElement)e))
260: .addTab(contents.annotationTypesString, utils::isAnnotationType);

should we normalize the `utils.is...` methods so that we do not need the casts?

I looked into it, but ran into sublte issues (many of these methods are implemented by exclusion, which makes their behaviour depend on its parameter type. So I?d prefer to handle this as a separate issue, if we think it?s worth changing.

src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/PackageSummaryWriter.java line 130:

128: * @param summaryContentTree the content tree to which the summaries will be added
129: */
130: void addAnnotationTypeSummary(SortedSet<TypeElement> annoTypes, Content summaryContentTree);

Nice cleanup!

src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/VisibleMemberTable.java line 111:

109:
110: private static final EnumSet<Kind> defaultSummarySet = EnumSet.of(
111: INNER_CLASSES, FIELDS, CONSTRUCTORS, METHODS);

Picky, maybe for another time: the correct term is probably `NESTED_CLASSES`. Inner classes are a subset of nested classes that have an `outer` instance. (i.e. they're not `static` nested classes.

I changed the name to `NESTED_CLASSES`.

src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/VisibleMemberTable.java line 119:

117: FIELDS, CONSTRUCTORS, METHODS);
118: private static final EnumSet<Kind> enumDetailSet = EnumSet.of(
119: ENUM_CONSTANTS, FIELDS, METHODS);

I'm a bit surprised by this, if only because we've had problems with tables like this in the past.

Is it possible to have a single combined list where some of the entries will give effectively empty tables which can be suppressed?

Not possible here because these are used for the sub-navigation links, so if a table for some kind is empty the link label is still rendered as plain text. So removing this logic from here means we have to filter out member kinds somewhere else (this was done in the many lines of code in `Navigation` that I was able to remove). I prefer to have it sorted at the source.

Case in point for an issue: why does `enumSummarySet` have `INNER_CLASSES` but `annotationSummarySet` does not.

That is a bug that was present before. It is even baked into a test we have. Obviously it is very uncommon to have nested classes in annotation interfaces, or else somebody would have filed a bug. I?ll do that now.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
integrated javadoc
2 participants