src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/ParamTaglet.java

Thu, 02 Oct 2008 19:58:40 -0700

author
xdono
date
Thu, 02 Oct 2008 19:58:40 -0700
changeset 117
24a47c3062fe
parent 74
5a9172b251dd
child 184
905e151a185a
permissions
-rw-r--r--

6754988: Update copyright year
Summary: Update for files that have been modified starting July 2008
Reviewed-by: ohair, tbell

     1 /*
     2  * Copyright 2001-2008 Sun Microsystems, Inc.  All Rights Reserved.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4  *
     5  * This code is free software; you can redistribute it and/or modify it
     6  * under the terms of the GNU General Public License version 2 only, as
     7  * published by the Free Software Foundation.  Sun designates this
     8  * particular file as subject to the "Classpath" exception as provided
     9  * by Sun in the LICENSE file that accompanied this code.
    10  *
    11  * This code is distributed in the hope that it will be useful, but WITHOUT
    12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    14  * version 2 for more details (a copy is included in the LICENSE file that
    15  * accompanied this code).
    16  *
    17  * You should have received a copy of the GNU General Public License version
    18  * 2 along with this work; if not, write to the Free Software Foundation,
    19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    20  *
    21  * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
    22  * CA 95054 USA or visit www.sun.com if you need additional information or
    23  * have any questions.
    24  */
    26 package com.sun.tools.doclets.internal.toolkit.taglets;
    28 import com.sun.javadoc.*;
    29 import com.sun.tools.doclets.internal.toolkit.util.*;
    30 import java.util.*;
    32 /**
    33  * A taglet that represents the @param tag.
    34  *
    35  * This code is not part of an API.
    36  * It is implementation that is subject to change.
    37  * Do not use it as an API
    38  *
    39  * @author Jamie Ho
    40  * @since 1.4
    41  */
    42 public class ParamTaglet extends BaseTaglet implements InheritableTaglet {
    44     /**
    45      * Construct a ParamTaglet.
    46      */
    47     public ParamTaglet() {
    48         name = "param";
    49     }
    51     /**
    52      * Given an array of <code>Parameter</code>s, return
    53      * a name/rank number map.  If the array is null, then
    54      * null is returned.
    55      * @param params The array of parmeters (from type or executable member) to
    56      *               check.
    57      * @return a name-rank number map.
    58      */
    59     private static Map<String,String> getRankMap(Object[] params){
    60         if (params == null) {
    61             return null;
    62         }
    63         HashMap<String,String> result = new HashMap<String,String>();
    64         for (int i = 0; i < params.length; i++) {
    65             String name = params[i] instanceof Parameter ?
    66                 ((Parameter) params[i]).name() :
    67                 ((TypeVariable) params[i]).typeName();
    68             result.put(name, String.valueOf(i));
    69         }
    70         return result;
    71     }
    73     /**
    74      * {@inheritDoc}
    75      */
    76     public void inherit(DocFinder.Input input, DocFinder.Output output) {
    77         if (input.tagId == null) {
    78             input.isTypeVariableParamTag = ((ParamTag) input.tag).isTypeParameter();
    79             Object[] parameters = input.isTypeVariableParamTag ?
    80                 (Object[]) ((MethodDoc) input.tag.holder()).typeParameters() :
    81                 (Object[]) ((MethodDoc) input.tag.holder()).parameters();
    82             String target = ((ParamTag) input.tag).parameterName();
    83             int i;
    84             for (i = 0; i < parameters.length; i++) {
    85                 String name = parameters[i] instanceof Parameter ?
    86                     ((Parameter) parameters[i]).name() :
    87                     ((TypeVariable) parameters[i]).typeName();
    88                 if (name.equals(target)) {
    89                     input.tagId = String.valueOf(i);
    90                     break;
    91                 }
    92             }
    93             if (i == parameters.length) {
    94                 //Someone used {@inheritDoc} on an invalid @param tag.
    95                 //We don't know where to inherit from.
    96                 //XXX: in the future when Configuration is available here,
    97                 //print a warning for this mistake.
    98                 return;
    99             }
   100         }
   101         ParamTag[] tags = input.isTypeVariableParamTag ?
   102             input.method.typeParamTags() : input.method.paramTags();
   103         Map rankMap = getRankMap(input.isTypeVariableParamTag ?
   104             (Object[]) input.method.typeParameters() :
   105             (Object[]) input.method.parameters());
   106         for (int i = 0; i < tags.length; i++) {
   107             if (rankMap.containsKey(tags[i].parameterName()) &&
   108                     rankMap.get(tags[i].parameterName()).equals((input.tagId))) {
   109                 output.holder = input.method;
   110                 output.holderTag = tags[i];
   111                 output.inlineTags = input.isFirstSentence ?
   112                     tags[i].firstSentenceTags() : tags[i].inlineTags();
   113                 return;
   114             }
   115         }
   116     }
   118     /**
   119      * {@inheritDoc}
   120      */
   121     public boolean inField() {
   122         return false;
   123     }
   125     /**
   126      * {@inheritDoc}
   127      */
   128     public boolean inMethod() {
   129         return true;
   130     }
   132     /**
   133      * {@inheritDoc}
   134      */
   135     public boolean inOverview() {
   136         return false;
   137     }
   139     /**
   140      * {@inheritDoc}
   141      */
   142     public boolean inPackage() {
   143         return false;
   144     }
   146     /**
   147      * {@inheritDoc}
   148      */
   149     public boolean inType() {
   150         return true;
   151     }
   153     /**
   154      * {@inheritDoc}
   155      */
   156     public boolean isInlineTag() {
   157         return false;
   158     }
   160     /**
   161      * Given an array of <code>ParamTag</code>s,return its string representation.
   162      * @param holder the member that holds the param tags.
   163      * @param writer the TagletWriter that will write this tag.
   164      * @return the TagletOutput representation of these <code>ParamTag</code>s.
   165      */
   166     public TagletOutput getTagletOutput(Doc holder, TagletWriter writer) {
   167         if (holder instanceof ExecutableMemberDoc) {
   168             ExecutableMemberDoc member = (ExecutableMemberDoc) holder;
   169             TagletOutput output = getTagletOutput(false, member, writer,
   170                 member.typeParameters(), member.typeParamTags());
   171             output.appendOutput(getTagletOutput(true, member, writer,
   172                 member.parameters(), member.paramTags()));
   173             return output;
   174         } else {
   175             ClassDoc classDoc = (ClassDoc) holder;
   176             return getTagletOutput(false, classDoc, writer,
   177                 classDoc.typeParameters(), classDoc.typeParamTags());
   178         }
   179     }
   181     /**
   182      * Given an array of <code>ParamTag</code>s,return its string representation.
   183      * Try to inherit the param tags that are missing.
   184      *
   185      * @param doc               the doc that holds the param tags.
   186      * @param writer            the TagletWriter that will write this tag.
   187      * @param formalParameters  The array of parmeters (from type or executable
   188      *                          member) to check.
   189      *
   190      * @return the TagletOutput representation of these <code>ParamTag</code>s.
   191      */
   192     private TagletOutput getTagletOutput(boolean isNonTypeParams, Doc holder,
   193             TagletWriter writer, Object[] formalParameters, ParamTag[] paramTags) {
   194         TagletOutput result = writer.getOutputInstance();
   195         Set<String> alreadyDocumented = new HashSet<String>();
   196         if (paramTags.length > 0) {
   197             result.appendOutput(
   198                 processParamTags(isNonTypeParams, paramTags,
   199                 getRankMap(formalParameters), writer, alreadyDocumented)
   200             );
   201         }
   202         if (alreadyDocumented.size() != formalParameters.length) {
   203             //Some parameters are missing corresponding @param tags.
   204             //Try to inherit them.
   205             result.appendOutput(getInheritedTagletOutput (isNonTypeParams, holder,
   206                 writer, formalParameters, alreadyDocumented));
   207         }
   208         return result;
   209     }
   211     /**
   212      * Loop through each indivitual parameter.  It it does not have a
   213      * corresponding param tag, try to inherit it.
   214      */
   215     private TagletOutput getInheritedTagletOutput(boolean isNonTypeParams, Doc holder,
   216             TagletWriter writer, Object[] formalParameters,
   217             Set<String> alreadyDocumented) {
   218         TagletOutput result = writer.getOutputInstance();
   219         if ((! alreadyDocumented.contains(null)) &&
   220                 holder instanceof MethodDoc) {
   221             for (int i = 0; i < formalParameters.length; i++) {
   222                 if (alreadyDocumented.contains(String.valueOf(i))) {
   223                     continue;
   224                 }
   225                 //This parameter does not have any @param documentation.
   226                 //Try to inherit it.
   227                 DocFinder.Output inheritedDoc =
   228                     DocFinder.search(new DocFinder.Input((MethodDoc) holder, this,
   229                         String.valueOf(i), ! isNonTypeParams));
   230                 if (inheritedDoc.inlineTags != null &&
   231                         inheritedDoc.inlineTags.length > 0) {
   232                     result.appendOutput(
   233                         processParamTag(isNonTypeParams, writer,
   234                             (ParamTag) inheritedDoc.holderTag,
   235                             isNonTypeParams ?
   236                                 ((Parameter) formalParameters[i]).name():
   237                                 ((TypeVariable) formalParameters[i]).typeName(),
   238                             alreadyDocumented.size() == 0));
   239                 }
   240                 alreadyDocumented.add(String.valueOf(i));
   241             }
   242         }
   243         return result;
   244     }
   246     /**
   247      * Given an array of <code>Tag</code>s representing this custom
   248      * tag, return its string representation.  Print a warning for param
   249      * tags that do not map to parameters.  Print a warning for param
   250      * tags that are duplicated.
   251      *
   252      * @param paramTags the array of <code>ParamTag</code>s to convert.
   253      * @param writer the TagletWriter that will write this tag.
   254      * @param alreadyDocumented the set of exceptions that have already
   255      *        been documented.
   256      * @param rankMap a {@link java.util.Map} which holds ordering
   257      *                    information about the parameters.
   258      * @param nameMap a {@link java.util.Map} which holds a mapping
   259      *                of a rank of a parameter to its name.  This is
   260      *                used to ensure that the right name is used
   261      *                when parameter documentation is inherited.
   262      * @return the TagletOutput representation of this <code>Tag</code>.
   263      */
   264     private TagletOutput processParamTags(boolean isNonTypeParams,
   265             ParamTag[] paramTags, Map rankMap, TagletWriter writer,
   266             Set<String> alreadyDocumented) {
   267         TagletOutput result = writer.getOutputInstance();
   268         if (paramTags.length > 0) {
   269             for (int i = 0; i < paramTags.length; ++i) {
   270                 ParamTag pt = paramTags[i];
   271                 String paramName = isNonTypeParams ?
   272                     pt.parameterName() : "<" + pt.parameterName() + ">";
   273                 if (! rankMap.containsKey(pt.parameterName())) {
   274                     writer.getMsgRetriever().warning(pt.position(),
   275                         isNonTypeParams ?
   276                             "doclet.Parameters_warn" :
   277                             "doclet.Type_Parameters_warn",
   278                         paramName);
   279                 }
   280                 String rank = (String) rankMap.get(pt.parameterName());
   281                 if (rank != null && alreadyDocumented.contains(rank)) {
   282                     writer.getMsgRetriever().warning(pt.position(),
   283                        isNonTypeParams ?
   284                            "doclet.Parameters_dup_warn" :
   285                            "doclet.Type_Parameters_dup_warn",
   286                        paramName);
   287                 }
   288                 result.appendOutput(processParamTag(isNonTypeParams, writer, pt,
   289                      pt.parameterName(), alreadyDocumented.size() == 0));
   290                 alreadyDocumented.add(rank);
   291             }
   292         }
   293         return result;
   294     }
   295     /**
   296      * Convert the individual ParamTag into TagletOutput.
   297      *
   298      * @param isNonTypeParams true if this is just a regular param tag.  False
   299      *                        if this is a type param tag.
   300      * @param writer          the taglet writer for output writing.
   301      * @param paramTag        the tag whose inline tags will be printed.
   302      * @param name            the name of the parameter.  We can't rely on
   303      *                        the name in the param tag because we might be
   304      *                        inheriting documentation.
   305      * @param isFirstParam    true if this is the first param tag being printed.
   306      *
   307      */
   308     private TagletOutput processParamTag(boolean isNonTypeParams,
   309             TagletWriter writer, ParamTag paramTag, String name,
   310             boolean isFirstParam) {
   311         TagletOutput result = writer.getOutputInstance();
   312         String header = writer.configuration().getText(
   313             isNonTypeParams ? "doclet.Parameters" : "doclet.TypeParameters");
   314         if (isFirstParam) {
   315             result.appendOutput(writer.getParamHeader(header));
   316         }
   317         result.appendOutput(writer.paramTagOutput(paramTag,
   318             name));
   319         return result;
   320     }
   321 }

mercurial