TagletWriter.java revision 3692:87b48a8fb3cf
1/*
2 * Copyright (c) 2003, 2016, 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
26package jdk.javadoc.internal.doclets.toolkit.taglets;
27
28import java.util.List;
29
30import javax.lang.model.element.Element;
31import javax.lang.model.element.VariableElement;
32import javax.lang.model.type.TypeMirror;
33
34import com.sun.source.doctree.DocTree;
35import jdk.javadoc.internal.doclets.toolkit.Configuration;
36import jdk.javadoc.internal.doclets.toolkit.Content;
37import jdk.javadoc.internal.doclets.toolkit.taglets.Taglet.UnsupportedTagletOperationException;
38import jdk.javadoc.internal.doclets.toolkit.util.CommentHelper;
39import 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
52public 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 header for the throws tag.
176     *
177     * @return the header for the throws tag.
178     */
179    protected abstract Content getThrowsHeader();
180
181    /**
182     * Return the header for the throws tag.
183     *
184     * @param element
185     * @param throwsTag the throws tag.
186     * @return the output of the throws tag.
187     */
188    protected abstract Content throwsTagOutput(Element element, DocTree throwsTag);
189
190    /**
191     * Return the output for the throws tag.
192     *
193     * @param throwsType the throws type.
194     * @return the output of the throws type.
195     */
196    protected abstract Content throwsTagOutput(TypeMirror throwsType);
197
198    /**
199     * Return the output for the value tag.
200     *
201     * @param field       the constant field that holds the value tag.
202     * @param constantVal the constant value to document.
203     * @param includeLink true if we should link the constant text to the
204     *                    constant field itself.
205     * @return the output of the value tag.
206     */
207    protected abstract Content valueTagOutput(VariableElement field,
208        String constantVal, boolean includeLink);
209
210    /**
211     * Given an output object, append to it the tag documentation for
212     * the given member.
213     *
214     * @param tagletManager the manager that manages the taglets.
215     * @param element the Doc that we are print tags for.
216     * @param taglets the taglets to print.
217     * @param writer the writer that will generate the output strings.
218     * @param output the output buffer to store the output in.
219     */
220    public static void genTagOutput(TagletManager tagletManager, Element element,
221            List<Taglet> taglets, TagletWriter writer, Content output) {
222        Utils utils = writer.configuration().utils;
223        tagletManager.checkTags(utils, element, utils.getBlockTags(element), false);
224        tagletManager.checkTags(utils, element, utils.getFullBody(element), true);
225        for (Taglet taglet : taglets) {
226            if (utils.isTypeElement(element) && taglet instanceof ParamTaglet) {
227                //The type parameters are documented in a special section away
228                //from the tag info, so skip here.
229                continue;
230            }
231            if (taglet instanceof DeprecatedTaglet) {
232                //Deprecated information is documented "inline", not in tag info
233                //section.
234                continue;
235            }
236            Content currentOutput = null;
237            try {
238                currentOutput = taglet.getTagletOutput(element, writer);
239            } catch (UnsupportedTagletOperationException utoe) {
240                //The taglet does not take a member as an argument.  Let's try
241                //a single tag.
242                List<? extends DocTree> tags = utils.getBlockTags(element, taglet.getName());
243                if (!tags.isEmpty()) {
244                    currentOutput = taglet.getTagletOutput(element, tags.get(0), writer);
245                }
246            }
247            if (currentOutput != null) {
248                tagletManager.seenCustomTag(taglet.getName());
249                output.addContent(currentOutput);
250            }
251        }
252    }
253    /**
254     * Given an inline tag, return its output.
255     * @param holder
256     * @param tagletManager The taglet manager for the current doclet.
257     * @param holderTag The tag this holds this inline tag.  Null if there
258     * is no tag that holds it.
259     * @param inlineTag The inline tag to be documented.
260     * @param tagletWriter The taglet writer to write the output.
261     * @return The output of the inline tag.
262     */
263    public static Content getInlineTagOutput(Element holder, TagletManager tagletManager,
264            DocTree holderTag, DocTree inlineTag, TagletWriter tagletWriter) {
265        List<Taglet> definedTags = tagletManager.getInlineCustomTaglets();
266        CommentHelper ch = tagletWriter.configuration().utils.getCommentHelper(holder);
267        final String inlineTagName = ch.getTagName(inlineTag);
268        //This is a custom inline tag.
269        for (Taglet definedTag : definedTags) {
270            if ((definedTag.getName()).equals(inlineTagName)) {
271                // Given a name of a seen custom tag, remove it from the
272                // set of unseen custom tags.
273                tagletManager.seenCustomTag(definedTag.getName());
274                Content output = definedTag.getTagletOutput(holder,
275                        holderTag != null &&
276                        definedTag.getName().equals("inheritDoc") ?
277                        holderTag : inlineTag, tagletWriter);
278                return output;
279            }
280        }
281        return null;
282    }
283
284    /**
285     * Converts inline tags and text to TagOutput, expanding the
286     * inline tags along the way.  Called wherever text can contain
287     * an inline tag, such as in comments or in free-form text arguments
288     * to non-inline tags.
289     *
290     * @param holderTag the tag that holds the documentation.
291     * @param tags   array of text tags and inline tags (often alternating)
292     *               present in the text of interest for this doc.
293     * @return the {@link Content} representing the comments.
294     */
295    public abstract Content commentTagsToOutput(DocTree holderTag, List<? extends DocTree> tags);
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 holder the element where comment resides.
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(Element holder, 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 holderTag the tag that holds the documentation.
317     * @param holder the element where comment resides.
318     * @param tags   array of text tags and inline tags (often alternating)
319     *               present in the text of interest for this doc.
320     * @param isFirstSentence true if this is the first sentence.
321     * @return the {@link Content} representing the comments.
322     */
323    public abstract Content commentTagsToOutput(DocTree holderTag,
324        Element holder, List<? extends DocTree> tags, boolean isFirstSentence);
325
326    /**
327     * @return an instance of the configuration used for this doclet.
328     */
329    public abstract Configuration configuration();
330}
331