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