Skip to content

Commit 7bbc5e0

Browse files
committed
8300517: Refactor VisibleMemberTable (method members)
Reviewed-by: jjg
1 parent a8f662e commit 7bbc5e0

File tree

13 files changed

+535
-316
lines changed

13 files changed

+535
-316
lines changed

src/jdk.javadoc/share/classes/jdk/javadoc/doclet/package-info.java

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2015, 2022, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2015, 2023, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -79,10 +79,13 @@
7979
* </dd>
8080
*
8181
* <dt><a id="included"></a>Included</dt>
82-
* <dd>An element is considered to be <em>included</em>, if it is
83-
* <em>specified</em> if it contains a <em>specified</em> element,
84-
* or it is enclosed in a <em>specified</em> element, and is <em>selected</em>.
85-
* Included elements will be documented.
82+
* <dd>An element is considered to be <em>included</em>, if it is <em>selected</em> and any of the following is true:
83+
* <ul>
84+
* <li>the element is <em>specified</em>, or
85+
* <li>the element contains a <em>specified</em> element, or
86+
* <li>the element is enclosed in a <em>specified</em> element.
87+
* </ul>
88+
* Included elements will be documented.
8689
* </dd>
8790
*
8891
* </dl>

src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlDocletWriter.java

Lines changed: 24 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -289,23 +289,30 @@ public String replaceDocRootDir(String htmlstr) {
289289
* @param dl the content to which the method information will be added
290290
*/
291291
private void addMethodInfo(ExecutableElement method, Content dl) {
292-
TypeElement enclosing = utils.getEnclosingTypeElement(method);
293-
List<? extends TypeMirror> intfacs = enclosing.getInterfaces();
294-
ExecutableElement overriddenMethod = utils.overriddenMethod(method);
295-
VisibleMemberTable vmt = configuration.getVisibleMemberTable(enclosing);
296-
// Check whether there is any implementation or overridden info to be
297-
// printed. If no overridden or implementation info needs to be
298-
// printed, do not print this section.
299-
if ((!intfacs.isEmpty()
300-
&& !vmt.getImplementedMethods(method).isEmpty())
301-
|| overriddenMethod != null) {
302-
MethodWriterImpl.addImplementsInfo(this, method, dl);
303-
if (overriddenMethod != null) {
304-
MethodWriterImpl.addOverridden(this,
305-
utils.overriddenType(method),
306-
overriddenMethod,
307-
dl);
308-
}
292+
var enclosing = (TypeElement) method.getEnclosingElement();
293+
var overrideInfo = utils.overriddenMethod(method);
294+
var enclosingVmt = configuration.getVisibleMemberTable(enclosing);
295+
var implementedMethods = enclosingVmt.getImplementedMethods(method);
296+
if ((!enclosing.getInterfaces().isEmpty()
297+
&& !implementedMethods.isEmpty())
298+
|| overrideInfo != null) {
299+
// TODO note that if there are any overridden interface methods throughout the
300+
// hierarchy, !enclosingVmt.getImplementedMethods(method).isEmpty(), their information
301+
// will be printed if *any* of the below is true:
302+
// * the enclosing has _directly_ implemented interfaces
303+
// * the overridden method is not null
304+
// If both are false, the information will not be printed: there will be no
305+
// "Specified by" documentation. The examples of that can be seen in documentation
306+
// for these methods:
307+
// * ForkJoinPool.execute(java.lang.Runnable)
308+
// This is a long-standing bug, which must be fixed separately: JDK-8302316
309+
MethodWriterImpl.addImplementsInfo(this, method, implementedMethods, dl);
310+
}
311+
if (overrideInfo != null) {
312+
MethodWriterImpl.addOverridden(this,
313+
overrideInfo.overriddenMethodOwner(),
314+
overrideInfo.overriddenMethod(),
315+
dl);
309316
}
310317
}
311318

src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/MethodWriterImpl.java

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525

2626
package jdk.javadoc.internal.doclets.formats.html;
2727

28+
import java.util.Collection;
2829
import java.util.SortedSet;
2930
import java.util.TreeSet;
3031

@@ -293,26 +294,28 @@ protected static void addOverridden(HtmlDocletWriter writer,
293294
* Adds "implements" information for a method (if appropriate)
294295
* into a definition list.
295296
*
296-
* @param writer the writer for the method
297-
* @param method the method
298-
* @param dl the definition list
297+
* @param writer the writer for the method
298+
* @param method the method
299+
* @param methods implemented methods
300+
* @param dl the definition list
299301
*/
300302
protected static void addImplementsInfo(HtmlDocletWriter writer,
301303
ExecutableElement method,
304+
Collection<ExecutableElement> methods,
302305
Content dl) {
303306
Utils utils = writer.utils;
304-
if (utils.isStatic(method) || writer.options.noComment()) {
307+
if (writer.options.noComment()) {
305308
return;
306309
}
307310
Contents contents = writer.contents;
308-
VisibleMemberTable vmt = writer.configuration
309-
.getVisibleMemberTable(utils.getEnclosingTypeElement(method));
311+
var enclosing = (TypeElement) method.getEnclosingElement();
312+
VisibleMemberTable vmt = writer.configuration.getVisibleMemberTable(enclosing);
310313
SortedSet<ExecutableElement> implementedMethods =
311314
new TreeSet<>(utils.comparators.makeOverrideUseComparator());
312-
implementedMethods.addAll(vmt.getImplementedMethods(method));
315+
implementedMethods.addAll(methods);
313316
for (ExecutableElement implementedMeth : implementedMethods) {
314317
TypeMirror intfac = vmt.getImplementedMethodHolder(method, implementedMeth);
315-
intfac = utils.getDeclaredType(utils.getEnclosingTypeElement(method), intfac);
318+
intfac = utils.getDeclaredType(enclosing, intfac);
316319
Content intfaclink = writer.getLink(new HtmlLinkInfo(
317320
writer.configuration, HtmlLinkInfo.Kind.LINK_TYPE_PARAMS_AND_BOUNDS, intfac));
318321
var codeIntfacLink = HtmlTree.CODE(intfaclink);

src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/TagletWriterImpl.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -573,8 +573,9 @@ private Content linkSeeReferenceOutput(Element holder,
573573
VisibleMemberTable vmt = configuration.getVisibleMemberTable(containing);
574574
overriddenMethod = vmt.getOverriddenMethod((ExecutableElement)refMem);
575575

576-
if (overriddenMethod != null)
576+
if (overriddenMethod != null) {
577577
containing = utils.getEnclosingTypeElement(overriddenMethod);
578+
}
578579
}
579580
if (refSignature.trim().startsWith("#") &&
580581
! (utils.isPublic(containing) || utils.isLinkable(containing))) {

src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/WorkArounds.java

Lines changed: 0 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -194,74 +194,6 @@ public TypeElement searchClass(TypeElement klass, String className) {
194194
return elementUtils.getTypeElement(className);
195195
}
196196

197-
// TODO: need to re-implement this using j.l.m. correctly!, this has
198-
// implications on testInterface, the note here is that javac's supertype
199-
// does the right thing returning Parameters in scope.
200-
/*
201-
* Returns the closest superclass (not the superinterface) that contains
202-
* a method that is both:
203-
*
204-
* - overridden by the specified method, and
205-
* - is not itself a *simple* override
206-
*
207-
* If no such class can be found, returns null.
208-
*
209-
* If the specified method belongs to an interface, the only considered
210-
* superclass is java.lang.Object no matter how many other interfaces
211-
* that interface extends.
212-
*/
213-
public DeclaredType overriddenType(ExecutableElement method) {
214-
if (utils.isStatic(method)) {
215-
return null;
216-
}
217-
MethodSymbol sym = (MethodSymbol) method;
218-
ClassSymbol origin = (ClassSymbol) sym.owner;
219-
for (Type t = javacTypes.supertype(origin.type);
220-
t.hasTag(TypeTag.CLASS);
221-
t = javacTypes.supertype(t)) {
222-
ClassSymbol c = (ClassSymbol) t.tsym;
223-
for (Symbol sym2 : c.members().getSymbolsByName(sym.name)) {
224-
if (sym.overrides(sym2, origin, javacTypes, true)) {
225-
// Ignore those methods that may be a simple override
226-
// and allow the real API method to be found.
227-
if (utils.isSimpleOverride((MethodSymbol)sym2)) {
228-
continue;
229-
}
230-
assert t.hasTag(TypeTag.CLASS) && !t.isInterface();
231-
return (Type.ClassType) t;
232-
}
233-
}
234-
}
235-
return null;
236-
}
237-
238-
// TODO: the method jx.l.m.Elements::overrides does not check
239-
// the return type, see JDK-8174840 until that is resolved,
240-
// use a copy of the same method, with a return type check.
241-
242-
// Note: the rider.overrides call in this method *must* be consistent
243-
// with the call in overrideType(....), the method above.
244-
public boolean overrides(ExecutableElement e1, ExecutableElement e2, TypeElement cls) {
245-
MethodSymbol rider = (MethodSymbol)e1;
246-
MethodSymbol ridee = (MethodSymbol)e2;
247-
ClassSymbol origin = (ClassSymbol)cls;
248-
249-
return rider.name == ridee.name &&
250-
251-
// not reflexive as per JLS
252-
rider != ridee &&
253-
254-
// we don't care if ridee is static, though that wouldn't
255-
// compile
256-
!rider.isStatic() &&
257-
258-
// Symbol.overrides assumes the following
259-
ridee.isMemberOf(origin, javacTypes) &&
260-
261-
// check access, signatures and check return types
262-
rider.overrides(ridee, origin, javacTypes, true);
263-
}
264-
265197
// TODO: jx.l.m ?
266198
public Location getLocationForModule(ModuleElement mdle) {
267199
ModuleSymbol msym = (ModuleSymbol)mdle;

0 commit comments

Comments
 (0)