diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ClassUseWriter.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ClassUseWriter.java index ddc8710e517..589854cacd6 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ClassUseWriter.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ClassUseWriter.java @@ -60,6 +60,9 @@ public class ClassUseWriter extends SubWriterHolderWriter { final TypeElement typeElement; Set pkgToPackageAnnotations = null; final Map> pkgToClassTypeParameter; + final Map> pkgToSubclassTypeParameter; + final Map> pkgToSubinterfaceTypeParameter; + final Map> pkgToImplementsTypeParameter; final Map> pkgToClassAnnotations; final Map> pkgToMethodTypeParameter; final Map> pkgToMethodArgTypeParameter; @@ -105,6 +108,9 @@ public class ClassUseWriter extends SubWriterHolderWriter { configuration.currentTypeElement = typeElement; this.pkgSet = new TreeSet<>(comparators.packageComparator()); this.pkgToClassTypeParameter = pkgDivide(mapper.classToClassTypeParam); + this.pkgToSubclassTypeParameter = pkgDivide(mapper.classToSubclassTypeParam); + this.pkgToSubinterfaceTypeParameter = pkgDivide(mapper.classToSubinterfaceTypeParam); + this.pkgToImplementsTypeParameter = pkgDivide(mapper.classToImplementsTypeParam); this.pkgToClassAnnotations = pkgDivide(mapper.classToClassAnnotations); this.pkgToMethodTypeParameter = pkgDivide(mapper.classToMethodTypeParam); this.pkgToMethodArgTypeParameter = pkgDivide(mapper.classToMethodArgTypeParam); @@ -338,6 +344,15 @@ public class ClassUseWriter extends SubWriterHolderWriter { classSubWriter.addUseInfo(pkgToImplementingClass.get(pkg), contents.getContent("doclet.ClassUse_ImplementingClass", classLink, pkgLink), content); + classSubWriter.addUseInfo(pkgToSubclassTypeParameter.get(pkg), + contents.getContent("doclet.ClassUse_SubclassTypeParameter", classLink, + pkgLink), content); + classSubWriter.addUseInfo(pkgToSubinterfaceTypeParameter.get(pkg), + contents.getContent("doclet.ClassUse_SubinterfaceTypeParameter", classLink, + pkgLink), content); + classSubWriter.addUseInfo(pkgToImplementsTypeParameter.get(pkg), + contents.getContent("doclet.ClassUse_ImplementsTypeParameter", classLink, + pkgLink), content); fieldSubWriter.addUseInfo(pkgToField.get(pkg), contents.getContent("doclet.ClassUse_Field", classLink, pkgLink), content); diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/standard.properties b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/standard.properties index b83768ea31a..23bf1f3c194 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/standard.properties +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/standard.properties @@ -1,5 +1,5 @@ # -# Copyright (c) 2010, 2022, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2010, 2024, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -277,12 +277,14 @@ doclet.help.other_files.body=\ doclet.help.use.head=\ Use doclet.help.use.body=\ - Each documented package, class and interface has its own Use page. This page describes what \ - packages, classes, methods, constructors and fields use any part of the given class or \ - package. Given a class or interface A, its Use page includes subclasses of A, fields declared \ - as A, methods that return A, and methods and constructors with parameters of type A. \ - You can access this page by first going to the package, class or interface, then clicking on \ - the USE link in the navigation bar. + Each documented package, class or interface has its own Use page, which lists \ + packages, classes, interfaces, methods, constructors and fields that use any \ + part of that package, class or interface. Given a class or interface A, its \ + Use page includes subclasses or subinterfaces of A, fields declared as A, \ + methods that return A, methods and constructors with parameters of type A, \ + and subclasses or subinterfaces with parameters of type A. You can access \ + this page by first going to the package, class or interface, then clicking \ + on the USE link in the navigation bar. doclet.help.tree.head=\ Tree (Class Hierarchy) # 0: link to main Class Hierarchy page; 1: java.lang.Object @@ -380,6 +382,9 @@ doclet.ClassUse_Classes.in.0.used.by.1=Classes in {0} used by {1} doclet.ClassUse_PackageAnnotation=Packages with annotations of type {0} doclet.ClassUse_Annotation=Classes in {1} with annotations of type {0} doclet.ClassUse_TypeParameter=Classes in {1} with type parameters of type {0} +doclet.ClassUse_SubclassTypeParameter=Subclasses with type arguments of type {0} in {1} +doclet.ClassUse_SubinterfaceTypeParameter=Subinterfaces with type arguments of type {0} in {1} +doclet.ClassUse_ImplementsTypeParameter=Classes in {1} that implement interfaces with type arguments of type {0} doclet.ClassUse_MethodTypeParameter=Methods in {1} with type parameters of type {0} doclet.ClassUse_FieldTypeParameter=Fields in {1} with type parameters of type {0} doclet.ClassUse_FieldAnnotations=Fields in {1} with annotations of type {0} diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/ClassUseMapper.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/ClassUseMapper.java index 3f16e3458fb..00a6f6d86ab 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/ClassUseMapper.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/ClassUseMapper.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -92,7 +92,22 @@ public class ClassUseMapper { /** * Mapping of TypeElements to list of TypeElements which implement this interface. */ - public Map> classToImplementingClass = new HashMap<>(); + public final Map> classToImplementingClass = new HashMap<>(); + + /** + * Mapping of TypeElements to list of TypeElements which use them in superclass type parameters. + */ + public final Map> classToSubclassTypeParam = new HashMap<>(); + + /** + * Mapping of TypeElements to list of TypeElements which use them in superinterface type parameters. + */ + public final Map> classToSubinterfaceTypeParam = new HashMap<>(); + + /** + * Mapping of TypeElements to list of TypeElements which use them in implemented interface type parameters. + */ + public final Map> classToImplementsTypeParam = new HashMap<>(); /** * Mapping of TypeElements to list of VariableElements declared as that class. @@ -214,6 +229,18 @@ public class ClassUseMapper { PackageElement pkg = elementUtils.getPackageOf(aClass); mapAnnotations(classToPackageAnnotations, pkg, pkg); mapTypeParameters(classToClassTypeParam, aClass, aClass); + mapTypeParameters(classToSubclassTypeParam, aClass.getSuperclass(), aClass); + + if (utils.isInterface(aClass)) { + for (var superinterface : aClass.getInterfaces()) { + mapTypeParameters(classToSubinterfaceTypeParam, superinterface, aClass); + } + } else { + for (var superinterface : aClass.getInterfaces()) { + mapTypeParameters(classToImplementsTypeParam, superinterface, aClass); + } + } + mapAnnotations(classToClassAnnotations, aClass, aClass); VisibleMemberTable vmt = configuration.getVisibleMemberTable(aClass); diff --git a/test/langtools/jdk/javadoc/doclet/testUseOption/TestUseOption.java b/test/langtools/jdk/javadoc/doclet/testUseOption/TestUseOption.java index ed96377c7e3..f5f6ff213a0 100644 --- a/test/langtools/jdk/javadoc/doclet/testUseOption/TestUseOption.java +++ b/test/langtools/jdk/javadoc/doclet/testUseOption/TestUseOption.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -24,15 +24,20 @@ /* * @test * @bug 4496290 4985072 7006178 7068595 8016328 8050031 8048351 8081854 8071982 8162363 8175200 8186332 - * 8182765 8196202 8202626 8261976 + * 8182765 8196202 8202626 8261976 8323698 * @summary A simple test to ensure class-use files are correct. - * @library ../../lib + * @library /tools/lib ../../lib * @modules jdk.javadoc/jdk.javadoc.internal.tool * @build javadoc.tester.* * @run main TestUseOption */ import javadoc.tester.JavadocTester; +import toolbox.ToolBox; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; public class TestUseOption extends JavadocTester { @@ -41,6 +46,8 @@ public class TestUseOption extends JavadocTester { tester.runTests(); } + private final ToolBox tb = new ToolBox(); + @Test public void test1() { javadoc("-d", "out-1", @@ -191,4 +198,83 @@ public class TestUseOption extends JavadocTester { """ """); } + + @Test + public void testSuperclassAndInterfaceTypeArgument(Path base) throws IOException { + Path src = base.resolve("src"); + + Files.createDirectories(src); + tb.writeJavaFiles(src, + """ + public class One {} + """, + """ + import java.util.*; + public class Two extends ArrayList implements Comparator { + } + """, + """ + import java.util.*; + public interface Three extends Comparator { + } + """); + + javadoc( + "-use", + "-d", base.resolve("out").toString(), + src.resolve("One.java").toString(), + src.resolve("Two.java").toString(), + src.resolve("Three.java").toString() + ); + checkExit(Exit.OK); + + checkOrder("class-use/One.html", + """ + + """, + """ +
+
Modifier and Type
+
Class
+
Description
+
class 
+ +
 
+
+ """, + """ +
Subinterfaces with type arguments of \ + type One \ + in Unnamed Package
+ """, + """ +
+
Modifier and Type
+
Interface
+
Description
+
interface 
+ +
 
+
+ """, + """ +
Classes in \ + Unnamed Package that implement interfaces with type arguments of type \ + One
+ """, + """ +
+
Modifier and Type
+
Class
+
Description
+
class 
+ +
 
+
+ """); + } }