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

Wed, 27 Apr 2016 01:34:52 +0800

author
aoqi
date
Wed, 27 Apr 2016 01:34:52 +0800
changeset 0
959103a6100f
child 2525
2eb010b6cb22
permissions
-rw-r--r--

Initial load
http://hg.openjdk.java.net/jdk8u/jdk8u/langtools/
changeset: 2573:53ca196be1ae
tag: jdk8u25-b17

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

mercurial