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
35 package jdk.javadoc.internal.doclets.toolkit;
36
37 import java.net.URI;
38 import java.util.ArrayList;
39 import java.util.HashMap;
40 import java.util.List;
41
42 import javax.lang.model.element.Element;
43 import javax.lang.model.element.ExecutableElement;
44 import javax.lang.model.element.Name;
45 import javax.lang.model.element.PackageElement;
46 import javax.lang.model.element.VariableElement;
47 import javax.lang.model.util.Elements;
48 import javax.tools.FileObject;
49 import javax.tools.JavaFileObject;
50 import javax.tools.SimpleJavaFileObject;
51
52 import com.sun.source.doctree.DocCommentTree;
53 import com.sun.source.doctree.DocTree;
54 import com.sun.source.doctree.IdentifierTree;
55 import com.sun.source.doctree.ReferenceTree;
56 import com.sun.source.doctree.TextTree;
57 import com.sun.source.util.DocTreeFactory;
58 import com.sun.source.util.DocTreePath;
59 import com.sun.source.util.DocTrees;
60 import com.sun.source.util.TreePath;
61 import com.sun.tools.javac.util.DefinedBy;
62 import com.sun.tools.javac.util.DefinedBy.Api;
63 import jdk.javadoc.internal.doclets.toolkit.util.Utils;
64
65 public class CommentUtils {
66
67 final BaseConfiguration configuration;
68 final Resources resources;
69 final DocTreeFactory treeFactory;
70 final HashMap<Element, DocCommentDuo> dcTreesMap = new HashMap<>();
71 final DocTrees trees;
72 final Elements elementUtils;
73
74 protected CommentUtils(BaseConfiguration configuration) {
75 this.configuration = configuration;
76 resources = configuration.getResources();
77 trees = configuration.docEnv.getDocTrees();
78 treeFactory = trees.getDocTreeFactory();
79 elementUtils = configuration.docEnv.getElementUtils();
80 }
81
82 public List<? extends DocTree> makePropertyDescriptionTree(List<? extends DocTree> content) {
83 List<DocTree> out = new ArrayList<>();
84 Name name = elementUtils.getName("propertyDescription");
85 out.add(treeFactory.newUnknownBlockTagTree(name, content));
86 return out;
87 }
88
89 public List<? extends DocTree> makePropertyDescriptionTree(String content) {
90 List<DocTree> inlist = new ArrayList<>();
91 inlist.add(treeFactory.newCommentTree(content));
92 List<DocTree> out = new ArrayList<>();
93 Name name = elementUtils.getName("propertyDescription");
94 out.add(treeFactory.newUnknownBlockTagTree(name, inlist));
95 return out;
96 }
97
98 public List<? extends DocTree> makeFirstSentenceTree(String content) {
99 List<DocTree> out = new ArrayList<>();
100 out.add(treeFactory.newTextTree(content));
101 return out;
102 }
103
104 public DocTree makeSeeTree(String sig, Element e) {
105 List<DocTree> list = new ArrayList<>();
106 list.add(treeFactory.newReferenceTree(sig));
107 return treeFactory.newSeeTree(list);
108 }
109
110 public DocTree makeTextTree(String content) {
111 TextTree text = treeFactory.newTextTree(content);
112 return (DocTree) text;
113 }
114
115 public void setEnumValuesTree(Element e) {
116 Utils utils = configuration.utils;
117 String klassName = utils.getSimpleName(utils.getEnclosingTypeElement(e));
118
119 List<DocTree> fullBody = new ArrayList<>();
120 fullBody.add(treeFactory.newTextTree(resources.getText("doclet.enum_values_doc.fullbody", klassName)));
121
122 List<DocTree> descriptions = new ArrayList<>();
123 descriptions.add(treeFactory.newTextTree(resources.getText("doclet.enum_values_doc.return")));
124
125 List<DocTree> tags = new ArrayList<>();
126 tags.add(treeFactory.newReturnTree(descriptions));
127 DocCommentTree docTree = treeFactory.newDocCommentTree(fullBody, tags);
128 dcTreesMap.put(e, new DocCommentDuo(null, docTree));
129 }
130
131 public void setEnumValueOfTree(Element e) {
132
133 List<DocTree> fullBody = new ArrayList<>();
134 fullBody.add(treeFactory.newTextTree(resources.getText("doclet.enum_valueof_doc.fullbody")));
135
136 List<DocTree> tags = new ArrayList<>();
137
138 List<DocTree> paramDescs = new ArrayList<>();
139 paramDescs.add(treeFactory.newTextTree(resources.getText("doclet.enum_valueof_doc.param_name")));
140 ExecutableElement ee = (ExecutableElement) e;
141 java.util.List<? extends VariableElement> parameters = ee.getParameters();
142 VariableElement param = parameters.get(0);
143 IdentifierTree id = treeFactory.newIdentifierTree(elementUtils.getName(param.getSimpleName().toString()));
144 tags.add(treeFactory.newParamTree(false, id, paramDescs));
145
146 List<DocTree> returnDescs = new ArrayList<>();
147 returnDescs.add(treeFactory.newTextTree(resources.getText("doclet.enum_valueof_doc.return")));
148 tags.add(treeFactory.newReturnTree(returnDescs));
149
150 List<DocTree> throwsDescs = new ArrayList<>();
151 throwsDescs.add(treeFactory.newTextTree(resources.getText("doclet.enum_valueof_doc.throws_ila")));
152
153 ReferenceTree ref = treeFactory.newReferenceTree("java.lang.IllegalArgumentException");
154 tags.add(treeFactory.newThrowsTree(ref, throwsDescs));
155
156 throwsDescs = new ArrayList<>();
157 throwsDescs.add(treeFactory.newTextTree(resources.getText("doclet.enum_valueof_doc.throws_npe")));
158
159 ref = treeFactory.newReferenceTree("java.lang.NullPointerException");
160 tags.add(treeFactory.newThrowsTree(ref, throwsDescs));
161
162 DocCommentTree docTree = treeFactory.newDocCommentTree(fullBody, tags);
163
164 dcTreesMap.put(e, new DocCommentDuo(null, docTree));
165 }
166
167 /*
168 * Returns the TreePath/DocCommentTree duo for synthesized element.
169 */
170 public DocCommentDuo getSyntheticCommentDuo(Element e) {
171 return dcTreesMap.get(e);
172 }
173
174 /*
175 * Returns the TreePath/DocCommentTree duo for html sources.
176 */
177 public DocCommentDuo getHtmlCommentDuo(Element e) {
178 FileObject fo = null;
179 PackageElement pe = null;
180 switch (e.getKind()) {
181 case OTHER:
182 if (e instanceof DocletElement) {
183 DocletElement de = (DocletElement)e;
184 fo = de.getFileObject();
198
199 DocCommentTree dcTree = trees.getDocCommentTree(fo);
200 if (dcTree == null) {
201 return null;
202 }
203 DocTreePath treePath = trees.getDocTreePath(fo, pe);
204 return new DocCommentDuo(treePath.getTreePath(), dcTree);
205 }
206
207 public DocCommentTree parse(URI uri, String text) {
208 return trees.getDocCommentTree(new SimpleJavaFileObject(
209 uri, JavaFileObject.Kind.SOURCE) {
210 @Override @DefinedBy(Api.COMPILER)
211 public CharSequence getCharContent(boolean ignoreEncoding) {
212 return text;
213 }
214 });
215 }
216
217 public void setDocCommentTree(Element element, List<? extends DocTree> fullBody,
218 List<? extends DocTree> blockTags, Utils utils) {
219 DocCommentTree docTree = treeFactory.newDocCommentTree(fullBody, blockTags);
220 dcTreesMap.put(element, new DocCommentDuo(null, docTree));
221 // A method having null comment (no comment) that might need to be replaced
222 // with a synthetic comment, remove such a comment from the cache.
223 utils.removeCommentHelper(element);
224 }
225
226 /**
227 * A simplistic container to transport a TreePath, DocCommentTree pair.
228 * Here is why we need this:
229 * a. not desirable to add javac's pair.
230 * b. DocTreePath is not a viable option either, as a null TreePath is required
231 * to represent synthetic comments for Enum.values, valuesOf, javafx properties.
232 */
233 public static class DocCommentDuo {
234 public final TreePath treePath;
235 public final DocCommentTree dcTree;
236
237 public DocCommentDuo(TreePath treePath, DocCommentTree dcTree) {
238 this.treePath = treePath;
|
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
35 package jdk.javadoc.internal.doclets.toolkit;
36
37 import java.net.URI;
38 import java.util.ArrayList;
39 import java.util.HashMap;
40 import java.util.List;
41 import java.util.regex.Matcher;
42 import java.util.regex.Pattern;
43
44 import javax.lang.model.element.Element;
45 import javax.lang.model.element.ExecutableElement;
46 import javax.lang.model.element.Name;
47 import javax.lang.model.element.PackageElement;
48 import javax.lang.model.element.RecordComponentElement;
49 import javax.lang.model.element.TypeElement;
50 import javax.lang.model.element.VariableElement;
51 import javax.lang.model.util.Elements;
52 import javax.tools.FileObject;
53 import javax.tools.JavaFileObject;
54 import javax.tools.SimpleJavaFileObject;
55
56 import com.sun.source.doctree.AttributeTree;
57 import com.sun.source.doctree.DocCommentTree;
58 import com.sun.source.doctree.DocTree;
59 import com.sun.source.doctree.IdentifierTree;
60 import com.sun.source.doctree.ParamTree;
61 import com.sun.source.doctree.ReferenceTree;
62 import com.sun.source.doctree.TextTree;
63 import com.sun.source.util.DocTreeFactory;
64 import com.sun.source.util.DocTreePath;
65 import com.sun.source.util.DocTrees;
66 import com.sun.source.util.TreePath;
67 import com.sun.tools.javac.util.DefinedBy;
68 import com.sun.tools.javac.util.DefinedBy.Api;
69 import jdk.javadoc.internal.doclets.toolkit.util.Utils;
70
71 public class CommentUtils {
72
73 final BaseConfiguration configuration;
74 final Utils utils;
75 final Resources resources;
76 final DocTreeFactory treeFactory;
77 final HashMap<Element, DocCommentDuo> dcTreesMap = new HashMap<>();
78 final DocTrees trees;
79 final Elements elementUtils;
80
81 protected CommentUtils(BaseConfiguration configuration) {
82 this.configuration = configuration;
83 utils = configuration.utils;
84 resources = configuration.getResources();
85 trees = configuration.docEnv.getDocTrees();
86 treeFactory = trees.getDocTreeFactory();
87 elementUtils = configuration.docEnv.getElementUtils();
88 }
89
90 public List<? extends DocTree> makePropertyDescriptionTree(List<? extends DocTree> content) {
91 List<DocTree> out = new ArrayList<>();
92 Name name = elementUtils.getName("propertyDescription");
93 out.add(treeFactory.newUnknownBlockTagTree(name, content));
94 return out;
95 }
96
97 public List<? extends DocTree> makePropertyDescriptionTree(String content) {
98 List<DocTree> inlist = new ArrayList<>();
99 inlist.add(treeFactory.newCommentTree(content));
100 List<DocTree> out = new ArrayList<>();
101 Name name = elementUtils.getName("propertyDescription");
102 out.add(treeFactory.newUnknownBlockTagTree(name, inlist));
103 return out;
104 }
105
106 public List<? extends DocTree> makeFirstSentenceTree(String content) {
107 List<DocTree> out = new ArrayList<>();
108 out.add(treeFactory.newTextTree(content));
109 return out;
110 }
111
112 public DocTree makeSeeTree(String sig, Element e) {
113 List<DocTree> list = new ArrayList<>();
114 list.add(treeFactory.newReferenceTree(sig));
115 return treeFactory.newSeeTree(list);
116 }
117
118 public TextTree makeTextTree(String content) {
119 return treeFactory.newTextTree(content);
120 }
121
122 public TextTree makeTextTreeForResource(String key) {
123 return treeFactory.newTextTree(resources.getText(key));
124 }
125
126 public void setEnumValuesTree(ExecutableElement ee) {
127 List<DocTree> fullBody = new ArrayList<>();
128 fullBody.add(treeFactory.newTextTree(resources.getText("doclet.enum_values_doc.fullbody")));
129
130 List<DocTree> descriptions = new ArrayList<>();
131 descriptions.add(treeFactory.newTextTree(resources.getText("doclet.enum_values_doc.return")));
132
133 List<DocTree> tags = new ArrayList<>();
134 tags.add(treeFactory.newReturnTree(descriptions));
135 DocCommentTree docTree = treeFactory.newDocCommentTree(fullBody, tags);
136 dcTreesMap.put(ee, new DocCommentDuo(null, docTree));
137 }
138
139 public void setEnumValueOfTree(ExecutableElement ee) {
140 List<DocTree> fullBody = new ArrayList<>();
141 fullBody.add(treeFactory.newTextTree(resources.getText("doclet.enum_valueof_doc.fullbody")));
142
143 List<DocTree> tags = new ArrayList<>();
144
145 List<DocTree> paramDescs = new ArrayList<>();
146 paramDescs.add(treeFactory.newTextTree(resources.getText("doclet.enum_valueof_doc.param_name")));
147 java.util.List<? extends VariableElement> parameters = ee.getParameters();
148 VariableElement param = parameters.get(0);
149 IdentifierTree id = treeFactory.newIdentifierTree(elementUtils.getName(param.getSimpleName().toString()));
150 tags.add(treeFactory.newParamTree(false, id, paramDescs));
151
152 List<DocTree> returnDescs = new ArrayList<>();
153 returnDescs.add(treeFactory.newTextTree(resources.getText("doclet.enum_valueof_doc.return")));
154 tags.add(treeFactory.newReturnTree(returnDescs));
155
156 List<DocTree> throwsDescs = new ArrayList<>();
157 throwsDescs.add(treeFactory.newTextTree(resources.getText("doclet.enum_valueof_doc.throws_ila")));
158
159 ReferenceTree ref = treeFactory.newReferenceTree("java.lang.IllegalArgumentException");
160 tags.add(treeFactory.newThrowsTree(ref, throwsDescs));
161
162 throwsDescs = new ArrayList<>();
163 throwsDescs.add(treeFactory.newTextTree(resources.getText("doclet.enum_valueof_doc.throws_npe")));
164
165 ref = treeFactory.newReferenceTree("java.lang.NullPointerException");
166 tags.add(treeFactory.newThrowsTree(ref, throwsDescs));
167
168 DocCommentTree docTree = treeFactory.newDocCommentTree(fullBody, tags);
169
170 dcTreesMap.put(ee, new DocCommentDuo(null, docTree));
171 }
172
173 /**
174 * Generates the description for the canonical constructor for a record.
175 * @param ee the constructor
176 */
177 public void setRecordConstructorTree(ExecutableElement ee) {
178 TypeElement te = utils.getEnclosingTypeElement(ee);
179
180 List<DocTree> fullBody =
181 makeDescriptionWithName("doclet.record_constructor_doc.fullbody", te.getSimpleName());
182
183 List<DocTree> tags = new ArrayList<>();
184 java.util.List<? extends VariableElement> parameters = ee.getParameters();
185 for (VariableElement param : ee.getParameters()) {
186 Name name = param.getSimpleName();
187 IdentifierTree id = treeFactory.newIdentifierTree(name);
188 tags.add(treeFactory.newParamTree(false, id,
189 makeDescriptionWithComponent("doclet.record_constructor_doc.param_name", te, name)));
190 }
191
192 DocCommentTree docTree = treeFactory.newDocCommentTree(fullBody, tags);
193 dcTreesMap.put(ee, new DocCommentDuo(null, docTree));
194 }
195
196 /**
197 * Generates the description for the standard {@code equals} method for a record.
198 * @param ee the {@code equals} method
199 */
200 @SuppressWarnings("preview")
201 public void setRecordEqualsTree(ExecutableElement ee) {
202 List<DocTree> fullBody = new ArrayList<>();
203 add(fullBody, "doclet.record_equals_doc.fullbody.head");
204 fullBody.add(treeFactory.newTextTree(" "));
205
206 List<? extends RecordComponentElement> comps = ((TypeElement) ee.getEnclosingElement()).getRecordComponents();
207 boolean hasPrimitiveComponents =
208 comps.stream().anyMatch(e -> e.asType().getKind().isPrimitive());
209 boolean hasReferenceComponents =
210 comps.stream().anyMatch(e -> !e.asType().getKind().isPrimitive());
211 if (hasPrimitiveComponents && hasReferenceComponents) {
212 add(fullBody, "doclet.record_equals_doc.fullbody.tail.both");
213 } else if (hasPrimitiveComponents) {
214 add(fullBody, "doclet.record_equals_doc.fullbody.tail.primitive");
215 } else if (hasReferenceComponents) {
216 add(fullBody, "doclet.record_equals_doc.fullbody.tail.reference");
217 }
218 Name paramName = ee.getParameters().get(0).getSimpleName();
219 IdentifierTree id = treeFactory.newIdentifierTree(paramName);
220 List<DocTree> paramDesc =
221 makeDescriptionWithName("doclet.record_equals_doc.param_name", paramName);
222 DocTree paramTree = treeFactory.newParamTree(false, id, paramDesc);
223
224 DocTree returnTree = treeFactory.newReturnTree(
225 makeDescriptionWithName("doclet.record_equals_doc.return", paramName));
226
227 TreePath treePath = utils.getTreePath(ee.getEnclosingElement());
228 DocCommentTree docTree = treeFactory.newDocCommentTree(fullBody, List.of(paramTree, returnTree));
229 dcTreesMap.put(ee, new DocCommentDuo(treePath, docTree));
230 }
231
232 private void add(List<DocTree> contents, String resourceKey) {
233 // Special case to allow '{@link ...}' to appear in the string.
234 // A less general case would be to detect literal use of Object.equals
235 // A more general case would be to allow access to DocCommentParser somehow
236 String body = resources.getText(resourceKey);
237 Pattern p = Pattern.compile("\\{@link (\\S*)(.*)}");
238 Matcher m = p.matcher(body);
239 int start = 0;
240 while (m.find(start)) {
241 if (m.start() > start) {
242 contents.add(treeFactory.newTextTree(body.substring(start, m.start())));
243 }
244 ReferenceTree refTree = treeFactory.newReferenceTree(m.group(1));
245 List<DocTree> descr = List.of(treeFactory.newTextTree(m.group(2).trim())) ;
246 contents.add(treeFactory.newLinkTree(refTree, descr));
247 start = m.end();
248 }
249 if (start < body.length()) {
250 contents.add(treeFactory.newTextTree(body.substring(start)));
251 }
252 }
253
254 /**
255 * Generates the description for the standard {@code hashCode} method for a record.
256 * @param ee the {@code hashCode} method
257 */
258 public void setRecordHashCodeTree(ExecutableElement ee) {
259 List<DocTree> fullBody = List.of(makeTextTreeForResource("doclet.record_hashCode_doc.fullbody"));
260
261 DocTree returnTree = treeFactory.newReturnTree(
262 List.of(makeTextTreeForResource("doclet.record_hashCode_doc.return")));
263
264 DocCommentTree docTree = treeFactory.newDocCommentTree(fullBody, List.of(returnTree));
265 dcTreesMap.put(ee, new DocCommentDuo(null, docTree));
266 }
267
268 /**
269 * Generates the description for the standard {@code toString} method for a record.
270 * @param ee the {@code toString} method
271 */
272 public void setRecordToStringTree(ExecutableElement ee) {
273 List<DocTree> fullBody = List.of(
274 treeFactory.newTextTree(resources.getText("doclet.record_toString_doc.fullbody")));
275
276 DocTree returnTree = treeFactory.newReturnTree(List.of(
277 treeFactory.newTextTree(resources.getText("doclet.record_toString_doc.return"))));
278
279 DocCommentTree docTree = treeFactory.newDocCommentTree(fullBody, List.of(returnTree));
280 dcTreesMap.put(ee, new DocCommentDuo(null, docTree));
281 }
282
283 /**
284 * Generates the description for the accessor method for a state component of a record.
285 * @param ee the accessor method
286 */
287 public void setRecordAccessorTree(ExecutableElement ee) {
288 TypeElement te = utils.getEnclosingTypeElement(ee);
289
290 List<DocTree> fullBody =
291 makeDescriptionWithComponent("doclet.record_accessor_doc.fullbody", te, ee.getSimpleName());
292
293 DocTree returnTree = treeFactory.newReturnTree(
294 makeDescriptionWithComponent("doclet.record_accessor_doc.return", te, ee.getSimpleName()));
295
296 DocCommentTree docTree = treeFactory.newDocCommentTree(fullBody, List.of(returnTree));
297 dcTreesMap.put(ee, new DocCommentDuo(null, docTree));
298 }
299
300 /**
301 * Generates the description for the field for a state component of a record.
302 * @param ve the field
303 */
304 public void setRecordFieldTree(VariableElement ve) {
305 TypeElement te = utils.getEnclosingTypeElement(ve);
306
307 List<DocTree> fullBody =
308 makeDescriptionWithComponent("doclet.record_field_doc.fullbody", te, ve.getSimpleName());
309
310 DocCommentTree docTree = treeFactory.newDocCommentTree(fullBody, List.of());
311 dcTreesMap.put(ve, new DocCommentDuo(null, docTree));
312 }
313
314 /**
315 * Creates a description that contains a reference to a state component of a record.
316 * The description is looked up as a resource, and should contain {@code {0}} where the
317 * reference to the component is to be inserted. The reference will be a link if the
318 * doc comment for the record has a {@code @param} tag for the component.
319 * @param key the resource key for the description
320 * @param elem the record element
321 * @param component the name of the component
322 * @return the description
323 */
324 private List<DocTree> makeDescriptionWithComponent(String key, TypeElement elem, Name component) {
325 List<DocTree> result = new ArrayList<>();
326 String text = resources.getText(key);
327 int index = text.indexOf("{0}");
328 result.add(treeFactory.newTextTree(text.substring(0, index)));
329 Name A = elementUtils.getName("a");
330 Name CODE = elementUtils.getName("code");
331 Name HREF = elementUtils.getName("href");
332 List<DocTree> code = List.of(
333 treeFactory.newStartElementTree(CODE, List.of(), false),
334 treeFactory.newTextTree(component.toString()),
335 treeFactory.newEndElementTree(CODE));
336 if (hasParamForComponent(elem, component)) {
337 DocTree href = treeFactory.newAttributeTree(HREF,
338 AttributeTree.ValueKind.DOUBLE,
339 List.of(treeFactory.newTextTree("#param-" + component)));
340 result.add(treeFactory.newStartElementTree(A, List.of(href), false));
341 result.addAll(code);
342 result.add(treeFactory.newEndElementTree(A));
343 } else {
344 result.addAll(code);
345 }
346 result.add(treeFactory.newTextTree(text.substring(index + 3)));
347 return result;
348 }
349
350 /**
351 * Returns whether or not the doc comment for a record contains an {@code @param}}
352 * for a state component of the record.
353 * @param elem the record element
354 * @param component the name of the component
355 * @return whether or not there is a {@code @param}} for the component
356 */
357 private boolean hasParamForComponent(TypeElement elem, Name component) {
358 DocCommentTree elemComment = utils.getDocCommentTree(elem);
359 if (elemComment == null) {
360 return false;
361 }
362
363 for (DocTree t : elemComment.getBlockTags()) {
364 if (t instanceof ParamTree && ((ParamTree) t).getName().getName() == component) {
365 return true;
366 }
367 }
368
369 return false;
370 }
371
372 /**
373 * Creates a description that contains the simple name of a program element
374 * The description is looked up as a resource, and should contain {@code {0}} where the
375 * name is to be inserted. T
376 * @param key the resource key for the description
377 * @param name the name
378 * @return the description
379 */
380 private List<DocTree> makeDescriptionWithName(String key, Name name) {
381 String text = resources.getText(key);
382 int index = text.indexOf("{0}");
383 if (index == -1) {
384 return List.of(treeFactory.newTextTree(text));
385 } else {
386 Name CODE = elementUtils.getName("code");
387 return List.of(
388 treeFactory.newTextTree(text.substring(0, index)),
389 treeFactory.newStartElementTree(CODE, List.of(), false),
390 treeFactory.newTextTree(name.toString()),
391 treeFactory.newEndElementTree(CODE),
392 treeFactory.newTextTree(text.substring(index + 3))
393 );
394 }
395 }
396
397 /*
398 * Returns the TreePath/DocCommentTree duo for synthesized element.
399 */
400 public DocCommentDuo getSyntheticCommentDuo(Element e) {
401 return dcTreesMap.get(e);
402 }
403
404 /*
405 * Returns the TreePath/DocCommentTree duo for html sources.
406 */
407 public DocCommentDuo getHtmlCommentDuo(Element e) {
408 FileObject fo = null;
409 PackageElement pe = null;
410 switch (e.getKind()) {
411 case OTHER:
412 if (e instanceof DocletElement) {
413 DocletElement de = (DocletElement)e;
414 fo = de.getFileObject();
428
429 DocCommentTree dcTree = trees.getDocCommentTree(fo);
430 if (dcTree == null) {
431 return null;
432 }
433 DocTreePath treePath = trees.getDocTreePath(fo, pe);
434 return new DocCommentDuo(treePath.getTreePath(), dcTree);
435 }
436
437 public DocCommentTree parse(URI uri, String text) {
438 return trees.getDocCommentTree(new SimpleJavaFileObject(
439 uri, JavaFileObject.Kind.SOURCE) {
440 @Override @DefinedBy(Api.COMPILER)
441 public CharSequence getCharContent(boolean ignoreEncoding) {
442 return text;
443 }
444 });
445 }
446
447 public void setDocCommentTree(Element element, List<? extends DocTree> fullBody,
448 List<? extends DocTree> blockTags) {
449 DocCommentTree docTree = treeFactory.newDocCommentTree(fullBody, blockTags);
450 dcTreesMap.put(element, new DocCommentDuo(null, docTree));
451 // A method having null comment (no comment) that might need to be replaced
452 // with a synthetic comment, remove such a comment from the cache.
453 utils.removeCommentHelper(element);
454 }
455
456 /**
457 * A simplistic container to transport a TreePath, DocCommentTree pair.
458 * Here is why we need this:
459 * a. not desirable to add javac's pair.
460 * b. DocTreePath is not a viable option either, as a null TreePath is required
461 * to represent synthetic comments for Enum.values, valuesOf, javafx properties.
462 */
463 public static class DocCommentDuo {
464 public final TreePath treePath;
465 public final DocCommentTree dcTree;
466
467 public DocCommentDuo(TreePath treePath, DocCommentTree dcTree) {
468 this.treePath = treePath;
|