1 /* 2 * Copyright (c) 2003, 2019, 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 */ 25 26 package jdk.javadoc.internal.doclets.toolkit.taglets; 27 28 import java.util.List; 29 30 import javax.lang.model.element.Element; 31 import javax.lang.model.element.VariableElement; 32 import javax.lang.model.type.TypeMirror; 33 34 import com.sun.source.doctree.DocTree; 35 import jdk.javadoc.internal.doclets.toolkit.BaseConfiguration; 36 import jdk.javadoc.internal.doclets.toolkit.Content; 37 import jdk.javadoc.internal.doclets.toolkit.taglets.Taglet.UnsupportedTagletOperationException; 38 import jdk.javadoc.internal.doclets.toolkit.util.CommentHelper; 39 import jdk.javadoc.internal.doclets.toolkit.util.Utils; 40 41 /** 42 * The interface for the taglet writer. 43 * 44 * <p><b>This is NOT part of any supported API. 45 * If you write code that depends on this, you do so at your own risk. 46 * This code and its internal interfaces are subject to change or 47 * deletion without notice.</b> 48 * 49 * @author Jamie Ho 50 */ 51 52 public abstract class TagletWriter { 53 54 /** 55 * True if we only want to write the first sentence. 56 */ 57 protected final boolean isFirstSentence; 58 59 protected TagletWriter(boolean isFirstSentence) { 60 this.isFirstSentence = isFirstSentence; 61 } 62 63 /** 64 * @return an instance of an output object. 65 */ 66 public abstract Content getOutputInstance(); 67 68 /** 69 * Return the output for a {@code {@code ...}} tag. 70 * 71 * @param element 72 * @param tag the tag. 73 * @return the output of the taglet. 74 */ 75 protected abstract Content codeTagOutput(Element element, DocTree tag); 76 77 /** 78 * Return the output for a {@index...} tag. 79 * 80 * @param tag the tag. 81 * @return the output of the taglet. 82 */ 83 protected abstract Content indexTagOutput(Element element, DocTree tag); 84 85 /** 86 * Returns the output for the DocRoot inline tag. 87 * @return the output for the DocRoot inline tag. 88 */ 89 protected abstract Content getDocRootOutput(); 90 91 /** 92 * Return the deprecated tag output. 93 * 94 * @param element the element to write deprecated documentation for. 95 * @return the output of the deprecated tag. 96 */ 97 protected abstract Content deprecatedTagOutput(Element element); 98 99 /** 100 * Return the output for a {@code {@literal ...}} tag. 101 * 102 * @param element 103 * @param tag the tag. 104 * @return the output of the taglet. 105 */ 106 protected abstract Content literalTagOutput(Element element, DocTree tag); 107 108 /** 109 * Return the header for the param tags. 110 * 111 * @param header the header to display. 112 * @return the header for the param tags. 113 */ 114 protected abstract Content getParamHeader(String header); 115 116 /** 117 * Return the output for param tags. 118 * 119 * @param element 120 * @param paramTag the parameter to document. 121 * @param paramName the name of the parameter. 122 * @return the output of the param tag. 123 */ 124 protected abstract Content paramTagOutput(Element element, DocTree paramTag, String paramName); 125 126 /** 127 * Return the output for property tags. 128 * 129 * @param element 130 * @param propertyTag the parameter to document. 131 * @param prefix the text with which to prefix the property name. 132 * @return the output of the param tag. 133 */ 134 protected abstract Content propertyTagOutput(Element element, DocTree propertyTag, String prefix); 135 136 /** 137 * Return the return tag output. 138 * 139 * @param element 140 * @param returnTag the return tag to output. 141 * @return the output of the return tag. 142 */ 143 protected abstract Content returnTagOutput(Element element, DocTree returnTag); 144 145 /** 146 * Return the see tag output. 147 * 148 * @param holder 149 * @param seeTags the array of See tags. 150 * @return the output of the see tags. 151 */ 152 protected abstract Content seeTagOutput(Element holder, List<? extends DocTree> seeTags); 153 154 /** 155 * Return the output for a simple tag. 156 * 157 * @param element 158 * @param simpleTags the array of simple tags. 159 * @param header 160 * @return the output of the simple tags. 161 */ 162 protected abstract Content simpleTagOutput(Element element, List<? extends DocTree> simpleTags, String header); 163 164 /** 165 * Return the output for a simple tag. 166 * 167 * @param element 168 * @param simpleTag the simple tag. 169 * @param header 170 * @return the output of the simple tag. 171 */ 172 protected abstract Content simpleTagOutput(Element element, DocTree simpleTag, String header); 173 174 /** 175 * Return the system property tag output. 176 * 177 * @param element 178 * @param systemPropertyTag the system property tag 179 * @return the output of system property tag 180 */ 181 protected abstract Content systemPropertyTagOutput(Element element, DocTree systemPropertyTag); 182 183 /** 184 * Return the header for the throws tag. 185 * 186 * @return the header for the throws tag. 187 */ 188 protected abstract Content getThrowsHeader(); 189 190 /** 191 * Return the header for the throws tag. 192 * 193 * @param element 194 * @param throwsTag the throws tag. 195 * @return the output of the throws tag. 196 */ 197 protected abstract Content throwsTagOutput(Element element, DocTree throwsTag); 198 199 /** 200 * Return the output for the throws tag. 201 * 202 * @param throwsType the throws type. 203 * @return the output of the throws type. 204 */ 205 protected abstract Content throwsTagOutput(TypeMirror throwsType); 206 207 /** 208 * Return the output for the value tag. 209 * 210 * @param field the constant field that holds the value tag. 211 * @param constantVal the constant value to document. 212 * @param includeLink true if we should link the constant text to the 213 * constant field itself. 214 * @return the output of the value tag. 215 */ 216 protected abstract Content valueTagOutput(VariableElement field, 217 String constantVal, boolean includeLink); 218 219 /** 220 * Given an output object, append to it the tag documentation for 221 * the given member. 222 * 223 * @param tagletManager the manager that manages the taglets. 224 * @param element the Doc that we are print tags for. 225 * @param taglets the taglets to print. 226 * @param writer the writer that will generate the output strings. 227 * @param output the output buffer to store the output in. 228 */ 229 public static void genTagOutput(TagletManager tagletManager, Element element, 230 List<Taglet> taglets, TagletWriter writer, Content output) { 231 Utils utils = writer.configuration().utils; 232 tagletManager.checkTags(element, utils.getBlockTags(element), false); 233 tagletManager.checkTags(element, utils.getFullBody(element), true); 234 for (Taglet taglet : taglets) { 235 if (utils.isTypeElement(element) && taglet instanceof ParamTaglet) { 236 //The type parameters are documented in a special section away 237 //from the tag info, so skip here. 238 continue; 239 } 240 if (taglet instanceof DeprecatedTaglet) { 241 //Deprecated information is documented "inline", not in tag info 242 //section. 243 continue; 244 } 245 if (taglet instanceof SimpleTaglet && !((SimpleTaglet) taglet).enabled) { 246 // taglet has been disabled 247 continue; 248 } 249 Content currentOutput = null; 250 try { 251 currentOutput = taglet.getTagletOutput(element, writer); 252 } catch (UnsupportedTagletOperationException utoe) { 253 //The taglet does not take a member as an argument. Let's try 254 //a single tag. 255 List<? extends DocTree> tags = utils.getBlockTags(element, taglet.getName()); 256 if (!tags.isEmpty()) { 257 currentOutput = taglet.getTagletOutput(element, tags.get(0), writer); 258 } 259 } 260 if (currentOutput != null) { 261 tagletManager.seenCustomTag(taglet.getName()); 262 output.add(currentOutput); 263 } 264 } 265 } 266 /** 267 * Given an inline tag, return its output. 268 * @param holder 269 * @param tagletManager The taglet manager for the current doclet. 270 * @param holderTag The tag this holds this inline tag. Null if there 271 * is no tag that holds it. 272 * @param inlineTag The inline tag to be documented. 273 * @param tagletWriter The taglet writer to write the output. 274 * @return The output of the inline tag. 275 */ 276 public static Content getInlineTagOutput(Element holder, TagletManager tagletManager, 277 DocTree holderTag, DocTree inlineTag, TagletWriter tagletWriter) { 278 List<Taglet> definedTags = tagletManager.getInlineTaglets(); 279 CommentHelper ch = tagletWriter.configuration().utils.getCommentHelper(holder); 280 final String inlineTagName = ch.getTagName(inlineTag); 281 //This is a custom inline tag. 282 for (Taglet definedTag : definedTags) { 283 if ((definedTag.getName()).equals(inlineTagName)) { 284 // Given a name of a seen custom tag, remove it from the 285 // set of unseen custom tags. 286 tagletManager.seenCustomTag(definedTag.getName()); 287 Content output = definedTag.getTagletOutput(holder, 288 holderTag != null && 289 definedTag.getName().equals("inheritDoc") ? 290 holderTag : inlineTag, tagletWriter); 291 return output; 292 } 293 } 294 return null; 295 } 296 297 /** 298 * Converts inline tags and text to TagOutput, expanding the 299 * inline tags along the way. Called wherever text can contain 300 * an inline tag, such as in comments or in free-form text arguments 301 * to non-inline tags. 302 * 303 * @param holderTag the tag that holds the documentation. 304 * @param tags array of text tags and inline tags (often alternating) 305 * present in the text of interest for this doc. 306 * @return the {@link Content} representing the comments. 307 */ 308 public abstract Content commentTagsToOutput(DocTree holderTag, List<? extends DocTree> tags); 309 310 /** 311 * Converts inline tags and text to TagOutput, expanding the 312 * inline tags along the way. Called wherever text can contain 313 * an inline tag, such as in comments or in free-form text arguments 314 * to non-inline tags. 315 * 316 * @param holder the element where comment resides. 317 * @param tags array of text tags and inline tags (often alternating) 318 * present in the text of interest for this doc. 319 * @return the {@link Content} representing the comments. 320 */ 321 public abstract Content commentTagsToOutput(Element holder, List<? extends DocTree> tags); 322 323 /** 324 * Converts inline tags and text to TagOutput, expanding the 325 * inline tags along the way. Called wherever text can contain 326 * an inline tag, such as in comments or in free-form text arguments 327 * to non-inline tags. 328 * 329 * @param holderTag the tag that holds the documentation. 330 * @param holder the element where comment resides. 331 * @param tags array of text tags and inline tags (often alternating) 332 * present in the text of interest for this doc. 333 * @param isFirstSentence true if this is the first sentence. 334 * @return the {@link Content} representing the comments. 335 */ 336 public abstract Content commentTagsToOutput(DocTree holderTag, 337 Element holder, List<? extends DocTree> tags, boolean isFirstSentence); 338 339 /** 340 * @return an instance of the configuration used for this doclet. 341 */ 342 public abstract BaseConfiguration configuration(); 343 }