CommentUtils.java revision 3233:b5d08bc0d224
1129203Scognet/*
2129203Scognet * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
3129203Scognet * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4129203Scognet *
5129203Scognet * This code is free software; you can redistribute it and/or modify it
6129203Scognet * under the terms of the GNU General Public License version 2 only, as
7129203Scognet * published by the Free Software Foundation.  Oracle designates this
8129203Scognet * particular file as subject to the "Classpath" exception as provided
9129203Scognet * by Oracle in the LICENSE file that accompanied this code.
10129203Scognet *
11129203Scognet * This code is distributed in the hope that it will be useful, but WITHOUT
12129203Scognet * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13129203Scognet * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14129203Scognet * version 2 for more details (a copy is included in the LICENSE file that
15129203Scognet * accompanied this code).
16129203Scognet *
17129203Scognet * You should have received a copy of the GNU General Public License version
18129203Scognet * 2 along with this work; if not, write to the Free Software Foundation,
19129203Scognet * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20129203Scognet *
21129203Scognet * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22129203Scognet * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26/**
27 *  A utility class.
28 *
29 *  <p><b>This is NOT part of any supported API.
30 *  If you write code that depends on this, you do so at your own risk.
31 *  This code and its internal interfaces are subject to change or
32 *  deletion without notice.</b>
33 */
34
35package jdk.javadoc.internal.doclets.toolkit;
36
37import com.sun.source.doctree.DocCommentTree;
38import com.sun.source.doctree.DocTree;
39import com.sun.source.doctree.IdentifierTree;
40import com.sun.source.doctree.ReferenceTree;
41import com.sun.source.doctree.TextTree;
42import com.sun.source.util.DocTreeFactory;
43import com.sun.source.util.DocTreePath;
44import com.sun.source.util.DocTrees;
45import com.sun.source.util.TreePath;
46import java.util.ArrayList;
47import java.util.HashMap;
48import java.util.List;
49import javax.lang.model.element.Element;
50import javax.lang.model.element.ElementKind;
51import javax.lang.model.element.ExecutableElement;
52import javax.lang.model.element.Name;
53import javax.lang.model.element.PackageElement;
54import javax.lang.model.element.VariableElement;
55import javax.lang.model.util.Elements;
56import javax.tools.FileObject;
57import jdk.javadoc.internal.doclets.toolkit.util.Utils;
58
59public class CommentUtils {
60
61    final Configuration configuration;
62    final DocTreeFactory treeFactory;
63    final HashMap<Element, DocCommentDuo> dcTreesMap = new HashMap<>();
64    final DocTrees trees;
65    final Elements elementUtils;
66
67    protected CommentUtils(Configuration configuration) {
68        this.configuration = configuration;
69        trees = configuration.root.getDocTrees();
70        treeFactory = trees.getDocTreeFactory();
71        elementUtils = configuration.root.getElementUtils();
72    }
73
74    public List<? extends DocTree> makePropertyDescriptionTree(List<? extends DocTree> content) {
75        List<DocTree> out = new ArrayList<>();
76        Name name = elementUtils.getName("propertyDescription");
77        out.add(treeFactory.newUnknownBlockTagTree(name, content));
78        return out;
79    }
80
81    public List<? extends DocTree> makePropertyDescriptionTree(String content) {
82        List<DocTree> inlist = new ArrayList<>();
83        inlist.add(treeFactory.newCommentTree(content));
84        List<DocTree> out = new ArrayList<>();
85        Name name = elementUtils.getName("propertyDescription");
86        out.add(treeFactory.newUnknownBlockTagTree(name, inlist));
87        return out;
88    }
89
90    public List<? extends DocTree> makeFirstSentenceTree(String content) {
91        List<DocTree> out = new ArrayList<>();
92        out.add(treeFactory.newTextTree(content));
93        return out;
94    }
95
96    public DocTree makeSeeTree(String sig, Element e) {
97        List<DocTree> list = new ArrayList<>();
98        list.add(treeFactory.newReferenceTree(sig));
99        return treeFactory.newSeeTree(list);
100    }
101
102    public DocTree makeTextTree(String content) {
103        TextTree text = treeFactory.newTextTree(content);
104        return (DocTree) text;
105    }
106
107    public void setEnumValuesTree(Configuration config, Element e) {
108        Utils utils = config.utils;
109        String klassName = utils.getSimpleName(utils.getEnclosingTypeElement(e));
110
111        List<DocTree> fs = new ArrayList<>();
112        fs.add(treeFactory.newTextTree(config.getText("doclet.enum_values_doc.firstsentence")));
113
114        List<DocTree> body = new ArrayList<>();
115        body.add(treeFactory.newTextTree(config.getText("doclet.enum_values_doc.body", klassName)));
116
117        List<DocTree> descriptions = new ArrayList<>();
118        descriptions.add(treeFactory.newTextTree(config.getText("doclet.enum_values_doc.return")));
119
120        List<DocTree> tags = new ArrayList<>();
121        tags.add(treeFactory.newReturnTree(descriptions));
122        DocCommentTree docTree = treeFactory.newDocCommentTree(fs, body, tags);
123        dcTreesMap.put(e, new DocCommentDuo(null, docTree));
124    }
125
126    public void setEnumValueOfTree(Configuration config, Element e) {
127        List<DocTree> fs = new ArrayList<>();
128        fs.add(treeFactory.newTextTree(config.getText("doclet.enum_valueof_doc.firstsentence")));
129
130        List<DocTree> body = new ArrayList<>();
131        body.add(treeFactory.newTextTree(config.getText("doclet.enum_valueof_doc.body")));
132
133        List<DocTree> tags = new ArrayList<>();
134
135        List<DocTree> paramDescs = new ArrayList<>();
136        paramDescs.add(treeFactory.newTextTree(config.getText("doclet.enum_valueof_doc.param_name")));
137        ExecutableElement ee = (ExecutableElement) e;
138        java.util.List<? extends VariableElement> parameters = ee.getParameters();
139        VariableElement param = parameters.get(0);
140        IdentifierTree id = treeFactory.newIdentifierTree(elementUtils.getName(param.getSimpleName().toString()));
141        tags.add(treeFactory.newParamTree(false, id, paramDescs));
142
143        List<DocTree> returnDescs = new ArrayList<>();
144        returnDescs.add(treeFactory.newTextTree(config.getText("doclet.enum_valueof_doc.return")));
145        tags.add(treeFactory.newReturnTree(returnDescs));
146
147        List<DocTree> throwsDescs = new ArrayList<>();
148        throwsDescs.add(treeFactory.newTextTree(config.getText("doclet.enum_valueof_doc.throws_ila")));
149
150        ReferenceTree ref = treeFactory.newReferenceTree("java.lang.IllegalArgumentException");
151        tags.add(treeFactory.newThrowsTree(ref, throwsDescs));
152
153        throwsDescs = new ArrayList<>();
154        throwsDescs.add(treeFactory.newTextTree(config.getText("doclet.enum_valueof_doc.throws_npe")));
155
156        ref = treeFactory.newReferenceTree("java.lang.NullPointerException");
157        tags.add(treeFactory.newThrowsTree(ref, throwsDescs));
158
159        DocCommentTree docTree = treeFactory.newDocCommentTree(fs, body, tags);
160
161        dcTreesMap.put(e, new DocCommentDuo(null, docTree));
162    }
163
164    /*
165     * Returns the TreePath/DocCommentTree duo for synthesized element.
166     */
167    public DocCommentDuo getSyntheticCommentDuo(Element e) {
168        return dcTreesMap.get(e);
169    }
170
171    /*
172     * Returns the TreePath/DocCommentTree duo for html sources.
173     */
174    public DocCommentDuo getHtmlCommentDuo(Element e) {
175        FileObject fo = null;
176        if (e.getKind().equals(ElementKind.OTHER)) {
177            fo = configuration.getOverviewPath();
178        } else if (e.getKind().equals(ElementKind.PACKAGE)) {
179            fo = configuration.workArounds.getJavaFileObject((PackageElement)e);
180        }
181        if (fo == null) {
182            return null;
183        }
184
185        DocCommentTree dcTree = trees.getDocCommentTree(fo);
186        if (dcTree == null) {
187            return null;
188        }
189        DocTreePath treePath = trees.getDocTreePath(fo);
190        return new DocCommentDuo(treePath.getTreePath(), dcTree);
191    }
192
193    public void setDocCommentTree(Element element, List<DocTree> firstSentence,
194            List<DocTree> bodyTags, List<DocTree> blockTags, Utils utils) {
195        DocCommentTree docTree = treeFactory.newDocCommentTree(firstSentence,
196                                                      bodyTags,
197                                                      blockTags);
198        dcTreesMap.put(element, new DocCommentDuo(null, docTree));
199        // There maybe an entry with the original comments usually null,
200        // therefore remove that entry if it exists, and allow a new one
201        // to be reestablished.
202        utils.removeCommentHelper(element);
203    }
204
205    /**
206     * A simplistic container to transport a TreePath, DocCommentTree pair.
207     * Here is why we need this:
208     * a. not desirable to add javac's pair.
209     * b. DocTreePath is not a viable  option either, as a null TreePath is required
210     * to represent synthetic comments for Enum.values, valuesOf, javafx properties.
211     */
212    public static class DocCommentDuo {
213        public final TreePath treePath;
214        public final DocCommentTree dcTree;
215
216        public DocCommentDuo(TreePath treePath, DocCommentTree dcTree) {
217            this.treePath = treePath;
218            this.dcTree = dcTree;
219        }
220    }
221}
222