--- old/src/jdk.javadoc/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/ParamTaglet.java Fri Jan 22 12:20:07 2016 +++ /dev/null Fri Jan 22 12:20:07 2016 @@ -1,323 +0,0 @@ -/* - * Copyright (c) 2001, 2014, 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 com.sun.tools.doclets.internal.toolkit.taglets; - -import java.util.*; - -import com.sun.javadoc.*; -import com.sun.tools.doclets.internal.toolkit.Content; -import com.sun.tools.doclets.internal.toolkit.util.*; - -/** - * A taglet that represents the @param tag. - * - *

This is NOT part of any supported API. - * If you write code that depends on this, you do so at your own risk. - * This code and its internal interfaces are subject to change or - * deletion without notice. - * - * @author Jamie Ho - * @since 1.4 - */ -public class ParamTaglet extends BaseTaglet implements InheritableTaglet { - - /** - * Construct a ParamTaglet. - */ - public ParamTaglet() { - name = "param"; - } - - /** - * Given an array of Parameters, return - * a name/rank number map. If the array is null, then - * null is returned. - * @param params The array of parmeters (from type or executable member) to - * check. - * @return a name-rank number map. - */ - private static Map getRankMap(Object[] params){ - if (params == null) { - return null; - } - HashMap result = new HashMap<>(); - for (int i = 0; i < params.length; i++) { - String name = params[i] instanceof Parameter ? - ((Parameter) params[i]).name() : - ((TypeVariable) params[i]).typeName(); - result.put(name, String.valueOf(i)); - } - return result; - } - - /** - * {@inheritDoc} - */ - public void inherit(DocFinder.Input input, DocFinder.Output output) { - if (input.tagId == null) { - input.isTypeVariableParamTag = ((ParamTag) input.tag).isTypeParameter(); - Object[] parameters = input.isTypeVariableParamTag ? - (Object[]) ((MethodDoc) input.tag.holder()).typeParameters() : - (Object[]) ((MethodDoc) input.tag.holder()).parameters(); - String target = ((ParamTag) input.tag).parameterName(); - int i; - for (i = 0; i < parameters.length; i++) { - String name = parameters[i] instanceof Parameter ? - ((Parameter) parameters[i]).name() : - ((TypeVariable) parameters[i]).typeName(); - if (name.equals(target)) { - input.tagId = String.valueOf(i); - break; - } - } - if (i == parameters.length) { - //Someone used {@inheritDoc} on an invalid @param tag. - //We don't know where to inherit from. - //XXX: in the future when Configuration is available here, - //print a warning for this mistake. - return; - } - } - ParamTag[] tags = input.isTypeVariableParamTag ? - ((MethodDoc)input.element).typeParamTags() : ((MethodDoc)input.element).paramTags(); - Map rankMap = getRankMap(input.isTypeVariableParamTag ? - (Object[]) ((MethodDoc)input.element).typeParameters() : - (Object[]) ((MethodDoc)input.element).parameters()); - for (ParamTag tag : tags) { - if (rankMap.containsKey(tag.parameterName()) && - rankMap.get(tag.parameterName()).equals((input.tagId))) { - output.holder = input.element; - output.holderTag = tag; - output.inlineTags = input.isFirstSentence ? - tag.firstSentenceTags() : tag.inlineTags(); - return; - } - } - } - - /** - * {@inheritDoc} - */ - public boolean inField() { - return false; - } - - /** - * {@inheritDoc} - */ - public boolean inMethod() { - return true; - } - - /** - * {@inheritDoc} - */ - public boolean inOverview() { - return false; - } - - /** - * {@inheritDoc} - */ - public boolean inPackage() { - return false; - } - - /** - * {@inheritDoc} - */ - public boolean inType() { - return true; - } - - /** - * {@inheritDoc} - */ - public boolean isInlineTag() { - return false; - } - - /** - * Given an array of ParamTags,return its string representation. - * @param holder the member that holds the param tags. - * @param writer the TagletWriter that will write this tag. - * @return the TagletOutput representation of these ParamTags. - */ - public Content getTagletOutput(Doc holder, TagletWriter writer) { - if (holder instanceof ExecutableMemberDoc) { - ExecutableMemberDoc member = (ExecutableMemberDoc) holder; - Content output = getTagletOutput(false, member, writer, - member.typeParameters(), member.typeParamTags()); - output.addContent(getTagletOutput(true, member, writer, - member.parameters(), member.paramTags())); - return output; - } else { - ClassDoc classDoc = (ClassDoc) holder; - return getTagletOutput(false, classDoc, writer, - classDoc.typeParameters(), classDoc.typeParamTags()); - } - } - - /** - * Given an array of ParamTags,return its string representation. - * Try to inherit the param tags that are missing. - * - * @param holder the doc that holds the param tags. - * @param writer the TagletWriter that will write this tag. - * @param formalParameters The array of parmeters (from type or executable - * member) to check. - * - * @return the TagletOutput representation of these ParamTags. - */ - private Content getTagletOutput(boolean isNonTypeParams, Doc holder, - TagletWriter writer, Object[] formalParameters, ParamTag[] paramTags) { - Content result = writer.getOutputInstance(); - Set alreadyDocumented = new HashSet<>(); - if (paramTags.length > 0) { - result.addContent( - processParamTags(isNonTypeParams, paramTags, - getRankMap(formalParameters), writer, alreadyDocumented) - ); - } - if (alreadyDocumented.size() != formalParameters.length) { - //Some parameters are missing corresponding @param tags. - //Try to inherit them. - result.addContent(getInheritedTagletOutput (isNonTypeParams, holder, - writer, formalParameters, alreadyDocumented)); - } - return result; - } - - /** - * Loop through each indivitual parameter. It it does not have a - * corresponding param tag, try to inherit it. - */ - private Content getInheritedTagletOutput(boolean isNonTypeParams, Doc holder, - TagletWriter writer, Object[] formalParameters, - Set alreadyDocumented) { - Content result = writer.getOutputInstance(); - if ((! alreadyDocumented.contains(null)) && - holder instanceof MethodDoc) { - for (int i = 0; i < formalParameters.length; i++) { - if (alreadyDocumented.contains(String.valueOf(i))) { - continue; - } - //This parameter does not have any @param documentation. - //Try to inherit it. - DocFinder.Output inheritedDoc = - DocFinder.search(writer.configuration(), new DocFinder.Input((MethodDoc) holder, this, - String.valueOf(i), ! isNonTypeParams)); - if (inheritedDoc.inlineTags != null && - inheritedDoc.inlineTags.length > 0) { - result.addContent( - processParamTag(isNonTypeParams, writer, - (ParamTag) inheritedDoc.holderTag, - isNonTypeParams ? - ((Parameter) formalParameters[i]).name(): - ((TypeVariable) formalParameters[i]).typeName(), - alreadyDocumented.size() == 0)); - } - alreadyDocumented.add(String.valueOf(i)); - } - } - return result; - } - - /** - * Given an array of Tags representing this custom - * tag, return its string representation. Print a warning for param - * tags that do not map to parameters. Print a warning for param - * tags that are duplicated. - * - * @param paramTags the array of ParamTags to convert. - * @param writer the TagletWriter that will write this tag. - * @param alreadyDocumented the set of exceptions that have already - * been documented. - * @param rankMap a {@link java.util.Map} which holds ordering - * information about the parameters. - * @param rankMap a {@link java.util.Map} which holds a mapping - * of a rank of a parameter to its name. This is - * used to ensure that the right name is used - * when parameter documentation is inherited. - * @return the Content representation of this Tag. - */ - private Content processParamTags(boolean isNonTypeParams, - ParamTag[] paramTags, Map rankMap, TagletWriter writer, - Set alreadyDocumented) { - Content result = writer.getOutputInstance(); - if (paramTags.length > 0) { - for (ParamTag pt : paramTags) { - String paramName = isNonTypeParams ? - pt.parameterName() : "<" + pt.parameterName() + ">"; - if (!rankMap.containsKey(pt.parameterName())) { - writer.getMsgRetriever().warning(pt.position(), - isNonTypeParams ? - "doclet.Parameters_warn" : - "doclet.Type_Parameters_warn", - paramName); - } - String rank = rankMap.get(pt.parameterName()); - if (rank != null && alreadyDocumented.contains(rank)) { - writer.getMsgRetriever().warning(pt.position(), - isNonTypeParams ? - "doclet.Parameters_dup_warn" : - "doclet.Type_Parameters_dup_warn", - paramName); - } - result.addContent(processParamTag(isNonTypeParams, writer, pt, - pt.parameterName(), alreadyDocumented.size() == 0)); - alreadyDocumented.add(rank); - } - } - return result; - } - /** - * Convert the individual ParamTag into Content. - * - * @param isNonTypeParams true if this is just a regular param tag. False - * if this is a type param tag. - * @param writer the taglet writer for output writing. - * @param paramTag the tag whose inline tags will be printed. - * @param name the name of the parameter. We can't rely on - * the name in the param tag because we might be - * inheriting documentation. - * @param isFirstParam true if this is the first param tag being printed. - * - */ - private Content processParamTag(boolean isNonTypeParams, - TagletWriter writer, ParamTag paramTag, String name, - boolean isFirstParam) { - Content result = writer.getOutputInstance(); - String header = writer.configuration().getText( - isNonTypeParams ? "doclet.Parameters" : "doclet.TypeParameters"); - if (isFirstParam) { - result.addContent(writer.getParamHeader(header)); - } - result.addContent(writer.paramTagOutput(paramTag, - name)); - return result; - } -} --- /dev/null Fri Jan 22 12:20:07 2016 +++ new/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/taglets/ParamTaglet.java Fri Jan 22 12:20:06 2016 @@ -0,0 +1,340 @@ +/* + * Copyright (c) 2001, 2016, 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 jdk.javadoc.internal.doclets.toolkit.taglets; + +import java.util.*; + +import javax.lang.model.element.Element; +import javax.lang.model.element.ExecutableElement; +import javax.lang.model.element.TypeElement; + +import com.sun.source.doctree.DocTree; +import com.sun.source.doctree.ParamTree; +import jdk.javadoc.internal.doclets.toolkit.Content; +import jdk.javadoc.internal.doclets.toolkit.util.CommentHelper; +import jdk.javadoc.internal.doclets.toolkit.util.DocFinder; +import jdk.javadoc.internal.doclets.toolkit.util.DocFinder.Input; +import jdk.javadoc.internal.doclets.toolkit.util.Utils; + +import static com.sun.source.doctree.DocTree.Kind.*; + +/** + * A taglet that represents the @param tag. + * + *

This is NOT part of any supported API. + * If you write code that depends on this, you do so at your own risk. + * This code and its internal interfaces are subject to change or + * deletion without notice. + * + * @author Jamie Ho + * @since 1.4 + */ +public class ParamTaglet extends BaseTaglet implements InheritableTaglet { + + /** + * Construct a ParamTaglet. + */ + public ParamTaglet() { + name = PARAM.tagName; + } + + /** + * Given an array of Parameters, return + a pname/rank number map. If the array is null, then + * null is returned. + * @param params The array of parameters (from type or executable member) to + * check. + * @return a pname-rank number map. + */ + private static Map getRankMap(Utils utils, List params){ + if (params == null) { + return null; + } + HashMap result = new HashMap<>(); + int rank = 0; + for (Element e : params) { + String name = utils.isTypeParameterElement(e) + ? utils.getTypeName(e.asType(), false) + : utils.getSimpleName(e); + result.put(name, String.valueOf(rank)); + rank++; + } + return result; + } + + /** + * {@inheritDoc} + */ + public void inherit(DocFinder.Input input, DocFinder.Output output) { + Utils utils = input.utils; + if (input.tagId == null) { + input.isTypeVariableParamTag = ((ParamTree)input.docTreeInfo.docTree).isTypeParameter(); + ExecutableElement ee = (ExecutableElement)input.docTreeInfo.element; + CommentHelper ch = utils.getCommentHelper(ee); + List parameters = input.isTypeVariableParamTag + ? ee.getTypeParameters() + : ee.getParameters(); + String target = ch.getParameterName(input.docTreeInfo.docTree); + for (int i = 0 ; i < parameters.size(); i++) { + Element e = parameters.get(i); + String pname = input.isTypeVariableParamTag + ? utils.getTypeName(e.asType(), false) + : utils.getSimpleName(e); + if (pname.equals(target)) { + input.tagId = String.valueOf(i); + break; + } + } + } + ExecutableElement md = (ExecutableElement)input.element; + CommentHelper ch = utils.getCommentHelper(md); + List tags = input.isTypeVariableParamTag + ? utils.getTypeParamTrees(md) + : utils.getParamTrees(md); + List parameters = input.isTypeVariableParamTag + ? md.getTypeParameters() + : md.getParameters(); + Map rankMap = getRankMap(utils, parameters); + for (DocTree tag : tags) { + String paramName = ch.getParameterName(tag); + if (rankMap.containsKey(paramName) && rankMap.get(paramName).equals((input.tagId))) { + output.holder = input.element; + output.holderTag = tag; + output.inlineTags = ch.getBody(utils.configuration, tag); + return; + } + } + } + + /** + * {@inheritDoc} + */ + public boolean inField() { + return false; + } + + /** + * {@inheritDoc} + */ + public boolean inMethod() { + return true; + } + + /** + * {@inheritDoc} + */ + public boolean inOverview() { + return false; + } + + /** + * {@inheritDoc} + */ + public boolean inPackage() { + return false; + } + + /** + * {@inheritDoc} + */ + public boolean inType() { + return true; + } + + /** + * {@inheritDoc} + */ + public boolean isInlineTag() { + return false; + } + + /** + * Given an array of ParamTags,return its string representation. + * @param holder the member that holds the param tags. + * @param writer the TagletWriter that will write this tag. + * @return the TagletOutput representation of these ParamTags. + */ + public Content getTagletOutput(Element holder, TagletWriter writer) { + Utils utils = writer.configuration().utils; + if (utils.isExecutableElement(holder)) { + ExecutableElement member = (ExecutableElement) holder; + Content output = getTagletOutput(false, member, writer, + member.getTypeParameters(), utils.getTypeParamTrees(member)); + output.addContent(getTagletOutput(true, member, writer, + member.getParameters(), utils.getParamTrees(member))); + return output; + } else { + TypeElement typeElement = (TypeElement) holder; + return getTagletOutput(false, typeElement, writer, + typeElement.getTypeParameters(), utils.getTypeParamTrees(typeElement)); + } + } + + /** + * Given an array of ParamTags,return its string representation. + * Try to inherit the param tags that are missing. + * + * @param holder the element that holds the param tags. + * @param writer the TagletWriter that will write this tag. + * @param formalParameters The array of parmeters (from type or executable + * member) to check. + * + * @return the TagletOutput representation of these ParamTags. + */ + private Content getTagletOutput(boolean isParameters, Element holder, + TagletWriter writer, List formalParameters, List paramTags) { + Content result = writer.getOutputInstance(); + Set alreadyDocumented = new HashSet<>(); + if (!paramTags.isEmpty()) { + result.addContent( + processParamTags(holder, isParameters, paramTags, + getRankMap(writer.configuration().utils, formalParameters), writer, alreadyDocumented) + ); + } + if (alreadyDocumented.size() != formalParameters.size()) { + //Some parameters are missing corresponding @param tags. + //Try to inherit them. + result.addContent(getInheritedTagletOutput(isParameters, holder, + writer, formalParameters, alreadyDocumented)); + } + return result; + } + + /** + * Loop through each individual parameter, despite not having a + * corresponding param tag, try to inherit it. + */ + private Content getInheritedTagletOutput(boolean isParameters, Element holder, + TagletWriter writer, List formalParameters, + Set alreadyDocumented) { + Utils utils = writer.configuration().utils; + Content result = writer.getOutputInstance(); + if ((!alreadyDocumented.contains(null)) && utils.isExecutableElement(holder)) { + for (int i = 0; i < formalParameters.size(); i++) { + if (alreadyDocumented.contains(String.valueOf(i))) { + continue; + } + // This parameter does not have any @param documentation. + // Try to inherit it. + Input input = new DocFinder.Input(writer.configuration().utils, holder, this, + Integer.toString(i), !isParameters); + DocFinder.Output inheritedDoc = DocFinder.search(writer.configuration(), input); + if (inheritedDoc.inlineTags != null && !inheritedDoc.inlineTags.isEmpty()) { + Element e = formalParameters.get(i); + String lname = isParameters + ? utils.getSimpleName(e) + : utils.getTypeName(e.asType(), false); + CommentHelper ch = utils.getCommentHelper(holder); + ch.setOverrideElement(inheritedDoc.holder); + Content content = processParamTag(holder, isParameters, writer, + inheritedDoc.holderTag, + lname, + alreadyDocumented.isEmpty()); + result.addContent(content); + } + alreadyDocumented.add(String.valueOf(i)); + } + } + return result; + } + + /** + * Given an array of Tags representing this custom + * tag, return its string representation. Print a warning for param + * tags that do not map to parameters. Print a warning for param + * tags that are duplicated. + * + * @param paramTags the array of ParamTags to convert. + * @param writer the TagletWriter that will write this tag. + * @param alreadyDocumented the set of exceptions that have already + * been documented. + * @param rankMap a {@link java.util.Map} which holds ordering + * information about the parameters. + * @param rankMap a {@link java.util.Map} which holds a mapping + of a rank of a parameter to its pname. This is + used to ensure that the right pname is used + when parameter documentation is inherited. + * @return the Content representation of this Tag. + */ + private Content processParamTags(Element e, boolean isParams, + List paramTags, Map rankMap, TagletWriter writer, + Set alreadyDocumented) { + Content result = writer.getOutputInstance(); + if (!paramTags.isEmpty()) { + CommentHelper ch = writer.configuration().utils.getCommentHelper(e); + for (DocTree dt : paramTags) { + String paramName = isParams + ? ch.getParameterName(dt) + : "<" + ch.getParameterName(dt) + ">"; + if (!rankMap.containsKey(ch.getParameterName(dt))) { + writer.getMsgRetriever().warning(ch.getDocTreePath(dt), + isParams ? + "doclet.Parameters_warn" : + "doclet.Type_Parameters_warn", + paramName); + } + String rank = rankMap.get(ch.getParameterName(dt)); + if (rank != null && alreadyDocumented.contains(rank)) { + writer.getMsgRetriever().warning(ch.getDocTreePath(dt), + isParams ? + "doclet.Parameters_dup_warn" : + "doclet.Type_Parameters_dup_warn", + paramName); + } + result.addContent(processParamTag(e, isParams, writer, dt, + ch.getParameterName(dt), alreadyDocumented.isEmpty())); + alreadyDocumented.add(rank); + } + } + return result; + } + + /** + * Convert the individual ParamTag into Content. + * + * @param isNonTypeParams true if this is just a regular param tag. False + * if this is a type param tag. + * @param writer the taglet writer for output writing. + * @param paramTag the tag whose inline tags will be printed. + * @param name the pname of the parameter. We can't rely on + the pname in the param tag because we might be + inheriting documentation. + * @param isFirstParam true if this is the first param tag being printed. + * + */ + private Content processParamTag(Element e, boolean isParams, + TagletWriter writer, DocTree paramTag, String name, + boolean isFirstParam) { + Content result = writer.getOutputInstance(); + String header = writer.configuration().getText( + isParams ? "doclet.Parameters" : "doclet.TypeParameters"); + if (isFirstParam) { + result.addContent(writer.getParamHeader(header)); + } + result.addContent(writer.paramTagOutput(e, paramTag, name)); + return result; + } +}