CommentUtils.java revision 3896:8e4dbcb99277
1/*
2 * Copyright (c) 2015, 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
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 java.net.URI;
38
39import com.sun.source.doctree.DocCommentTree;
40import com.sun.source.doctree.DocTree;
41import com.sun.source.doctree.IdentifierTree;
42import com.sun.source.doctree.ReferenceTree;
43import com.sun.source.doctree.TextTree;
44import com.sun.source.util.DocTreeFactory;
45import com.sun.source.util.DocTreePath;
46import com.sun.source.util.DocTrees;
47import com.sun.source.util.TreePath;
48
49import java.util.ArrayList;
50import java.util.HashMap;
51import java.util.List;
52
53import javax.lang.model.element.Element;
54import javax.lang.model.element.ElementKind;
55import javax.lang.model.element.ExecutableElement;
56import javax.lang.model.element.Name;
57import javax.lang.model.element.PackageElement;
58import javax.lang.model.element.VariableElement;
59import javax.lang.model.util.Elements;
60import javax.tools.FileObject;
61import javax.tools.JavaFileObject;
62import javax.tools.SimpleJavaFileObject;
63
64import com.sun.tools.javac.util.DefinedBy;
65import com.sun.tools.javac.util.DefinedBy.Api;
66import jdk.javadoc.internal.doclets.toolkit.util.Utils;
67
68public class CommentUtils {
69
70    final Configuration configuration;
71    final DocTreeFactory treeFactory;
72    final HashMap<Element, DocCommentDuo> dcTreesMap = new HashMap<>();
73    final DocTrees trees;
74    final Elements elementUtils;
75
76    protected CommentUtils(Configuration configuration) {
77        this.configuration = configuration;
78        trees = configuration.docEnv.getDocTrees();
79        treeFactory = trees.getDocTreeFactory();
80        elementUtils = configuration.docEnv.getElementUtils();
81    }
82
83    public List<? extends DocTree> makePropertyDescriptionTree(List<? extends DocTree> content) {
84        List<DocTree> out = new ArrayList<>();
85        Name name = elementUtils.getName("propertyDescription");
86        out.add(treeFactory.newUnknownBlockTagTree(name, content));
87        return out;
88    }
89
90    public List<? extends DocTree> makePropertyDescriptionTree(String content) {
91        List<DocTree> inlist = new ArrayList<>();
92        inlist.add(treeFactory.newCommentTree(content));
93        List<DocTree> out = new ArrayList<>();
94        Name name = elementUtils.getName("propertyDescription");
95        out.add(treeFactory.newUnknownBlockTagTree(name, inlist));
96        return out;
97    }
98
99    public List<? extends DocTree> makeFirstSentenceTree(String content) {
100        List<DocTree> out = new ArrayList<>();
101        out.add(treeFactory.newTextTree(content));
102        return out;
103    }
104
105    public DocTree makeSeeTree(String sig, Element e) {
106        List<DocTree> list = new ArrayList<>();
107        list.add(treeFactory.newReferenceTree(sig));
108        return treeFactory.newSeeTree(list);
109    }
110
111    public DocTree makeTextTree(String content) {
112        TextTree text = treeFactory.newTextTree(content);
113        return (DocTree) text;
114    }
115
116    public void setEnumValuesTree(Configuration config, Element e) {
117        Utils utils = config.utils;
118        String klassName = utils.getSimpleName(utils.getEnclosingTypeElement(e));
119
120        List<DocTree> fullBody = new ArrayList<>();
121        fullBody.add(treeFactory.newTextTree(config.getText("doclet.enum_values_doc.fullbody", klassName)));
122
123        List<DocTree> descriptions = new ArrayList<>();
124        descriptions.add(treeFactory.newTextTree(config.getText("doclet.enum_values_doc.return")));
125
126        List<DocTree> tags = new ArrayList<>();
127        tags.add(treeFactory.newReturnTree(descriptions));
128        DocCommentTree docTree = treeFactory.newDocCommentTree(fullBody, tags);
129        dcTreesMap.put(e, new DocCommentDuo(null, docTree));
130    }
131
132    public void setEnumValueOfTree(Configuration config, Element e) {
133
134        List<DocTree> fullBody = new ArrayList<>();
135        fullBody.add(treeFactory.newTextTree(config.getText("doclet.enum_valueof_doc.fullbody")));
136
137        List<DocTree> tags = new ArrayList<>();
138
139        List<DocTree> paramDescs = new ArrayList<>();
140        paramDescs.add(treeFactory.newTextTree(config.getText("doclet.enum_valueof_doc.param_name")));
141        ExecutableElement ee = (ExecutableElement) e;
142        java.util.List<? extends VariableElement> parameters = ee.getParameters();
143        VariableElement param = parameters.get(0);
144        IdentifierTree id = treeFactory.newIdentifierTree(elementUtils.getName(param.getSimpleName().toString()));
145        tags.add(treeFactory.newParamTree(false, id, paramDescs));
146
147        List<DocTree> returnDescs = new ArrayList<>();
148        returnDescs.add(treeFactory.newTextTree(config.getText("doclet.enum_valueof_doc.return")));
149        tags.add(treeFactory.newReturnTree(returnDescs));
150
151        List<DocTree> throwsDescs = new ArrayList<>();
152        throwsDescs.add(treeFactory.newTextTree(config.getText("doclet.enum_valueof_doc.throws_ila")));
153
154        ReferenceTree ref = treeFactory.newReferenceTree("java.lang.IllegalArgumentException");
155        tags.add(treeFactory.newThrowsTree(ref, throwsDescs));
156
157        throwsDescs = new ArrayList<>();
158        throwsDescs.add(treeFactory.newTextTree(config.getText("doclet.enum_valueof_doc.throws_npe")));
159
160        ref = treeFactory.newReferenceTree("java.lang.NullPointerException");
161        tags.add(treeFactory.newThrowsTree(ref, throwsDescs));
162
163        DocCommentTree docTree = treeFactory.newDocCommentTree(fullBody, tags);
164
165        dcTreesMap.put(e, new DocCommentDuo(null, docTree));
166    }
167
168    /*
169     * Returns the TreePath/DocCommentTree duo for synthesized element.
170     */
171    public DocCommentDuo getSyntheticCommentDuo(Element e) {
172        return dcTreesMap.get(e);
173    }
174
175    /*
176     * Returns the TreePath/DocCommentTree duo for html sources.
177     */
178    public DocCommentDuo getHtmlCommentDuo(Element e) {
179        FileObject fo = null;
180        if (e.getKind().equals(ElementKind.OTHER)) {
181            fo = configuration.getOverviewPath();
182        } else if (e.getKind().equals(ElementKind.PACKAGE)) {
183            fo = configuration.workArounds.getJavaFileObject((PackageElement)e);
184        }
185        if (fo == null) {
186            return null;
187        }
188
189        DocCommentTree dcTree = trees.getDocCommentTree(fo);
190        if (dcTree == null) {
191            return null;
192        }
193        DocTreePath treePath = trees.getDocTreePath(fo);
194        return new DocCommentDuo(treePath.getTreePath(), dcTree);
195    }
196
197    public DocCommentTree parse(URI uri, String text) {
198        return trees.getDocCommentTree(new SimpleJavaFileObject(
199                uri, JavaFileObject.Kind.SOURCE) {
200            @Override @DefinedBy(Api.COMPILER)
201            public CharSequence getCharContent(boolean ignoreEncoding) {
202                return text;
203            }
204        });
205    }
206
207    public void setDocCommentTree(Element element, List<DocTree> fullBody,
208            List<DocTree> blockTags, Utils utils) {
209        DocCommentTree docTree = treeFactory.newDocCommentTree(fullBody, blockTags);
210        dcTreesMap.put(element, new DocCommentDuo(null, docTree));
211        // There maybe an entry with the original comments usually null,
212        // therefore remove that entry if it exists, and allow a new one
213        // to be reestablished.
214        utils.removeCommentHelper(element);
215    }
216
217    /**
218     * A simplistic container to transport a TreePath, DocCommentTree pair.
219     * Here is why we need this:
220     * a. not desirable to add javac's pair.
221     * b. DocTreePath is not a viable  option either, as a null TreePath is required
222     * to represent synthetic comments for Enum.values, valuesOf, javafx properties.
223     */
224    public static class DocCommentDuo {
225        public final TreePath treePath;
226        public final DocCommentTree dcTree;
227
228        public DocCommentDuo(TreePath treePath, DocCommentTree dcTree) {
229            this.treePath = treePath;
230            this.dcTree = dcTree;
231        }
232    }
233}
234