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 package jdk.javadoc.internal.doclets.formats.html;
27
28 import java.util.Collection;
29 import java.util.List;
30 import java.util.Set;
31 import java.util.SortedSet;
32 import java.util.TreeSet;
33
34 import javax.lang.model.element.AnnotationMirror;
35 import javax.lang.model.element.Element;
36 import javax.lang.model.element.ModuleElement;
37 import javax.lang.model.element.PackageElement;
38 import javax.lang.model.element.TypeElement;
39 import javax.lang.model.type.TypeMirror;
40 import javax.lang.model.util.SimpleElementVisitor8;
41
42 import com.sun.source.doctree.DocTree;
43 import jdk.javadoc.internal.doclets.formats.html.markup.ContentBuilder;
44 import jdk.javadoc.internal.doclets.formats.html.markup.Entity;
45 import jdk.javadoc.internal.doclets.formats.html.markup.HtmlAttr;
46 import jdk.javadoc.internal.doclets.formats.html.markup.HtmlStyle;
47 import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTag;
48 import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTree;
49 import jdk.javadoc.internal.doclets.formats.html.markup.Navigation;
50 import jdk.javadoc.internal.doclets.formats.html.markup.Navigation.PageMode;
51 import jdk.javadoc.internal.doclets.formats.html.markup.StringContent;
52 import jdk.javadoc.internal.doclets.toolkit.ClassWriter;
53 import jdk.javadoc.internal.doclets.toolkit.Content;
54 import jdk.javadoc.internal.doclets.toolkit.taglets.ParamTaglet;
55 import jdk.javadoc.internal.doclets.toolkit.util.ClassTree;
56 import jdk.javadoc.internal.doclets.toolkit.util.CommentHelper;
57 import jdk.javadoc.internal.doclets.toolkit.util.DocFileIOException;
193
194 /**
195 * {@inheritDoc}
196 */
197 @Override
198 public Content getClassInfoTreeHeader() {
199 return getMemberTreeHeader();
200 }
201
202 /**
203 * {@inheritDoc}
204 */
205 @Override
206 public Content getClassInfo(Content classInfoTree) {
207 return getMemberTree(HtmlStyle.description, classInfoTree);
208 }
209
210 /**
211 * {@inheritDoc}
212 */
213 @Override
214 public void addClassSignature(String modifiers, Content classInfoTree) {
215 Content hr = new HtmlTree(HtmlTag.HR);
216 classInfoTree.add(hr);
217 Content pre = new HtmlTree(HtmlTag.PRE);
218 addAnnotationInfo(typeElement, pre);
219 pre.add(modifiers);
220 LinkInfoImpl linkInfo = new LinkInfoImpl(configuration,
221 LinkInfoImpl.Kind.CLASS_SIGNATURE, typeElement);
222 //Let's not link to ourselves in the signature.
223 linkInfo.linkToSelf = false;
224 Content className = new StringContent(utils.getSimpleName(typeElement));
225 Content parameterLinks = getTypeParameterLinks(linkInfo);
226 if (configuration.linksource) {
227 addSrcLink(typeElement, className, pre);
228 pre.add(parameterLinks);
229 } else {
230 Content span = HtmlTree.SPAN(HtmlStyle.typeNameLabel, className);
231 span.add(parameterLinks);
232 pre.add(span);
233 }
234 if (!utils.isInterface(typeElement)) {
235 TypeMirror superclass = utils.getFirstVisibleSuperClass(typeElement);
236 if (superclass != null) {
237 pre.add(DocletConstants.NL);
238 pre.add("extends ");
239 Content link = getLink(new LinkInfoImpl(configuration,
240 LinkInfoImpl.Kind.CLASS_SIGNATURE_PARENT_NAME,
241 superclass));
242 pre.add(link);
243 }
244 }
245 List<? extends TypeMirror> interfaces = typeElement.getInterfaces();
246 if (!interfaces.isEmpty()) {
247 boolean isFirst = true;
248 for (TypeMirror type : interfaces) {
249 TypeElement tDoc = utils.asTypeElement(type);
250 if (!(utils.isPublic(tDoc) || utils.isLinkable(tDoc))) {
251 continue;
252 }
253 if (isFirst) {
254 pre.add(DocletConstants.NL);
255 pre.add(utils.isInterface(typeElement) ? "extends " : "implements ");
256 isFirst = false;
257 } else {
258 pre.add(", ");
259 }
260 Content link = getLink(new LinkInfoImpl(configuration,
261 LinkInfoImpl.Kind.CLASS_SIGNATURE_PARENT_NAME,
262 type));
263 pre.add(link);
264 }
265 }
266 classInfoTree.add(pre);
267 }
268
269 /**
270 * {@inheritDoc}
271 */
272 @Override
273 public void addClassDescription(Content classInfoTree) {
274 if(!configuration.nocomment) {
275 // generate documentation for the class.
276 if (!utils.getFullBody(typeElement).isEmpty()) {
277 addInlineComment(typeElement, classInfoTree);
278 }
279 }
280 }
281
282 /**
283 * {@inheritDoc}
284 */
285 @Override
286 public void addClassTagInfo(Content classInfoTree) {
287 if(!configuration.nocomment) {
288 // Print Information about all the tags here
289 addTagsInfo(typeElement, classInfoTree);
290 }
291 }
292
293 /**
294 * Get the class hierarchy tree for the given class.
295 *
296 * @param type the class to print the hierarchy for
297 * @return a content tree for class inheritence
298 */
299 private Content getClassInheritenceTree(TypeMirror type) {
300 TypeMirror sup;
301 HtmlTree classTree = null;
302 do {
303 sup = utils.getFirstVisibleSuperClass(type);
304 HtmlTree htmlElement = HtmlTree.DIV(HtmlStyle.inheritance, getTreeForClassHelper(type));
305 if (classTree != null)
306 htmlElement.add(classTree);
307 classTree = htmlElement;
308 type = sup;
309 } while (sup != null);
310 classTree.put(HtmlAttr.TITLE, contents.getContent("doclet.Inheritance_Tree").toString());
311 return classTree;
312 }
313
314 /**
315 * Get the class helper tree for the given class.
316 *
317 * @param type the class to print the helper for
318 * @return a content tree for class helper
319 */
330 content.add(utils.asTypeElement(type).getQualifiedName());
331 content.add(typeParameters);
332 }
333 } else {
334 Content link = getLink(new LinkInfoImpl(configuration,
335 LinkInfoImpl.Kind.CLASS_TREE_PARENT, type)
336 .label(configuration.getClassName(utils.asTypeElement(type))));
337 content.add(link);
338 }
339 return content;
340 }
341
342 /**
343 * {@inheritDoc}
344 */
345 @Override
346 public void addClassTree(Content classContentTree) {
347 if (!utils.isClass(typeElement)) {
348 return;
349 }
350 classContentTree.add(getClassInheritenceTree(typeElement.asType()));
351 }
352
353 /**
354 * {@inheritDoc}
355 */
356 @Override
357 public void addTypeParamInfo(Content classInfoTree) {
358 if (!utils.getTypeParamTrees(typeElement).isEmpty()) {
359 Content typeParam = (new ParamTaglet()).getTagletOutput(typeElement,
360 getTagletWriterInstance(false));
361 Content dl = HtmlTree.DL(typeParam);
362 classInfoTree.add(dl);
363 }
364 }
365
366 /**
367 * {@inheritDoc}
368 */
369 @Override
370 public void addSubClassInfo(Content classInfoTree) {
371 if (utils.isClass(typeElement)) {
372 for (String s : suppressSubtypesSet) {
373 if (typeElement.getQualifiedName().contentEquals(s)) {
374 return; // Don't generate the list, too huge
375 }
376 }
377 Set<TypeElement> subclasses = classtree.directSubClasses(typeElement, false);
378 if (!subclasses.isEmpty()) {
379 Content label = contents.subclassesLabel;
380 Content dt = HtmlTree.DT(label);
381 Content dl = HtmlTree.DL(dt);
382 dl.add(getClassLinks(LinkInfoImpl.Kind.SUBCLASSES,
|
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 package jdk.javadoc.internal.doclets.formats.html;
27
28 import java.util.Collection;
29 import java.util.List;
30 import java.util.Set;
31 import java.util.SortedSet;
32 import java.util.TreeSet;
33
34 import javax.lang.model.element.AnnotationMirror;
35 import javax.lang.model.element.Element;
36 import javax.lang.model.element.ModuleElement;
37 import javax.lang.model.element.PackageElement;
38 import javax.lang.model.element.RecordComponentElement;
39 import javax.lang.model.element.TypeElement;
40 import javax.lang.model.type.TypeMirror;
41 import javax.lang.model.util.SimpleElementVisitor8;
42
43 import com.sun.source.doctree.DocTree;
44 import jdk.javadoc.internal.doclets.formats.html.markup.ContentBuilder;
45 import jdk.javadoc.internal.doclets.formats.html.markup.Entity;
46 import jdk.javadoc.internal.doclets.formats.html.markup.HtmlAttr;
47 import jdk.javadoc.internal.doclets.formats.html.markup.HtmlStyle;
48 import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTag;
49 import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTree;
50 import jdk.javadoc.internal.doclets.formats.html.markup.Navigation;
51 import jdk.javadoc.internal.doclets.formats.html.markup.Navigation.PageMode;
52 import jdk.javadoc.internal.doclets.formats.html.markup.StringContent;
53 import jdk.javadoc.internal.doclets.toolkit.ClassWriter;
54 import jdk.javadoc.internal.doclets.toolkit.Content;
55 import jdk.javadoc.internal.doclets.toolkit.taglets.ParamTaglet;
56 import jdk.javadoc.internal.doclets.toolkit.util.ClassTree;
57 import jdk.javadoc.internal.doclets.toolkit.util.CommentHelper;
58 import jdk.javadoc.internal.doclets.toolkit.util.DocFileIOException;
194
195 /**
196 * {@inheritDoc}
197 */
198 @Override
199 public Content getClassInfoTreeHeader() {
200 return getMemberTreeHeader();
201 }
202
203 /**
204 * {@inheritDoc}
205 */
206 @Override
207 public Content getClassInfo(Content classInfoTree) {
208 return getMemberTree(HtmlStyle.description, classInfoTree);
209 }
210
211 /**
212 * {@inheritDoc}
213 */
214 @Override @SuppressWarnings("preview")
215 public void addClassSignature(String modifiers, Content classInfoTree) {
216 Content hr = new HtmlTree(HtmlTag.HR);
217 classInfoTree.add(hr);
218 Content pre = new HtmlTree(HtmlTag.PRE);
219 addAnnotationInfo(typeElement, pre);
220 pre.add(modifiers);
221 LinkInfoImpl linkInfo = new LinkInfoImpl(configuration,
222 LinkInfoImpl.Kind.CLASS_SIGNATURE, typeElement);
223 //Let's not link to ourselves in the signature.
224 linkInfo.linkToSelf = false;
225 Content className = new StringContent(utils.getSimpleName(typeElement));
226 Content parameterLinks = getTypeParameterLinks(linkInfo);
227 if (configuration.linksource) {
228 addSrcLink(typeElement, className, pre);
229 pre.add(parameterLinks);
230 } else {
231 Content span = HtmlTree.SPAN(HtmlStyle.typeNameLabel, className);
232 span.add(parameterLinks);
233 pre.add(span);
234 }
235 if (utils.isRecord(typeElement)) {
236 pre.add(getRecordComponents(typeElement));
237 }
238 if (!utils.isInterface(typeElement)) {
239 TypeMirror superclass = utils.getFirstVisibleSuperClass(typeElement);
240 if (superclass != null) {
241 pre.add(DocletConstants.NL);
242 pre.add("extends ");
243 Content link = getLink(new LinkInfoImpl(configuration,
244 LinkInfoImpl.Kind.CLASS_SIGNATURE_PARENT_NAME,
245 superclass));
246 pre.add(link);
247 }
248 }
249 List<? extends TypeMirror> interfaces = typeElement.getInterfaces();
250 if (!interfaces.isEmpty()) {
251 boolean isFirst = true;
252 for (TypeMirror type : interfaces) {
253 TypeElement tDoc = utils.asTypeElement(type);
254 if (!(utils.isPublic(tDoc) || utils.isLinkable(tDoc))) {
255 continue;
256 }
257 if (isFirst) {
258 pre.add(DocletConstants.NL);
259 pre.add(utils.isInterface(typeElement) ? "extends " : "implements ");
260 isFirst = false;
261 } else {
262 pre.add(", ");
263 }
264 Content link = getLink(new LinkInfoImpl(configuration,
265 LinkInfoImpl.Kind.CLASS_SIGNATURE_PARENT_NAME,
266 type));
267 pre.add(link);
268 }
269 }
270 classInfoTree.add(pre);
271 }
272
273 @SuppressWarnings("preview")
274 private Content getRecordComponents(TypeElement typeElem) {
275 Content content = new ContentBuilder();
276 content.add("(");
277 String sep = "";
278 for (RecordComponentElement e : typeElement.getRecordComponents()) {
279 content.add(sep);
280 getAnnotations(e.getAnnotationMirrors(), false).stream()
281 .forEach(a -> { content.add(a); content.add(" "); });
282 Content link = getLink(new LinkInfoImpl(configuration, LinkInfoImpl.Kind.RECORD_COMPONENT,
283 e.asType()));
284 content.add(link);
285 content.add(Entity.NO_BREAK_SPACE);
286 content.add(e.getSimpleName());
287 sep = ", ";
288 }
289 content.add(")");
290 return content;
291 }
292
293 /**
294 * {@inheritDoc}
295 */
296 @Override
297 public void addClassDescription(Content classInfoTree) {
298 if(!configuration.nocomment) {
299 // generate documentation for the class.
300 if (!utils.getFullBody(typeElement).isEmpty()) {
301 addInlineComment(typeElement, classInfoTree);
302 }
303 }
304 }
305
306 /**
307 * {@inheritDoc}
308 */
309 @Override
310 public void addClassTagInfo(Content classInfoTree) {
311 if(!configuration.nocomment) {
312 // Print Information about all the tags here
313 addTagsInfo(typeElement, classInfoTree);
314 }
315 }
316
317 /**
318 * Get the class hierarchy tree for the given class.
319 *
320 * @param type the class to print the hierarchy for
321 * @return a content tree for class inheritance
322 */
323 private Content getClassInheritanceTree(TypeMirror type) {
324 TypeMirror sup;
325 HtmlTree classTree = null;
326 do {
327 sup = utils.getFirstVisibleSuperClass(type);
328 HtmlTree htmlElement = HtmlTree.DIV(HtmlStyle.inheritance, getTreeForClassHelper(type));
329 if (classTree != null)
330 htmlElement.add(classTree);
331 classTree = htmlElement;
332 type = sup;
333 } while (sup != null);
334 classTree.put(HtmlAttr.TITLE, contents.getContent("doclet.Inheritance_Tree").toString());
335 return classTree;
336 }
337
338 /**
339 * Get the class helper tree for the given class.
340 *
341 * @param type the class to print the helper for
342 * @return a content tree for class helper
343 */
354 content.add(utils.asTypeElement(type).getQualifiedName());
355 content.add(typeParameters);
356 }
357 } else {
358 Content link = getLink(new LinkInfoImpl(configuration,
359 LinkInfoImpl.Kind.CLASS_TREE_PARENT, type)
360 .label(configuration.getClassName(utils.asTypeElement(type))));
361 content.add(link);
362 }
363 return content;
364 }
365
366 /**
367 * {@inheritDoc}
368 */
369 @Override
370 public void addClassTree(Content classContentTree) {
371 if (!utils.isClass(typeElement)) {
372 return;
373 }
374 classContentTree.add(getClassInheritanceTree(typeElement.asType()));
375 }
376
377 /**
378 * {@inheritDoc}
379 */
380 @Override
381 public void addParamInfo(Content classInfoTree) {
382 if (utils.hasBlockTag(typeElement, DocTree.Kind.PARAM)) {
383 Content paramInfo = (new ParamTaglet()).getTagletOutput(typeElement,
384 getTagletWriterInstance(false));
385 if (!paramInfo.isEmpty()) {
386 classInfoTree.add(HtmlTree.DL(paramInfo));
387 }
388 }
389 }
390
391 /**
392 * {@inheritDoc}
393 */
394 @Override
395 public void addSubClassInfo(Content classInfoTree) {
396 if (utils.isClass(typeElement)) {
397 for (String s : suppressSubtypesSet) {
398 if (typeElement.getQualifiedName().contentEquals(s)) {
399 return; // Don't generate the list, too huge
400 }
401 }
402 Set<TypeElement> subclasses = classtree.directSubClasses(typeElement, false);
403 if (!subclasses.isEmpty()) {
404 Content label = contents.subclassesLabel;
405 Content dt = HtmlTree.DT(label);
406 Content dl = HtmlTree.DL(dt);
407 dl.add(getClassLinks(LinkInfoImpl.Kind.SUBCLASSES,
|