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

Mon, 25 Mar 2013 16:55:14 -0700

author
mfang
date
Mon, 25 Mar 2013 16:55:14 -0700
changeset 1658
fdf30b225e1c
parent 1359
25e14ad23cef
child 1724
d918b63a5509
permissions
-rw-r--r--

8010521: jdk8 l10n resource file translation update 2
Reviewed-by: naoto, yhuang

     1 /*
     2  * Copyright (c) 2001, 2012, Oracle and/or its affiliates. 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.  Oracle designates this
     8  * particular file as subject to the "Classpath" exception as provided
     9  * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    22  * or visit www.oracle.com if you need additional information or have any
    23  * questions.
    24  */
    26 package com.sun.tools.doclets.internal.toolkit.taglets;
    28 import java.util.*;
    30 import com.sun.javadoc.*;
    31 import com.sun.tools.doclets.internal.toolkit.util.*;
    33 /**
    34  * A taglet that represents the @param tag.
    35  *
    36  *  <p><b>This is NOT part of any supported API.
    37  *  If you write code that depends on this, you do so at your own risk.
    38  *  This code and its internal interfaces are subject to change or
    39  *  deletion without notice.</b>
    40  *
    41  * @author Jamie Ho
    42  * @since 1.4
    43  */
    44 public class ParamTaglet extends BaseTaglet implements InheritableTaglet {
    46     /**
    47      * Construct a ParamTaglet.
    48      */
    49     public ParamTaglet() {
    50         name = "param";
    51     }
    53     /**
    54      * Given an array of <code>Parameter</code>s, return
    55      * a name/rank number map.  If the array is null, then
    56      * null is returned.
    57      * @param params The array of parmeters (from type or executable member) to
    58      *               check.
    59      * @return a name-rank number map.
    60      */
    61     private static Map<String,String> getRankMap(Object[] params){
    62         if (params == null) {
    63             return null;
    64         }
    65         HashMap<String,String> result = new HashMap<String,String>();
    66         for (int i = 0; i < params.length; i++) {
    67             String name = params[i] instanceof Parameter ?
    68                 ((Parameter) params[i]).name() :
    69                 ((TypeVariable) params[i]).typeName();
    70             result.put(name, String.valueOf(i));
    71         }
    72         return result;
    73     }
    75     /**
    76      * {@inheritDoc}
    77      */
    78     public void inherit(DocFinder.Input input, DocFinder.Output output) {
    79         if (input.tagId == null) {
    80             input.isTypeVariableParamTag = ((ParamTag) input.tag).isTypeParameter();
    81             Object[] parameters = input.isTypeVariableParamTag ?
    82                 (Object[]) ((MethodDoc) input.tag.holder()).typeParameters() :
    83                 (Object[]) ((MethodDoc) input.tag.holder()).parameters();
    84             String target = ((ParamTag) input.tag).parameterName();
    85             int i;
    86             for (i = 0; i < parameters.length; i++) {
    87                 String name = parameters[i] instanceof Parameter ?
    88                     ((Parameter) parameters[i]).name() :
    89                     ((TypeVariable) parameters[i]).typeName();
    90                 if (name.equals(target)) {
    91                     input.tagId = String.valueOf(i);
    92                     break;
    93                 }
    94             }
    95             if (i == parameters.length) {
    96                 //Someone used {@inheritDoc} on an invalid @param tag.
    97                 //We don't know where to inherit from.
    98                 //XXX: in the future when Configuration is available here,
    99                 //print a warning for this mistake.
   100                 return;
   101             }
   102         }
   103         ParamTag[] tags = input.isTypeVariableParamTag ?
   104             input.method.typeParamTags() : input.method.paramTags();
   105         Map<String, String> rankMap = getRankMap(input.isTypeVariableParamTag ?
   106             (Object[]) input.method.typeParameters() :
   107             (Object[]) input.method.parameters());
   108         for (int i = 0; i < tags.length; i++) {
   109             if (rankMap.containsKey(tags[i].parameterName()) &&
   110                     rankMap.get(tags[i].parameterName()).equals((input.tagId))) {
   111                 output.holder = input.method;
   112                 output.holderTag = tags[i];
   113                 output.inlineTags = input.isFirstSentence ?
   114                     tags[i].firstSentenceTags() : tags[i].inlineTags();
   115                 return;
   116             }
   117         }
   118     }
   120     /**
   121      * {@inheritDoc}
   122      */
   123     public boolean inField() {
   124         return false;
   125     }
   127     /**
   128      * {@inheritDoc}
   129      */
   130     public boolean inMethod() {
   131         return true;
   132     }
   134     /**
   135      * {@inheritDoc}
   136      */
   137     public boolean inOverview() {
   138         return false;
   139     }
   141     /**
   142      * {@inheritDoc}
   143      */
   144     public boolean inPackage() {
   145         return false;
   146     }
   148     /**
   149      * {@inheritDoc}
   150      */
   151     public boolean inType() {
   152         return true;
   153     }
   155     /**
   156      * {@inheritDoc}
   157      */
   158     public boolean isInlineTag() {
   159         return false;
   160     }
   162     /**
   163      * Given an array of <code>ParamTag</code>s,return its string representation.
   164      * @param holder the member that holds the param tags.
   165      * @param writer the TagletWriter that will write this tag.
   166      * @return the TagletOutput representation of these <code>ParamTag</code>s.
   167      */
   168     public TagletOutput getTagletOutput(Doc holder, TagletWriter writer) {
   169         if (holder instanceof ExecutableMemberDoc) {
   170             ExecutableMemberDoc member = (ExecutableMemberDoc) holder;
   171             TagletOutput output = getTagletOutput(false, member, writer,
   172                 member.typeParameters(), member.typeParamTags());
   173             output.appendOutput(getTagletOutput(true, member, writer,
   174                 member.parameters(), member.paramTags()));
   175             return output;
   176         } else {
   177             ClassDoc classDoc = (ClassDoc) holder;
   178             return getTagletOutput(false, classDoc, writer,
   179                 classDoc.typeParameters(), classDoc.typeParamTags());
   180         }
   181     }
   183     /**
   184      * Given an array of <code>ParamTag</code>s,return its string representation.
   185      * Try to inherit the param tags that are missing.
   186      *
   187      * @param holder            the doc that holds the param tags.
   188      * @param writer            the TagletWriter that will write this tag.
   189      * @param formalParameters  The array of parmeters (from type or executable
   190      *                          member) to check.
   191      *
   192      * @return the TagletOutput representation of these <code>ParamTag</code>s.
   193      */
   194     private TagletOutput getTagletOutput(boolean isNonTypeParams, Doc holder,
   195             TagletWriter writer, Object[] formalParameters, ParamTag[] paramTags) {
   196         TagletOutput result = writer.getOutputInstance();
   197         Set<String> alreadyDocumented = new HashSet<String>();
   198         if (paramTags.length > 0) {
   199             result.appendOutput(
   200                 processParamTags(isNonTypeParams, paramTags,
   201                 getRankMap(formalParameters), writer, alreadyDocumented)
   202             );
   203         }
   204         if (alreadyDocumented.size() != formalParameters.length) {
   205             //Some parameters are missing corresponding @param tags.
   206             //Try to inherit them.
   207             result.appendOutput(getInheritedTagletOutput (isNonTypeParams, holder,
   208                 writer, formalParameters, alreadyDocumented));
   209         }
   210         return result;
   211     }
   213     /**
   214      * Loop through each indivitual parameter.  It it does not have a
   215      * corresponding param tag, try to inherit it.
   216      */
   217     private TagletOutput getInheritedTagletOutput(boolean isNonTypeParams, Doc holder,
   218             TagletWriter writer, Object[] formalParameters,
   219             Set<String> alreadyDocumented) {
   220         TagletOutput result = writer.getOutputInstance();
   221         if ((! alreadyDocumented.contains(null)) &&
   222                 holder instanceof MethodDoc) {
   223             for (int i = 0; i < formalParameters.length; i++) {
   224                 if (alreadyDocumented.contains(String.valueOf(i))) {
   225                     continue;
   226                 }
   227                 //This parameter does not have any @param documentation.
   228                 //Try to inherit it.
   229                 DocFinder.Output inheritedDoc =
   230                     DocFinder.search(new DocFinder.Input((MethodDoc) holder, this,
   231                         String.valueOf(i), ! isNonTypeParams));
   232                 if (inheritedDoc.inlineTags != null &&
   233                         inheritedDoc.inlineTags.length > 0) {
   234                     result.appendOutput(
   235                         processParamTag(isNonTypeParams, writer,
   236                             (ParamTag) inheritedDoc.holderTag,
   237                             isNonTypeParams ?
   238                                 ((Parameter) formalParameters[i]).name():
   239                                 ((TypeVariable) formalParameters[i]).typeName(),
   240                             alreadyDocumented.size() == 0));
   241                 }
   242                 alreadyDocumented.add(String.valueOf(i));
   243             }
   244         }
   245         return result;
   246     }
   248     /**
   249      * Given an array of <code>Tag</code>s representing this custom
   250      * tag, return its string representation.  Print a warning for param
   251      * tags that do not map to parameters.  Print a warning for param
   252      * tags that are duplicated.
   253      *
   254      * @param paramTags the array of <code>ParamTag</code>s to convert.
   255      * @param writer the TagletWriter that will write this tag.
   256      * @param alreadyDocumented the set of exceptions that have already
   257      *        been documented.
   258      * @param rankMap a {@link java.util.Map} which holds ordering
   259      *                    information about the parameters.
   260      * @param rankMap a {@link java.util.Map} which holds a mapping
   261      *                of a rank of a parameter to its name.  This is
   262      *                used to ensure that the right name is used
   263      *                when parameter documentation is inherited.
   264      * @return the TagletOutput representation of this <code>Tag</code>.
   265      */
   266     private TagletOutput processParamTags(boolean isNonTypeParams,
   267             ParamTag[] paramTags, Map<String, String> rankMap, TagletWriter writer,
   268             Set<String> alreadyDocumented) {
   269         TagletOutput result = writer.getOutputInstance();
   270         if (paramTags.length > 0) {
   271             for (int i = 0; i < paramTags.length; ++i) {
   272                 ParamTag pt = paramTags[i];
   273                 String paramName = isNonTypeParams ?
   274                     pt.parameterName() : "<" + pt.parameterName() + ">";
   275                 if (! rankMap.containsKey(pt.parameterName())) {
   276                     writer.getMsgRetriever().warning(pt.position(),
   277                         isNonTypeParams ?
   278                             "doclet.Parameters_warn" :
   279                             "doclet.Type_Parameters_warn",
   280                         paramName);
   281                 }
   282                 String rank = rankMap.get(pt.parameterName());
   283                 if (rank != null && alreadyDocumented.contains(rank)) {
   284                     writer.getMsgRetriever().warning(pt.position(),
   285                        isNonTypeParams ?
   286                            "doclet.Parameters_dup_warn" :
   287                            "doclet.Type_Parameters_dup_warn",
   288                        paramName);
   289                 }
   290                 result.appendOutput(processParamTag(isNonTypeParams, writer, pt,
   291                      pt.parameterName(), alreadyDocumented.size() == 0));
   292                 alreadyDocumented.add(rank);
   293             }
   294         }
   295         return result;
   296     }
   297     /**
   298      * Convert the individual ParamTag into TagletOutput.
   299      *
   300      * @param isNonTypeParams true if this is just a regular param tag.  False
   301      *                        if this is a type param tag.
   302      * @param writer          the taglet writer for output writing.
   303      * @param paramTag        the tag whose inline tags will be printed.
   304      * @param name            the name of the parameter.  We can't rely on
   305      *                        the name in the param tag because we might be
   306      *                        inheriting documentation.
   307      * @param isFirstParam    true if this is the first param tag being printed.
   308      *
   309      */
   310     private TagletOutput processParamTag(boolean isNonTypeParams,
   311             TagletWriter writer, ParamTag paramTag, String name,
   312             boolean isFirstParam) {
   313         TagletOutput result = writer.getOutputInstance();
   314         String header = writer.configuration().getText(
   315             isNonTypeParams ? "doclet.Parameters" : "doclet.TypeParameters");
   316         if (isFirstParam) {
   317             result.appendOutput(writer.getParamHeader(header));
   318         }
   319         result.appendOutput(writer.paramTagOutput(paramTag,
   320             name));
   321         return result;
   322     }
   323 }

mercurial