001/* 002 * JDrupes MDoclet 003 * Copyright (C) 2021 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.util.ArrayList; 022import java.util.List; 023 024import com.sun.source.doctree.DocCommentTree; 025import com.sun.source.doctree.DocTree; 026import com.sun.source.doctree.DocTreeVisitor; 027import com.sun.tools.javac.tree.DCTree; 028 029/** 030 * Feeds the results of the methods through the {@link TreeConverter} 031 * where appropriate. 032 * 033 * With JDK 11, {@link DocCommentTreeWrapper} only had to implement 034 * {@link DocCommentTree}. Starting with (at least) JDK 15, javadoc 035 * casts (without check) {@link DocCommentTree} instances to 036 * {@link DCTree.DCDocComment} when reporting errors e.g. about 037 * a missing link target. That's the only reason why the 038 * wrapper extends {@link DCTree.DCDocComment}. 039 */ 040public class DocCommentTreeWrapper extends DCTree.DCDocComment 041 implements DocCommentTree { 042 043 private DocCommentTree tree; 044 private TreeConverter treeConverter; 045 private List<DocTree> fullBody; 046 private List<DocTree> firstSentence; 047 private List<DocTree> body; 048 private List<DocTree> blockTags; 049 050 public DocCommentTreeWrapper(MDoclet doclet, MDocletEnvironment environment, 051 DocCommentTree tree) { 052 super(tree instanceof DCTree.DCDocComment 053 ? ((DCTree.DCDocComment) tree).comment 054 : null, 055 null, null, null, null, null, null); 056 this.tree = tree; 057 treeConverter = new TreeConverter(doclet.getProcessor(), 058 environment.getDocTrees().getDocTreeFactory(), 059 environment.getElementUtils()); 060 } 061 062 /** 063 * Overridden by {@link DCTree.DCDocComment}, restore to default. 064 */ 065 @Override 066 public List<? extends DocTree> getFullBody() { 067 if (fullBody == null) { 068 fullBody = new ArrayList<>(); 069 fullBody.addAll(getFirstSentence()); 070 fullBody.addAll(getBody()); 071 } 072 return fullBody; 073 } 074 075 /** 076 * {@inheritDoc} 077 * 078 * @see com.sun.source.doctree.DocCommentTree#getFirstSentence() 079 */ 080 public List<? extends DocTree> getFirstSentence() { 081 if (firstSentence == null) { 082 firstSentence 083 = treeConverter.convertFragment(tree.getFirstSentence()); 084 } 085 return firstSentence; 086 } 087 088 /** 089 * {@inheritDoc} 090 * 091 * @see com.sun.source.doctree.DocCommentTree#getBody() 092 */ 093 public List<? extends DocTree> getBody() { 094 if (body == null) { 095 body = treeConverter.convertDescription(tree.getBody()); 096 } 097 return body; 098 } 099 100 /** 101 * {@inheritDoc} 102 * 103 * @see com.sun.source.doctree.DocCommentTree#getBlockTags() 104 */ 105 public List<? extends DocTree> getBlockTags() { 106 if (blockTags == null) { 107 List<? extends DocTree> origTags = tree.getBlockTags(); 108 blockTags = new ArrayList<>(); 109 for (DocTree tree : origTags) { 110 treeConverter.convertTag(blockTags, tree); 111 } 112 } 113 return blockTags; 114 } 115 116 /** 117 * {@inheritDoc} 118 * 119 * @see com.sun.source.doctree.DocCommentTree#getPreamble() 120 */ 121 public List<? extends DocTree> getPreamble() { 122 return tree.getPreamble(); 123 } 124 125 /** 126 * {@inheritDoc} 127 * 128 * @see com.sun.source.doctree.DocCommentTree#getPostamble() 129 */ 130 public List<? extends DocTree> getPostamble() { 131 return tree.getPostamble(); 132 } 133 134 /** 135 * {@inheritDoc} 136 * 137 * @see com.sun.source.doctree.DocTree#getKind() 138 */ 139 public Kind getKind() { 140 return tree.getKind(); 141 } 142 143 /** 144 * {@inheritDoc} 145 * 146 * @see com.sun.source.doctree.DocTree#accept(com.sun.source.doctree.DocTreeVisitor, java.lang.Object) 147 */ 148 public <R, D> R accept(DocTreeVisitor<R, D> visitor, D data) { 149 // Work around NPE when reporting param related problems. 150 if (tree instanceof DCTree.DCDocComment 151 && visitor.getClass().getName() 152 .equals("com.sun.source.util.DocTreePath$1PathFinder")) { 153 return visitor.visitDocComment(this, data); 154 } 155 return tree.accept(visitor, data); 156 } 157 158}