--- old/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/FieldWriterImpl.java Mon Oct 16 17:19:37 2017 +++ new/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/FieldWriterImpl.java Mon Oct 16 17:19:37 2017 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2017, 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 @@ -243,9 +243,16 @@ public void addInheritedSummaryLabel(TypeElement typeElement, Content inheritedTree) { Content classLink = writer.getPreQualifiedClassLink( LinkInfoImpl.Kind.MEMBER, typeElement, false); - Content label = new StringContent(utils.isClass(typeElement) - ? configuration.getText("doclet.Fields_Inherited_From_Class") - : configuration.getText("doclet.Fields_Inherited_From_Interface")); + Content label; + if (configuration.summarizeOverriddenMethods) { + label = new StringContent(utils.isClass(typeElement) + ? configuration.getText("doclet.Fields_Declared_In_Class") + : configuration.getText("doclet.Fields_Declared_In_Interface")); + } else { + label = new StringContent(utils.isClass(typeElement) + ? configuration.getText("doclet.Fields_Inherited_From_Class") + : configuration.getText("doclet.Fields_Inherited_From_Interface")); + } Content labelHeading = HtmlTree.HEADING(HtmlConstants.INHERITED_SUMMARY_HEADING, label); labelHeading.addContent(Contents.SPACE); --- old/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlConfiguration.java Mon Oct 16 17:19:38 2017 +++ new/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlConfiguration.java Mon Oct 16 17:19:38 2017 @@ -245,7 +245,7 @@ /** * Constructor. Initializes resource for the - * {@link com.sun.tools.doclets.internal.toolkit.util.MessageRetriever MessageRetriever}. + * {@link jdk.javadoc.internal.tool.Messager Messager}. */ public HtmlConfiguration(Doclet doclet) { super(doclet); --- old/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlDocletWriter.java Mon Oct 16 17:19:39 2017 +++ new/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlDocletWriter.java Mon Oct 16 17:19:38 2017 @@ -29,15 +29,18 @@ import java.util.*; import java.util.regex.Matcher; import java.util.regex.Pattern; +import java.util.stream.Collectors; import javax.lang.model.element.AnnotationMirror; import javax.lang.model.element.AnnotationValue; import javax.lang.model.element.Element; +import javax.lang.model.element.ElementKind; import javax.lang.model.element.ExecutableElement; import javax.lang.model.element.ModuleElement; import javax.lang.model.element.Name; import javax.lang.model.element.PackageElement; import javax.lang.model.element.TypeElement; +import javax.lang.model.element.TypeParameterElement; import javax.lang.model.element.VariableElement; import javax.lang.model.type.DeclaredType; import javax.lang.model.type.TypeMirror; @@ -94,6 +97,7 @@ import jdk.javadoc.internal.doclets.toolkit.util.DocletConstants; import jdk.javadoc.internal.doclets.toolkit.util.ImplementedMethods; import jdk.javadoc.internal.doclets.toolkit.util.Utils; +import jdk.javadoc.internal.doclets.toolkit.util.VisibleMemberMap; import static com.sun.source.doctree.DocTree.Kind.*; import static jdk.javadoc.internal.doclets.toolkit.util.CommentHelper.SPACER; @@ -1569,6 +1573,16 @@ // Must be a member reference since refClass is not null and refMemName is not null. // refMem is not null, so this @see tag must be referencing a valid member. TypeElement containing = utils.getEnclosingTypeElement(refMem); + + // Find the enclosing type where the method is actually visible, + // in the inheritance hierarchy. + if (refMem.getKind() == ElementKind.METHOD) { + VisibleMemberMap vmm = configuration. + getVisibleMemberMap(containing, VisibleMemberMap.Kind.METHODS); + ExecutableElement overriddenMethod = vmm.getVisibleMethod((ExecutableElement)refMem); + if (overriddenMethod != null) + containing = utils.getEnclosingTypeElement(overriddenMethod); + } if (ch.getText(see).trim().startsWith("#") && ! (utils.isPublic(containing) || utils.isLinkable(containing))) { // Since the link is relative and the holder is not even being --- old/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/LinkInfoImpl.java Mon Oct 16 17:19:40 2017 +++ new/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/LinkInfoImpl.java Mon Oct 16 17:19:39 2017 @@ -326,7 +326,7 @@ /** * Set the target to be used for the link. - * @param styleName String style of text defined in style sheet. + * @param target the target name. */ public LinkInfoImpl target(String target) { this.target = target; --- old/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/MethodWriterImpl.java Mon Oct 16 17:19:41 2017 +++ new/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/MethodWriterImpl.java Mon Oct 16 17:19:40 2017 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2017, 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 @@ -290,9 +290,16 @@ public void addInheritedSummaryLabel(TypeElement typeElement, Content inheritedTree) { Content classLink = writer.getPreQualifiedClassLink( LinkInfoImpl.Kind.MEMBER, typeElement, false); - Content label = new StringContent(utils.isClass(typeElement) - ? configuration.getText("doclet.Methods_Inherited_From_Class") - : configuration.getText("doclet.Methods_Inherited_From_Interface")); + Content label; + if (configuration.summarizeOverriddenMethods) { + label = new StringContent(utils.isClass(typeElement) + ? configuration.getText("doclet.Methods_Declared_In_Class") + : configuration.getText("doclet.Methods_Declared_In_Interface")); + } else { + label = new StringContent(utils.isClass(typeElement) + ? configuration.getText("doclet.Methods_Inherited_From_Class") + : configuration.getText("doclet.Methods_Inherited_From_Interface")); + } Content labelHeading = HtmlTree.HEADING(HtmlConstants.INHERITED_SUMMARY_HEADING, label); labelHeading.addContent(Contents.SPACE); --- old/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/NestedClassWriterImpl.java Mon Oct 16 17:19:42 2017 +++ new/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/NestedClassWriterImpl.java Mon Oct 16 17:19:41 2017 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2017, 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 @@ -150,9 +150,16 @@ public void addInheritedSummaryLabel(TypeElement typeElement, Content inheritedTree) { Content classLink = writer.getPreQualifiedClassLink( LinkInfoImpl.Kind.MEMBER, typeElement, false); - Content label = new StringContent(utils.isInterface(typeElement) - ? configuration.getText("doclet.Nested_Classes_Interface_Inherited_From_Interface") - : configuration.getText("doclet.Nested_Classes_Interfaces_Inherited_From_Class")); + Content label; + if (configuration.summarizeOverriddenMethods) { + label = new StringContent(utils.isInterface(typeElement) + ? configuration.getText("doclet.Nested_Classes_Interfaces_Declared_In_Interface") + : configuration.getText("doclet.Nested_Classes_Interfaces_Declared_In_Class")); + } else { + label = new StringContent(utils.isInterface(typeElement) + ? configuration.getText("doclet.Nested_Classes_Interfaces_Inherited_From_Interface") + : configuration.getText("doclet.Nested_Classes_Interfaces_Inherited_From_Class")); + } Content labelHeading = HtmlTree.HEADING(HtmlConstants.INHERITED_SUMMARY_HEADING, label); labelHeading.addContent(Contents.SPACE); --- old/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/PropertyWriterImpl.java Mon Oct 16 17:19:42 2017 +++ new/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/PropertyWriterImpl.java Mon Oct 16 17:19:42 2017 @@ -269,10 +269,16 @@ public void addInheritedSummaryLabel(TypeElement typeElement, Content inheritedTree) { Content classLink = writer.getPreQualifiedClassLink( LinkInfoImpl.Kind.MEMBER, typeElement, false); - Content label = new StringContent( - utils.isClass(typeElement) - ? configuration.getText("doclet.Properties_Inherited_From_Class") - : configuration.getText("doclet.Properties_Inherited_From_Interface")); + Content label; + if (configuration.summarizeOverriddenMethods) { + label = new StringContent(utils.isClass(typeElement) + ? configuration.getText("doclet.Properties_Declared_In_Class") + : configuration.getText("doclet.Properties_Declared_In_Interface")); + } else { + label = new StringContent(utils.isClass(typeElement) + ? configuration.getText("doclet.Properties_Inherited_From_Class") + : configuration.getText("doclet.Properties_Inherited_From_Interface")); + } Content labelHeading = HtmlTree.HEADING(HtmlConstants.INHERITED_SUMMARY_HEADING, label); labelHeading.addContent(Contents.SPACE); --- old/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/standard.properties Mon Oct 16 17:19:43 2017 +++ new/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/standard.properties Mon Oct 16 17:19:43 2017 @@ -345,6 +345,12 @@ doclet.usage.no-frames.description=\ Disable the use of frames in the generated output +doclet.usage.override-methods.parameters=\ + (detail|summary) + +doclet.usage.override-methods.description=\ + Document overridden methods in the detail or summary sections + doclet.usage.allow-script-in-comments.description=\ Allow JavaScript in options and comments --- old/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/BaseConfiguration.java Mon Oct 16 17:19:44 2017 +++ new/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/BaseConfiguration.java Mon Oct 16 17:19:44 2017 @@ -282,6 +282,13 @@ */ public boolean quiet = false; + /** + * Specifies whether those methods that overrides a super-type's method + * with no changes to the API contract, should be summarized in the + * foot note section. + */ + public boolean summarizeOverriddenMethods = false; + // A list containing urls private final List linkList = new ArrayList<>(); @@ -595,6 +602,13 @@ addToSet(excludedQualifiers, args.get(0)); return true; } + }, + new Option(resources, "--override-methods", 1) { + @Override + public boolean process(String opt, List args) { + summarizeOverriddenMethods = args.get(0).equals("summary"); + return true; + } }, new Hidden(resources, "-quiet") { @Override --- old/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/WorkArounds.java Mon Oct 16 17:19:45 2017 +++ new/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/WorkArounds.java Mon Oct 16 17:19:45 2017 @@ -61,6 +61,7 @@ import com.sun.tools.javac.code.Symbol.ModuleSymbol; import com.sun.tools.javac.code.Symbol.PackageSymbol; import com.sun.tools.javac.code.Symbol.VarSymbol; +import com.sun.tools.javac.code.TypeTag; import com.sun.tools.javac.comp.AttrContext; import com.sun.tools.javac.comp.Env; import com.sun.tools.javac.model.JavacElements; @@ -283,11 +284,17 @@ MethodSymbol sym = (MethodSymbol)method; ClassSymbol origin = (ClassSymbol) sym.owner; for (com.sun.tools.javac.code.Type t = toolEnv.getTypes().supertype(origin.type); - t.hasTag(com.sun.tools.javac.code.TypeTag.CLASS); + t.hasTag(TypeTag.CLASS); t = toolEnv.getTypes().supertype(t)) { ClassSymbol c = (ClassSymbol) t.tsym; for (com.sun.tools.javac.code.Symbol sym2 : c.members().getSymbolsByName(sym.name)) { if (sym.overrides(sym2, origin, toolEnv.getTypes(), true)) { + // Ignore those methods that may be a simple overridden + // and allow the real API method to be found. + if (sym2.type.hasTag(TypeTag.METHOD) && + utils.isSimpleOverride((MethodSymbol)sym2)) { + continue; + } return t; } } --- old/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/builders/MemberSummaryBuilder.java Mon Oct 16 17:19:47 2017 +++ new/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/builders/MemberSummaryBuilder.java Mon Oct 16 17:19:46 2017 @@ -79,9 +79,8 @@ /** * Construct a new MemberSummaryBuilder. * - * @param classWriter the writer for the class whose members are being - * summarized. * @param context the build context. + * @param typeElement the typeElement. */ private MemberSummaryBuilder(Context context, TypeElement typeElement) { super(context); @@ -337,7 +336,7 @@ List tableContents = new LinkedList<>(); int counter = 0; for (Element member : members) { - final Element property = visibleMemberMap.getPropertyMemberDoc(member); + final Element property = visibleMemberMap.getPropertyElement(member); if (property != null) { processProperty(visibleMemberMap, member, property); } @@ -475,30 +474,57 @@ */ private void buildInheritedSummary(MemberSummaryWriter writer, VisibleMemberMap visibleMemberMap, LinkedList summaryTreeList) { - for (TypeElement inhclass : visibleMemberMap.getVisibleClasses()) { - if (!(utils.isPublic(inhclass) || utils.isLinkable(inhclass))) { + for (TypeElement inheritedClass : visibleMemberMap.getVisibleClasses()) { + if (!(utils.isPublic(inheritedClass) || utils.isLinkable(inheritedClass))) { continue; } - if (inhclass == typeElement) { + if (inheritedClass == typeElement) { continue; } - SortedSet inhmembers = asSortedSet(visibleMemberMap.getMembers(inhclass)); - if (!inhmembers.isEmpty()) { - Content inheritedTree = writer.getInheritedSummaryHeader(inhclass); - Content linksTree = writer.getInheritedSummaryLinksTree(); - for (Element member : inhmembers) { - TypeElement t= inhclass; - if (utils.isPackagePrivate(inhclass) && !utils.isLinkable(inhclass)) { - t = typeElement; + SortedSet inheritedMembersFromMap = asSortedSet( + visibleMemberMap.getMembers(inheritedClass)); + + if (!inheritedMembersFromMap.isEmpty()) { + SortedSet inheritedMembers = new TreeSet<>(comparator); + List enclosedSuperMethods = utils.getMethods(inheritedClass); + for (Element inheritedMember : inheritedMembersFromMap) { + if (visibleMemberMap.kind != VisibleMemberMap.Kind.METHODS) { + inheritedMembers.add(inheritedMember); + continue; } - writer.addInheritedMemberSummary(t, member, inhmembers.first() == member, - inhmembers.last() == member, linksTree); + + // If applicable, filter those overridden methods that + // should not be documented in the summary/detail sections + // instead document them in the footnote, care must be taken + // to handle fx property methods which have no source comments, + // but comments are synthesized on the output. + ExecutableElement inheritedMethod = (ExecutableElement)inheritedMember; + if (enclosedSuperMethods.stream() + .anyMatch(e -> utils.executableMembersEqual(inheritedMethod, e) + && (!utils.isSimpleOverride(e) + || visibleMemberMap.getPropertyElement(e) != null))) { + inheritedMembers.add(inheritedMember); + } } + + Content inheritedTree = writer.getInheritedSummaryHeader(inheritedClass); + Content linksTree = writer.getInheritedSummaryLinksTree(); + addSummaryFootNote(inheritedClass, inheritedMembers, linksTree, writer); inheritedTree.addContent(linksTree); summaryTreeList.add(writer.getMemberTree(inheritedTree)); } } } + + private void addSummaryFootNote(TypeElement inheritedClass, SortedSet inheritedMembers, + Content linksTree, MemberSummaryWriter writer) { + for (Element member : inheritedMembers) { + TypeElement t = (utils.isPackagePrivate(inheritedClass) && !utils.isLinkable(inheritedClass)) + ? typeElement : inheritedClass; + writer.addInheritedMemberSummary(t, member, inheritedMembers.first() == member, + inheritedMembers.last() == member, linksTree); + } + } /** * Add the summary for the documentation. --- old/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/resources/doclets.properties Mon Oct 16 17:19:48 2017 +++ new/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/resources/doclets.properties Mon Oct 16 17:19:48 2017 @@ -144,13 +144,21 @@ doclet.exceptions=exceptions doclet.Package_private=(package private) doclet.Nested_Classes_Interfaces_Inherited_From_Class=Nested classes/interfaces inherited from class -doclet.Nested_Classes_Interface_Inherited_From_Interface=Nested classes/interfaces inherited from interface +doclet.Nested_Classes_Interfaces_Inherited_From_Interface=Nested classes/interfaces inherited from interface +doclet.Nested_Classes_Interfaces_Declared_In_Class=Nested classes/interfaces declared in class +doclet.Nested_Classes_Interfaces_Declared_In_Interface=Nested classes/interfaces declared in interface doclet.Methods_Inherited_From_Class=Methods inherited from class doclet.Methods_Inherited_From_Interface=Methods inherited from interface +doclet.Methods_Declared_In_Class=Methods declared in class +doclet.Methods_Declared_In_Interface=Methods declared in interface doclet.Fields_Inherited_From_Class=Fields inherited from class doclet.Fields_Inherited_From_Interface=Fields inherited from interface +doclet.Fields_Declared_In_Class=Fields declared in class +doclet.Fields_Declared_In_Interface=Fields declared in interface doclet.Properties_Inherited_From_Class=Properties inherited from class doclet.Properties_Inherited_From_Interface=Properties inherited from interface +doclet.Properties_Declared_In_Class=Properties declared in class +doclet.Properties_Declared_In_Interface=Properties declared in interface doclet.Annotation_Type_Member_Detail=Element Detail doclet.Enum_Constant_Detail=Enum Constant Detail doclet.Constants_Summary=Constant Field Values --- old/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/ClassUseMapper.java Mon Oct 16 17:19:49 2017 +++ new/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/ClassUseMapper.java Mon Oct 16 17:19:49 2017 @@ -39,6 +39,7 @@ import javax.lang.model.type.TypeMirror; import javax.lang.model.type.TypeVariable; import javax.lang.model.type.WildcardType; +import javax.lang.model.util.ElementFilter; import javax.lang.model.util.Elements; import javax.lang.model.util.SimpleElementVisitor9; import javax.lang.model.util.SimpleTypeVisitor9; @@ -46,6 +47,7 @@ import jdk.javadoc.doclet.DocletEnvironment; import jdk.javadoc.internal.doclets.formats.html.HtmlConfiguration; +import jdk.javadoc.internal.doclets.toolkit.util.VisibleMemberMap.Kind; /** * Map all class uses for a given class. @@ -241,7 +243,8 @@ mapExecutable(ctor); } - List methods = utils.getMethods(aClass); + VisibleMemberMap vmm = configuration.getVisibleMemberMap(aClass, Kind.METHODS); + List methods = ElementFilter.methodsIn(vmm.getMembers(aClass)); for (ExecutableElement method : methods) { mapExecutable(method); mapTypeParameters(classToMethodTypeParam, method, method); --- old/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/IndexBuilder.java Mon Oct 16 17:19:50 2017 +++ new/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/IndexBuilder.java Mon Oct 16 17:19:50 2017 @@ -35,6 +35,7 @@ import jdk.javadoc.doclet.DocletEnvironment; import jdk.javadoc.internal.doclets.toolkit.BaseConfiguration; import jdk.javadoc.internal.doclets.toolkit.Messages; +import jdk.javadoc.internal.doclets.toolkit.util.VisibleMemberMap.Kind; /** * Build the mapping of each Unicode character with it's member lists @@ -164,7 +165,8 @@ protected void putMembersInIndexMap(TypeElement te) { adjustIndexMap(utils.getAnnotationFields(te)); adjustIndexMap(utils.getFields(te)); - adjustIndexMap(utils.getMethods(te)); + VisibleMemberMap vmm = configuration.getVisibleMemberMap(te, Kind.METHODS); + adjustIndexMap(vmm.getMembers(te)); adjustIndexMap(utils.getConstructors(te)); adjustIndexMap(utils.getEnumConstants(te)); } --- old/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/Utils.java Mon Oct 16 17:19:51 2017 +++ new/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/Utils.java Mon Oct 16 17:19:51 2017 @@ -78,6 +78,7 @@ import com.sun.source.util.DocTrees; import com.sun.source.util.TreePath; import com.sun.tools.javac.model.JavacTypes; +import jdk.javadoc.internal.doclets.formats.html.HtmlConfiguration; import jdk.javadoc.internal.doclets.toolkit.BaseConfiguration; import jdk.javadoc.internal.doclets.toolkit.CommentUtils.DocCommentDuo; import jdk.javadoc.internal.doclets.toolkit.Messages; @@ -892,9 +893,12 @@ if (te == null) { return null; } - List methods = te.getEnclosedElements(); + VisibleMemberMap vmm = configuration.getVisibleMemberMap(te, + VisibleMemberMap.Kind.METHODS); + List methods = vmm.getMembers(te); for (ExecutableElement ee : ElementFilter.methodsIn(methods)) { - if (configuration.workArounds.overrides(method, ee, origin)) { + if (configuration.workArounds.overrides(method, ee, origin) && + !isSimpleOverride(ee)) { return ee; } } @@ -1462,9 +1466,11 @@ if (!getFullBody(e).isEmpty()) // ignore if already set continue; if (ee.getSimpleName().contentEquals("values") && ee.getParameters().isEmpty()) { + removeCommentHelper(ee); // purge previous entry configuration.cmtUtils.setEnumValuesTree(configuration, e); } if (ee.getSimpleName().contentEquals("valueOf") && ee.getParameters().size() == 1) { + removeCommentHelper(ee); // purge previous entry configuration.cmtUtils.setEnumValueOfTree(configuration, e); } } @@ -1557,6 +1563,25 @@ return hasBlockTag(e, DocTree.Kind.HIDDEN); } + /** + * Returns true if the method has no comments, or a lone @inheritDoc. + * @param m a method + * @return + */ + public boolean isSimpleOverride(ExecutableElement m) { + if (!configuration.summarizeOverriddenMethods || + !isIncluded(m)) { + return false; + } + + if (!getBlockTags(m).isEmpty()) + return false; + + List fullBody = getFullBody(m); + return fullBody.isEmpty() || + (fullBody.size() == 1 && fullBody.get(0).getKind().equals(Kind.INHERIT_DOC)); + } + /** * In case of JavaFX mode on, filters out classes that are private, * package private, these are not documented in JavaFX mode, also --- old/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/VisibleMemberMap.java Mon Oct 16 17:19:52 2017 +++ new/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/VisibleMemberMap.java Mon Oct 16 17:19:52 2017 @@ -29,11 +29,13 @@ import java.util.regex.Pattern; import javax.lang.model.element.Element; +import javax.lang.model.element.ElementKind; import javax.lang.model.element.ExecutableElement; import javax.lang.model.element.TypeElement; import javax.lang.model.element.VariableElement; import javax.lang.model.type.TypeKind; import javax.lang.model.type.TypeMirror; +import javax.lang.model.util.ElementFilter; import com.sun.source.doctree.DocCommentTree; import com.sun.source.doctree.DocTree; @@ -121,7 +123,7 @@ /** * Member kind: InnerClasses/Fields/Methods? */ - private final Kind kind; + public final Kind kind; /** * The configuration this VisibleMemberMap was created with. @@ -173,11 +175,41 @@ } /** + * Returns the first method where the given method is visible. + * @param e the method whose visible enclosing type is to be found. + * @return the method found or null + */ + public ExecutableElement getVisibleMethod(ExecutableElement e) { + if (kind != Kind.METHODS || e.getKind() != ElementKind.METHOD) { + throw new AssertionError("incompatible member type or visible member map" + e); + } + // start with the current class + for (Element m : getMembers(typeElement)) { + ExecutableElement mthd = (ExecutableElement)m; + if (utils.executableMembersEqual(mthd, e)) { + return mthd; + } + } + + for (TypeElement te : visibleClasses) { + if (te == typeElement) + continue; + for (Element m : getMembers(te)) { + ExecutableElement mthd = (ExecutableElement)m; + if (utils.executableMembersEqual(mthd, e)) { + return mthd; + } + } + } + return null; + } + + /** * Returns the property field documentation belonging to the given member. * @param element the member for which the property documentation is needed. * @return the property field documentation, null if there is none. */ - public Element getPropertyMemberDoc(Element element) { + public Element getPropertyElement(Element element) { return classPropertiesMap.get(element); } @@ -220,7 +252,12 @@ } /** - * Returns a list of visible enclosed members of the type being mapped. + * Returns a list of visible enclosed members of the mapped type element. + * + * In the case of methods, the list may contain those methods that are + * extended with no specification changes as indicated by the existence + * of a sole @inheritDoc or devoid of any API commments. + * * This list may also contain appended members, inherited by inaccessible * super types. These members are documented in the subtype when the * super type is not documented. @@ -230,11 +267,22 @@ public List getLeafMembers() { List result = new ArrayList<>(); - result.addAll(classMap.get(typeElement).members); + result.addAll(getMembers(typeElement)); result.addAll(getInheritedPackagePrivateMethods()); return result; } + private boolean hasOverridden(ExecutableElement method) { + for (TypeElement t : visibleClasses) { + for (ExecutableElement inheritedMethod : ElementFilter.methodsIn(classMap.get(t).members)) { + if (utils.elementUtils.overrides(method, inheritedMethod, t)) { + return true; + } + } + } + return false; + } + /** * Returns a list of enclosed members for the given type. * @@ -243,7 +291,22 @@ * @return a list of enclosed members */ public List getMembers(TypeElement typeElement) { - return classMap.get(typeElement).members; + List result = new ArrayList<>(); + if (this.kind == Kind.METHODS) { + for (Element member : classMap.get(typeElement).members) { + ExecutableElement method = (ExecutableElement)member; + if (hasOverridden(method)) { + if (!utils.isSimpleOverride(method)) { + result.add(method); + } + } else { + result.add(method); + } + } + } else { + result.addAll(classMap.get(typeElement).members); + } + return result; } public boolean hasMembers(TypeElement typeElement) { @@ -282,10 +345,14 @@ members.add(element); } - public boolean isEqual(ExecutableElement member) { - for (Element element : members) { - if (utils.executableMembersEqual(member, (ExecutableElement) element)) { - members.add(member); + public boolean isEqual(ExecutableElement method) { + for (Element member : members) { + if (member.getKind() != ElementKind.METHOD) + continue; + ExecutableElement thatMethod = (ExecutableElement) member; + if (utils.executableMembersEqual(method, thatMethod) && + !utils.isSimpleOverride(thatMethod)) { + members.add(method); return true; } } --- old/test/langtools/jdk/javadoc/doclet/lib/JavadocTester.java Mon Oct 16 17:19:53 2017 +++ new/test/langtools/jdk/javadoc/doclet/lib/JavadocTester.java Mon Oct 16 17:19:53 2017 @@ -511,7 +511,7 @@ int prevIndex = -1; for (String s : strings) { s = s.replace("\n", NL); // normalize new lines - int currentIndex = fileString.indexOf(s); + int currentIndex = fileString.indexOf(s, prevIndex + 1); checking(s + " at index " + currentIndex); if (currentIndex == -1) { failed(s + " not found."); --- /dev/null Mon Oct 16 17:19:54 2017 +++ new/test/langtools/jdk/javadoc/doclet/testOverridenMethods/TestOverrideMethods.java Mon Oct 16 17:19:53 2017 @@ -0,0 +1,230 @@ +/* + * Copyright (c) 2017, 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 + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8157000 + * @summary test the behavior of --override-methods option + * @library ../lib + * @modules jdk.javadoc/jdk.javadoc.internal.tool + * @build JavadocTester + * @run main TestOverrideMethods + */ + +public class TestOverrideMethods extends JavadocTester { + public static void main(String... args) throws Exception { + TestOverrideMethods tester = new TestOverrideMethods(); + tester.runTests(); + } + + @Test + void test() { + javadoc("-d", "out", + "-sourcepath", testSrc, + "-javafx", + "--override-methods=summary", + "pkg5"); + + checkExit(Exit.OK); + + checkOutput("pkg5/Classes.C.html", true, + // check properties + "

Properties declared in class pkg5.Classes.P

\n" + + "rate", + + // check nested classes + "

Nested classes/interfaces declared in class pkg5." + + "Classes.P

\n" + + "" + + "Classes.P.PN<K," + + "" + + "V>\n", + + // check fields + "

Fields declared in class pkg5.Classes.P

\n" + + "field0\n", + + // check method summary + "void\n" + + "" + + "m1()\n" + + "\n" + + "
A modified method
\n", + + "void\n" + + "" + + "m4" + + "​(java.lang.String k,\n" + + " java.lang.String v)\n", + + // check footnotes + "

Methods declared in class pkg5.Classes.GP

\n" + + "m0", + + // check method details for override + "
Overrides:
\n" + + "
m7" + + " in class Classes.GP
\n" + ); + + // check footnotes 2 + checkOrder("pkg5/Classes.C.html", + "Methods declared in class pkg5.", + "getRate, ", + "m2, ", + "m3, ", + "m4, ", + "rateProperty, ", + "setRate" + ); + + // check @link + checkOrder("pkg5/Classes.C.html", + "A test of links to the methods in this class.

\n", + "Classes.GP.m0()", + "m1()", + "Classes.P.m2()", + "Classes.P.m3()", + "m4(java.lang.String,java.lang.String)", + "Classes.P.m5()", + "m6()", + "m7()", + "End of links" + ); + + // check @see + checkOrder("pkg5/Classes.C.html", + "See Also:", + "Classes.GP.m0()", + "m1()", + "Classes.P.m2()", + "Classes.P.m3()", + "" + + "m4(String k, String v)", + "Classes.P.m5()", + "m6()", + "m7()" + ); + + checkOutput("pkg5/Interfaces.D.html", true, + // check properties + "

Properties declared in interface pkg5.Interfaces.A", + + // check nested classes + "

Nested classes/interfaces declared in interface pkg5." + + "" + + "Interfaces.A

\n" + + "Interfaces.A.AA", + + // check fields + "

Fields declared in interface pkg5.Interfaces.A

\n" + + "f", + + // check method summary + "void\n" + + "" + + "m()\n" + + "\n" + + "
m in D
\n", + + "void\n" + + "" + + "n()\n" + + "\n" + + "
n in D
\n", + + // check footnote + "

Methods declared in interface pkg5.Interfaces.A

\n" + + "getRate, " + + "rateProperty, " + + "setRate", + + "

Methods declared in interface pkg5.Interfaces.B

\n" + + "m1, " + + "m3", + + "

Methods declared in interface pkg5.Interfaces.C

\n" + + "o" + ); + + checkOrder("pkg5/Interfaces.D.html", + "Start of links

", + "Interfaces.A.m0()", + "Interfaces.A.m1()", + "Interfaces.A.m2()", + "Interfaces.A.m3()", + "m()", + "n()", + "Interfaces.C.o()", + "End of links"); + + checkOrder("pkg5/Interfaces.D.html", + "See Also:", + "Interfaces.A.m0()", + "Interfaces.A.m1()", + "Interfaces.A.m2()", + "Interfaces.A.m3()", + "m()", + "n()", + "Interfaces.C.o()"); + + // Test synthetic values and valuesof of an enum. + checkOrder("index-all.html", + "

M

", + "m()", + "m()", + "m0()", + "m0()", + "m1()", + "m1()", + "m1()", + "m1()", + "m2()", + "m2()", + "m3()", + "m3()", + "m3()", + "m4(String, String)", + "m4(K, V)", + "m5()", + "m6()", + "m6()", + "m7()", + "m7()", + "Returns the enum constant of this type with the specified name.", + "Returns an array containing the constants of this enum type, in\n" + + "the order they are declared." + ); + } +} --- /dev/null Mon Oct 16 17:19:55 2017 +++ new/test/langtools/jdk/javadoc/doclet/testOverridenMethods/pkg5/Classes.java Mon Oct 16 17:19:54 2017 @@ -0,0 +1,140 @@ +/* + * Copyright (c) 2017, 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 + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package pkg5; + +public class Classes { + + public static class GP { + /** m0 in grand parent */ + public void m0() {} + + /** m7 in grand parent */ + public void m7() {} + } + + public static class P extends GP { + + /** a nested class in parent */ + public class PN{} + + /** A property in parent */ + private DoubleProperty rate; + public final void setRate(double l){} + public final double getRate(){return 1;} + public DoubleProperty rateProperty() {return null;} + + /** A ctor in parent */ + public P() {} + + /** + * A ctor in parent. + * @param s string + */ + public P(String s) {} + + /** field0 in parent */ + public int field0; + + /** field1 in parent */ + public int field1; + + + // m0 in parent + public void m0() {} + + /** m1 in parent */ + public void m1() {} + + /** m2 in parent */ + public void m2() {} + + /** m3 in parent */ + public void m3() {} + + /** m4 in parent + @param k a key + @param v a value + */ + public void m4(K k, V v) {} + + // no comment + public void m5() {} + + // no comment + public void m6() {} + + /** {@inheritDoc} */ + public void m7() {} + + } + + public static class C extends P { + + public C(String s) {} + + public int field1; + + /** A modified method */ + public void m1() {} + + /** {@inheritDoc} */ + public void m2() {} + + // no comment method + public void m3() {} + + public void m4(String k, String v) {} + + // do something else than the parent + public void m5() {} + + /** A test of links to the methods in this class.

+ * {@link m0}, + * {@link m1}, + * {@link m2}, + * {@link m3}, + * {@link m4}, + * {@link m5}, + * {@link m6}, + * {@link m7}, + * End of links + * + * @see #m0() + * @see #m1() + * @see #m2() + * @see #m3() + * @see #m4(String k, String v) + * @see #m5() + * @see #m6() + * @see #m7() + */ + public void m6() {} + + /** m7 in Child. */ + public void m7() {} + } + + /** You must see this {@link TestEnum#doSomething()} */ + public class DoubleProperty {} +} --- /dev/null Mon Oct 16 17:19:56 2017 +++ new/test/langtools/jdk/javadoc/doclet/testOverridenMethods/pkg5/Interfaces.java Mon Oct 16 17:19:55 2017 @@ -0,0 +1,112 @@ +/* + * Copyright (c) 2017, 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 + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package pkg5; + +public class Interfaces { + public interface A { + + /** field f in A */ + public int f = 0; + + /** A property in parent */ + DoubleProperty rate = null; + public void setRate(double l); + public double getRate(); + public DoubleProperty rateProperty(); + // support class + public interface DoubleProperty {} + + /** AA in A */ + public interface AA {} + + /** m0 in A */ + public void m0(); + + /** m1 in A */ + public void m1(); + + /** m2 in A */ + public void m2(); + + /** m3 in A */ + public void m3(); + } + + public interface B extends A { + // no comment + public void m0(); + + /** m1 in B */ + public void m1(); + + /** {@inheritDoc} */ + public void m2(); + + /** @throws Exception e */ + public void m3() throws Exception; + + /** n in B */ + public void n(); + } + + public interface C extends A, B { + /** m in C */ + public void m(); + + /** o in C */ + public void o(); + } + + /** + * The child of all children. + * + * Start of links

+ * {@link m0}, + * {@link m1}, + * {@link m2}, + * {@link m3}, + * {@link m}, + * {@link n}, + * {@link o}, + * End of links + * + * @see #m0() + * @see #m1() + * @see #m2() + * @see #m3() + * @see #m + * @see #n + * @see #o + */ + public interface D extends A, B, C { + /** m in D */ + public void m(); + + /** n in D */ + public void n(); + + // no comment + public void o(); + } + } --- /dev/null Mon Oct 16 17:19:57 2017 +++ new/test/langtools/jdk/javadoc/doclet/testOverridenMethods/pkg5/TestEnum.java Mon Oct 16 17:19:56 2017 @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2017, 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 + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package pkg5; + +/** Test Enum */ +public enum TestEnum { + A, B, C, D; + /** An useful method. */ + public void doSomething(){} +}