001/* 002 * JDrupes MDoclet 003 * Copyright (C) 2021,2022 Michael N. Lipp 004 * 005 * This program is free software; you can redistribute it and/or modify it 006 * under the terms of the GNU Affero General Public License as published by 007 * the Free Software Foundation; either version 3 of the License, or 008 * (at your option) any later version. 009 * 010 * This program is distributed in the hope that it will be useful, but 011 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 012 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License 013 * for more details. 014 * 015 * You should have received a copy of the GNU Affero General Public License along 016 * with this program; if not, see <http://www.gnu.org/licenses/>. 017 */ 018 019package org.jdrupes.mdoclet; 020 021import java.io.IOException; 022import java.text.BreakIterator; 023import java.util.List; 024 025import javax.lang.model.element.AnnotationMirror; 026import javax.lang.model.element.AnnotationValue; 027import javax.lang.model.element.Element; 028import javax.lang.model.element.ExecutableElement; 029import javax.lang.model.element.PackageElement; 030import javax.lang.model.element.TypeElement; 031import javax.lang.model.type.DeclaredType; 032import javax.lang.model.type.ErrorType; 033import javax.lang.model.type.TypeMirror; 034import javax.tools.Diagnostic.Kind; 035import javax.tools.FileObject; 036import javax.tools.ForwardingFileObject; 037 038import com.sun.source.doctree.DocCommentTree; 039import com.sun.source.doctree.DocTree; 040import com.sun.source.doctree.EntityTree; 041import com.sun.source.tree.CatchTree; 042import com.sun.source.tree.ClassTree; 043import com.sun.source.tree.CompilationUnitTree; 044import com.sun.source.tree.MethodTree; 045import com.sun.source.tree.Scope; 046import com.sun.source.tree.Tree; 047import com.sun.source.util.DocSourcePositions; 048import com.sun.source.util.DocTreeFactory; 049import com.sun.source.util.DocTreePath; 050import com.sun.source.util.DocTrees; 051import com.sun.source.util.TreePath; 052 053/** 054 * Wraps the {@link DocTrees} passed to the constructor. 055 * 056 * The main purpose of the wrapper is to wrap the results from methods 057 * that return a {@link DocCommentTree} for already parsed content 058 * in a {@link DocCommentTreeWrapper}. 059 * 060 * For method invocations with {@link FileObject}s as argument, 061 * the source is converted from markdown to html if the name ends 062 * with ".md". 063 */ 064public class DocTreesWrapper extends DocTrees { 065 066 private final MDoclet doclet; 067 private final MDocletEnvironment environment; 068 private final DocTrees docTrees; 069 070 public DocTreesWrapper(MDoclet doclet, MDocletEnvironment environment, 071 DocTrees docTrees) { 072 super(); 073 this.doclet = doclet; 074 this.environment = environment; 075 this.docTrees = docTrees; 076 } 077 078 private DocCommentTree wrap(DocCommentTree tree) { 079 if (tree == null) { 080 return null; 081 } 082 return new DocCommentTreeWrapper(doclet, environment, tree); 083 } 084 085 /** 086 * Delegates to the docTrees passed to the constructor. 087 * 088 * {@inheritDoc} 089 * @see com.sun.source.util.DocTrees#getBreakIterator() 090 */ 091 public BreakIterator getBreakIterator() { 092 return docTrees.getBreakIterator(); 093 } 094 095 /** 096 * Substitutes the original doctree with one processed my the markdown 097 * processor. 098 * 099 * {@inheritDoc} 100 * @see com.sun.source.util.DocTrees#getDocCommentTree(com.sun.source.util.TreePath) 101 */ 102 public DocCommentTree getDocCommentTree(TreePath path) { 103 return wrap(docTrees.getDocCommentTree(path)); 104 } 105 106 /** 107 * Delegates to the docTrees passed to the constructor. 108 * 109 * {@inheritDoc} 110 * @see com.sun.source.util.DocTrees#getDocCommentTree(javax.lang.model.element.Element) 111 */ 112 public DocCommentTree getDocCommentTree(Element e) { 113 return wrap(docTrees.getDocCommentTree(e)); 114 } 115 116 /** 117 * Delegates to the docTrees passed to the constructor. 118 * 119 * {@inheritDoc} 120 * @see com.sun.source.util.DocTrees#getDocCommentTree(javax.tools.FileObject) 121 */ 122 public DocCommentTree getDocCommentTree(FileObject fileObject) { 123 if (!fileObject.getName().endsWith(".md")) { 124 return docTrees.getDocCommentTree(fileObject); 125 } 126 return wrap(docTrees.getDocCommentTree(wrapMdFile(fileObject))); 127 } 128 129 private FileObject wrapMdFile(FileObject fileObject) { 130 return new ForwardingFileObject<>(fileObject) { 131 132 @Override 133 public String getName() { 134 String origName = super.getName(); 135 return origName.substring(0, origName.length() - 2) + "html"; 136 } 137 138 @Override 139 public CharSequence getCharContent(boolean ignoreEncodingErrors) 140 throws IOException { 141 String md 142 = super.getCharContent(ignoreEncodingErrors).toString(); 143 return "<body>" + md + "</body>"; 144 } 145 }; 146 } 147 148 /** 149 * Delegates to the docTrees passed to the constructor. 150 * 151 * {@inheritDoc} 152 * @see com.sun.source.util.Trees#getTree(javax.lang.model.element.Element) 153 */ 154 public Tree getTree(Element element) { 155 return docTrees.getTree(element); 156 } 157 158 /** 159 * Delegates to the docTrees passed to the constructor. 160 * 161 * {@inheritDoc} 162 * @see com.sun.source.util.DocTrees#getDocCommentTree(javax.lang.model.element.Element, java.lang.String) 163 */ 164 public DocCommentTree getDocCommentTree(Element e, String relativePath) 165 throws IOException { 166 return wrap(docTrees.getDocCommentTree(e, relativePath)); 167 } 168 169 /** 170 * Delegates to the docTrees passed to the constructor. 171 * 172 * {@inheritDoc} 173 * @see com.sun.source.util.Trees#getTree(javax.lang.model.element.TypeElement) 174 */ 175 public ClassTree getTree(TypeElement element) { 176 return docTrees.getTree(element); 177 } 178 179 /** 180 * Delegates to the docTrees passed to the constructor. 181 * 182 * {@inheritDoc} 183 * @see com.sun.source.util.Trees#getTree(javax.lang.model.element.ExecutableElement) 184 */ 185 public MethodTree getTree(ExecutableElement method) { 186 return docTrees.getTree(method); 187 } 188 189 /** 190 * Delegates to the docTrees passed to the constructor. 191 * 192 * {@inheritDoc} 193 * @see com.sun.source.util.Trees#getTree(javax.lang.model.element.Element, javax.lang.model.element.AnnotationMirror) 194 */ 195 public Tree getTree(Element e, AnnotationMirror a) { 196 return docTrees.getTree(e, a); 197 } 198 199 /** 200 * Delegates to the docTrees passed to the constructor. 201 * 202 * {@inheritDoc} 203 * @see com.sun.source.util.DocTrees#getDocTreePath(javax.tools.FileObject, javax.lang.model.element.PackageElement) 204 */ 205 public DocTreePath getDocTreePath(FileObject fileObject, 206 PackageElement packageElement) { 207 if (!fileObject.getName().endsWith(".md")) { 208 return docTrees.getDocTreePath(fileObject, packageElement); 209 } 210 return docTrees.getDocTreePath(wrapMdFile(fileObject), packageElement); 211 } 212 213 /** 214 * Delegates to the docTrees passed to the constructor. 215 * 216 * {@inheritDoc} 217 * @see com.sun.source.util.Trees#getTree(javax.lang.model.element.Element, javax.lang.model.element.AnnotationMirror, javax.lang.model.element.AnnotationValue) 218 */ 219 public Tree getTree(Element e, AnnotationMirror a, AnnotationValue v) { 220 return docTrees.getTree(e, a, v); 221 } 222 223 /** 224 * Delegates to the docTrees passed to the constructor. 225 * 226 * {@inheritDoc} 227 * @see com.sun.source.util.Trees#getPath(com.sun.source.tree.CompilationUnitTree, com.sun.source.tree.Tree) 228 */ 229 public TreePath getPath(CompilationUnitTree unit, Tree node) { 230 return docTrees.getPath(unit, node); 231 } 232 233 /** 234 * Delegates to the docTrees passed to the constructor. 235 * 236 * {@inheritDoc} 237 * @see com.sun.source.util.Trees#getPath(javax.lang.model.element.Element) 238 */ 239 public TreePath getPath(Element e) { 240 return docTrees.getPath(e); 241 } 242 243 /** 244 * Delegates to the docTrees passed to the constructor. 245 * 246 * {@inheritDoc} 247 * @see com.sun.source.util.DocTrees#getElement(com.sun.source.util.DocTreePath) 248 */ 249 public Element getElement(DocTreePath path) { 250 return docTrees.getElement(path); 251 } 252 253 /** 254 * Delegates to the docTrees passed to the constructor. 255 * 256 * {@inheritDoc} 257 * @see com.sun.source.util.Trees#getPath(javax.lang.model.element.Element, javax.lang.model.element.AnnotationMirror) 258 */ 259 public TreePath getPath(Element e, AnnotationMirror a) { 260 return docTrees.getPath(e, a); 261 } 262 263 /** 264 * Delegates to the docTrees passed to the constructor. 265 * 266 * {@inheritDoc} 267 * @see com.sun.source.util.DocTrees#getFirstSentence(java.util.List) 268 */ 269 public List<DocTree> getFirstSentence(List<? extends DocTree> list) { 270 return docTrees.getFirstSentence(list); 271 } 272 273 /** 274 * Delegates to the docTrees passed to the constructor. 275 * 276 * {@inheritDoc} 277 * @see com.sun.source.util.Trees#getPath(javax.lang.model.element.Element, javax.lang.model.element.AnnotationMirror, javax.lang.model.element.AnnotationValue) 278 */ 279 public TreePath getPath(Element e, AnnotationMirror a, AnnotationValue v) { 280 return docTrees.getPath(e, a, v); 281 } 282 283 /** 284 * Delegates to the docTrees passed to the constructor. 285 * 286 * {@inheritDoc} 287 * @see com.sun.source.util.DocTrees#getSourcePositions() 288 */ 289 public DocSourcePositions getSourcePositions() { 290 return docTrees.getSourcePositions(); 291 } 292 293 /** 294 * Delegates to the docTrees passed to the constructor. 295 * 296 * {@inheritDoc} 297 * @see com.sun.source.util.Trees#getElement(com.sun.source.util.TreePath) 298 */ 299 public Element getElement(TreePath path) { 300 return docTrees.getElement(path); 301 } 302 303 /** 304 * Delegates to the docTrees passed to the constructor. 305 * 306 * {@inheritDoc} 307 * @see com.sun.source.util.DocTrees#printMessage(javax.tools.Diagnostic.Kind, java.lang.CharSequence, com.sun.source.doctree.DocTree, com.sun.source.doctree.DocCommentTree, com.sun.source.tree.CompilationUnitTree) 308 */ 309 public void printMessage(Kind kind, CharSequence msg, DocTree t, 310 DocCommentTree c, CompilationUnitTree root) { 311 docTrees.printMessage(kind, msg, t, c, root); 312 } 313 314 /** 315 * Delegates to the docTrees passed to the constructor. 316 * 317 * {@inheritDoc} 318 * @see com.sun.source.util.Trees#getTypeMirror(com.sun.source.util.TreePath) 319 */ 320 public TypeMirror getTypeMirror(TreePath path) { 321 return docTrees.getTypeMirror(path); 322 } 323 324 /** 325 * Delegates to the docTrees passed to the constructor. 326 * 327 * {@inheritDoc} 328 * @see com.sun.source.util.DocTrees#setBreakIterator(java.text.BreakIterator) 329 */ 330 public void setBreakIterator(BreakIterator breakiterator) { 331 docTrees.setBreakIterator(breakiterator); 332 } 333 334 /** 335 * Delegates to the docTrees passed to the constructor. 336 * 337 * {@inheritDoc} 338 * @see com.sun.source.util.Trees#getScope(com.sun.source.util.TreePath) 339 */ 340 public Scope getScope(TreePath path) { 341 return docTrees.getScope(path); 342 } 343 344 /** 345 * Delegates to the docTrees passed to the constructor. 346 * 347 * {@inheritDoc} 348 * @see com.sun.source.util.DocTrees#getDocTreeFactory() 349 */ 350 public DocTreeFactory getDocTreeFactory() { 351 return docTrees.getDocTreeFactory(); 352 } 353 354 /** 355 * Delegates to the docTrees passed to the constructor. 356 * 357 * {@inheritDoc} 358 * @see com.sun.source.util.Trees#getDocComment(com.sun.source.util.TreePath) 359 */ 360 public String getDocComment(TreePath path) { 361 return docTrees.getDocComment(path); 362 } 363 364 /** 365 * Delegates to the docTrees passed to the constructor. 366 * 367 * {@inheritDoc} 368 * @see com.sun.source.util.Trees#isAccessible(com.sun.source.tree.Scope, javax.lang.model.element.TypeElement) 369 */ 370 public boolean isAccessible(Scope scope, TypeElement type) { 371 return docTrees.isAccessible(scope, type); 372 } 373 374 /** 375 * Delegates to the docTrees passed to the constructor. 376 * 377 * {@inheritDoc} 378 * @see com.sun.source.util.Trees#isAccessible(com.sun.source.tree.Scope, javax.lang.model.element.Element, javax.lang.model.type.DeclaredType) 379 */ 380 public boolean isAccessible(Scope scope, Element member, 381 DeclaredType type) { 382 return docTrees.isAccessible(scope, member, type); 383 } 384 385 /** 386 * Delegates to the docTrees passed to the constructor. 387 * 388 * {@inheritDoc} 389 * @see com.sun.source.util.Trees#getOriginalType(javax.lang.model.type.ErrorType) 390 */ 391 public TypeMirror getOriginalType(ErrorType errorType) { 392 return docTrees.getOriginalType(errorType); 393 } 394 395 /** 396 * Delegates to the docTrees passed to the constructor. 397 * 398 * {@inheritDoc} 399 * @see com.sun.source.util.Trees#printMessage(javax.tools.Diagnostic.Kind, java.lang.CharSequence, com.sun.source.tree.Tree, com.sun.source.tree.CompilationUnitTree) 400 */ 401 public void printMessage(Kind kind, CharSequence msg, Tree t, 402 CompilationUnitTree root) { 403 docTrees.printMessage(kind, msg, t, root); 404 } 405 406 /** 407 * Delegates to the docTrees passed to the constructor. 408 * 409 * {@inheritDoc} 410 * @see com.sun.source.util.Trees#getLub(com.sun.source.tree.CatchTree) 411 */ 412 public TypeMirror getLub(CatchTree tree) { 413 return docTrees.getLub(tree); 414 } 415 416 /** 417 * Delegates to the docTrees passed to the constructor. 418 * 419 * {@inheritDoc} 420 */ 421 @Override 422 public TypeMirror getType(DocTreePath path) { 423 return docTrees.getType(path); 424 } 425 426 /** 427 * Delegates to the docTrees passed to the constructor. 428 * 429 * {@inheritDoc} 430 */ 431 @Override 432 public String getCharacters(EntityTree tree) { 433 return docTrees.getCharacters(tree); 434 } 435 436 /** 437 * Delegates to the docTrees passed to the constructor. 438 * 439 * {@inheritDoc} 440 * @see java.lang.Object#toString() 441 */ 442 public String toString() { 443 return docTrees.toString(); 444 } 445 446}