29 import java.util.List; 30 import java.util.Set; 31 import java.util.TreeSet; 32 import java.util.stream.Collectors; 33 34 import javax.lang.model.element.Element; 35 import javax.lang.model.element.ExecutableElement; 36 import javax.lang.model.element.Modifier; 37 import javax.lang.model.element.TypeElement; 38 import javax.lang.model.element.TypeParameterElement; 39 import javax.lang.model.type.TypeMirror; 40 41 import com.sun.source.doctree.DocTree; 42 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.HtmlStyle; 46 import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTag; 47 import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTree; 48 import jdk.javadoc.internal.doclets.formats.html.markup.Links; 49 import jdk.javadoc.internal.doclets.formats.html.markup.Table; 50 import jdk.javadoc.internal.doclets.formats.html.markup.TableHeader; 51 import jdk.javadoc.internal.doclets.toolkit.Content; 52 import jdk.javadoc.internal.doclets.toolkit.MemberSummaryWriter; 53 import jdk.javadoc.internal.doclets.toolkit.Resources; 54 import jdk.javadoc.internal.doclets.toolkit.taglets.DeprecatedTaglet; 55 import jdk.javadoc.internal.doclets.toolkit.util.Utils; 56 57 import static javax.lang.model.element.Modifier.ABSTRACT; 58 import static javax.lang.model.element.Modifier.NATIVE; 59 import static javax.lang.model.element.Modifier.PUBLIC; 60 import static javax.lang.model.element.Modifier.STRICTFP; 61 import static javax.lang.model.element.Modifier.SYNCHRONIZED; 62 63 /** 64 * The base class for member writers. 65 * 66 * <p><b>This is NOT part of any supported API. 67 * If you write code that depends on this, you do so at your own risk. 68 * This code and its internal interfaces are subject to change or 69 * deletion without notice.</b> 70 * 71 * @author Robert Field 72 * @author Atul M Dambalkar 73 * @author Jamie Ho (Re-write) 74 * @author Bhavesh Patel (Modified) 202 TypeElement typeElement, Element member, Content tdSummary); 203 204 /** 205 * Add the inherited summary link for the member. 206 * 207 * @param typeElement the TypeElement to be documented 208 * @param member the member to be documented 209 * @param linksTree the content tree to which the inherited summary link will be added 210 */ 211 protected abstract void addInheritedSummaryLink(TypeElement typeElement, 212 Element member, Content linksTree); 213 214 /** 215 * Get the deprecated link. 216 * 217 * @param member the member being linked to 218 * @return a content tree representing the link 219 */ 220 protected abstract Content getDeprecatedLink(Element member); 221 222 /** 223 * Add the member name to the content tree. 224 * 225 * @param name the member name to be added to the content tree. 226 * @param htmltree the content tree to which the name will be added. 227 */ 228 protected void addName(String name, Content htmltree) { 229 htmltree.add(name); 230 } 231 232 /** 233 * Add the modifier for the member. The modifiers are ordered as specified 234 * by <em>The Java Language Specification</em>. 235 * 236 * @param member the member for which the modifier will be added. 237 * @param htmltree the content tree to which the modifier information will be added. 238 */ 239 protected void addModifiers(Element member, Content htmltree) { 240 Set<Modifier> set = new TreeSet<>(member.getModifiers()); 241 242 // remove the ones we really don't need 243 set.remove(NATIVE); 244 set.remove(SYNCHRONIZED); 245 set.remove(STRICTFP); 246 247 // According to JLS, we should not be showing public modifier for 248 // interface methods. 249 if ((utils.isField(member) || utils.isMethod(member)) 250 && ((writer instanceof ClassWriterImpl 251 && utils.isInterface(((ClassWriterImpl) writer).getTypeElement()) || 252 writer instanceof AnnotationTypeWriterImpl) )) { 253 // Remove the implicit abstract and public modifiers 254 if (utils.isMethod(member) && 255 (utils.isInterface(member.getEnclosingElement()) || 256 utils.isAnnotationType(member.getEnclosingElement()))) { 257 set.remove(ABSTRACT); 258 set.remove(PUBLIC); 259 } 260 if (!utils.isMethod(member)) { 261 set.remove(PUBLIC); 262 } 263 } 264 if (!set.isEmpty()) { 265 String mods = set.stream().map(Modifier::toString).collect(Collectors.joining(" ")); 266 htmltree.add(mods); 267 htmltree.add(Entity.NO_BREAK_SPACE); 268 } 269 } 270 271 protected CharSequence makeSpace(int len) { 272 if (len <= 0) { 273 return ""; 274 } 275 StringBuilder sb = new StringBuilder(len); 276 for (int i = 0; i < len; i++) { 277 sb.append(' '); 278 } 279 return sb; 280 } 281 282 /** 283 * Add the modifier and type for the member in the member summary. 284 * 285 * @param member the member to add the type for 286 * @param type the type to add 287 * @param tdSummaryType the content tree to which the modified and type will be added 288 */ 289 protected void addModifierAndType(Element member, TypeMirror type, 290 Content tdSummaryType) { 546 * @return a content tree that will be added to the class documentation 547 */ 548 @Override 549 public Content getMemberTree(Content memberTree) { 550 return writer.getMemberTree(memberTree); 551 } 552 553 /** 554 * Get the member tree to be documented. 555 * 556 * @param memberTree the content tree of member to be documented 557 * @param isLastContent true if the content to be added is the last content 558 * @return a content tree that will be added to the class documentation 559 */ 560 public Content getMemberTree(Content memberTree, boolean isLastContent) { 561 if (isLastContent) 562 return HtmlTree.LI(HtmlStyle.blockListLast, memberTree); 563 else 564 return HtmlTree.LI(HtmlStyle.blockList, memberTree); 565 } 566 } | 29 import java.util.List; 30 import java.util.Set; 31 import java.util.TreeSet; 32 import java.util.stream.Collectors; 33 34 import javax.lang.model.element.Element; 35 import javax.lang.model.element.ExecutableElement; 36 import javax.lang.model.element.Modifier; 37 import javax.lang.model.element.TypeElement; 38 import javax.lang.model.element.TypeParameterElement; 39 import javax.lang.model.type.TypeMirror; 40 41 import com.sun.source.doctree.DocTree; 42 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.HtmlStyle; 46 import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTag; 47 import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTree; 48 import jdk.javadoc.internal.doclets.formats.html.markup.Links; 49 import jdk.javadoc.internal.doclets.formats.html.markup.StringContent; 50 import jdk.javadoc.internal.doclets.formats.html.markup.Table; 51 import jdk.javadoc.internal.doclets.formats.html.markup.TableHeader; 52 import jdk.javadoc.internal.doclets.toolkit.Content; 53 import jdk.javadoc.internal.doclets.toolkit.MemberSummaryWriter; 54 import jdk.javadoc.internal.doclets.toolkit.Resources; 55 import jdk.javadoc.internal.doclets.toolkit.taglets.DeprecatedTaglet; 56 import jdk.javadoc.internal.doclets.toolkit.util.DocletConstants; 57 import jdk.javadoc.internal.doclets.toolkit.util.Utils; 58 59 import static javax.lang.model.element.Modifier.ABSTRACT; 60 import static javax.lang.model.element.Modifier.NATIVE; 61 import static javax.lang.model.element.Modifier.PUBLIC; 62 import static javax.lang.model.element.Modifier.STRICTFP; 63 import static javax.lang.model.element.Modifier.SYNCHRONIZED; 64 65 /** 66 * The base class for member writers. 67 * 68 * <p><b>This is NOT part of any supported API. 69 * If you write code that depends on this, you do so at your own risk. 70 * This code and its internal interfaces are subject to change or 71 * deletion without notice.</b> 72 * 73 * @author Robert Field 74 * @author Atul M Dambalkar 75 * @author Jamie Ho (Re-write) 76 * @author Bhavesh Patel (Modified) 204 TypeElement typeElement, Element member, Content tdSummary); 205 206 /** 207 * Add the inherited summary link for the member. 208 * 209 * @param typeElement the TypeElement to be documented 210 * @param member the member to be documented 211 * @param linksTree the content tree to which the inherited summary link will be added 212 */ 213 protected abstract void addInheritedSummaryLink(TypeElement typeElement, 214 Element member, Content linksTree); 215 216 /** 217 * Get the deprecated link. 218 * 219 * @param member the member being linked to 220 * @return a content tree representing the link 221 */ 222 protected abstract Content getDeprecatedLink(Element member); 223 224 protected CharSequence makeSpace(int len) { 225 if (len <= 0) { 226 return ""; 227 } 228 StringBuilder sb = new StringBuilder(len); 229 for (int i = 0; i < len; i++) { 230 sb.append(' '); 231 } 232 return sb; 233 } 234 235 /** 236 * Add the modifier and type for the member in the member summary. 237 * 238 * @param member the member to add the type for 239 * @param type the type to add 240 * @param tdSummaryType the content tree to which the modified and type will be added 241 */ 242 protected void addModifierAndType(Element member, TypeMirror type, 243 Content tdSummaryType) { 499 * @return a content tree that will be added to the class documentation 500 */ 501 @Override 502 public Content getMemberTree(Content memberTree) { 503 return writer.getMemberTree(memberTree); 504 } 505 506 /** 507 * Get the member tree to be documented. 508 * 509 * @param memberTree the content tree of member to be documented 510 * @param isLastContent true if the content to be added is the last content 511 * @return a content tree that will be added to the class documentation 512 */ 513 public Content getMemberTree(Content memberTree, boolean isLastContent) { 514 if (isLastContent) 515 return HtmlTree.LI(HtmlStyle.blockListLast, memberTree); 516 else 517 return HtmlTree.LI(HtmlStyle.blockList, memberTree); 518 } 519 520 /** 521 * A HtmlTree builder for member signatures. 522 */ 523 class MemberSignature { 524 525 // The content builder 526 private Content content = new ContentBuilder(); 527 528 // Position of last line separator. 529 private int lastNewLine = 0; 530 531 // Threshold for length of type parameters before switching from inline to block representation. 532 private final static int TYPE_PARAMS_MAX_INLINE_LENGTH = 50; 533 534 // Threshold for combined length of modifiers, type params and return type before breaking 535 // it up with a line break before the return type. 536 private final static int RETURN_TYPE_MAX_LINE_LENGTH = 50; 537 538 /** 539 * Create a new member signature tree. 540 * 541 * @param element The element for which to create a signature. 542 */ 543 MemberSignature(Element element) { 544 Content annotationInfo = writer.getAnnotationInfo(element.getAnnotationMirrors(), true); 545 if (!annotationInfo.isEmpty()) { 546 content.add(HtmlTree.SPAN(HtmlStyle.annotations, annotationInfo)); 547 lastNewLine = content.charCount(); 548 } 549 addModifiers(element); 550 } 551 552 /** 553 * Add the modifier for the member. The modifiers are ordered as specified 554 * by <em>The Java Language Specification</em>. 555 * 556 * @param member the member for which the modifier will be added. 557 */ 558 void addModifiers(Element member) { 559 Set<Modifier> set = new TreeSet<>(member.getModifiers()); 560 561 // remove the ones we really don't need 562 set.remove(NATIVE); 563 set.remove(SYNCHRONIZED); 564 set.remove(STRICTFP); 565 566 // According to JLS, we should not be showing public modifier for 567 // interface methods. 568 if ((utils.isField(member) || utils.isMethod(member)) 569 && ((writer instanceof ClassWriterImpl 570 && utils.isInterface(((ClassWriterImpl) writer).getTypeElement()) || 571 writer instanceof AnnotationTypeWriterImpl) )) { 572 // Remove the implicit abstract and public modifiers 573 if (utils.isMethod(member) && 574 (utils.isInterface(member.getEnclosingElement()) || 575 utils.isAnnotationType(member.getEnclosingElement()))) { 576 set.remove(ABSTRACT); 577 set.remove(PUBLIC); 578 } 579 if (!utils.isMethod(member)) { 580 set.remove(PUBLIC); 581 } 582 } 583 if (!set.isEmpty()) { 584 String mods = set.stream().map(Modifier::toString).collect(Collectors.joining(" ")); 585 content.add(HtmlTree.SPAN(HtmlStyle.modifiers, new StringContent(mods))); 586 content.add(Entity.NO_BREAK_SPACE); 587 } 588 } 589 590 /** 591 * Add the type parameters and return type for an executable member. 592 * 593 * @param typeParameters the content tree containing the type parameters to add. 594 * @param returnType the content tree containing the return type to add. 595 */ 596 void addTypeParametersAndReturnType(Content typeParameters, Content returnType) { 597 598 if (!typeParameters.isEmpty()) { 599 // Apply different wrapping strategies for type parameters 600 // depending of combined length of type parameters and return type. 601 int typeParamLength = typeParameters.charCount(); 602 603 if (typeParamLength >= TYPE_PARAMS_MAX_INLINE_LENGTH) { 604 content.add(HtmlTree.SPAN(HtmlStyle.typeParametersLong, typeParameters)); 605 } else { 606 content.add(HtmlTree.SPAN(HtmlStyle.typeParameters, typeParameters)); 607 } 608 609 // count below includes modifiers plus type params added above 610 if (charCountFromNewline() + returnType.charCount()> RETURN_TYPE_MAX_LINE_LENGTH) { 611 content.add(DocletConstants.NL); 612 lastNewLine = content.charCount(); 613 } else { 614 content.add(Entity.NO_BREAK_SPACE); 615 } 616 } 617 618 content.add(HtmlTree.SPAN(HtmlStyle.returnType, returnType)); 619 content.add(Entity.NO_BREAK_SPACE); 620 } 621 622 /** 623 * Add the type information for a non-executable member. 624 * 625 * @param type the type of the member. 626 */ 627 void addType(TypeMirror type) { 628 Content typeLink = writer.getLink(new LinkInfoImpl(configuration, LinkInfoImpl.Kind.MEMBER, type)); 629 content.add(HtmlTree.SPAN(HtmlStyle.returnType, typeLink)); 630 content.add(Entity.NO_BREAK_SPACE); 631 } 632 633 /** 634 * Add the name of a member. 635 * 636 * @param element the member being documented. 637 */ 638 void addName(Element element) { 639 HtmlTree nameSpan = new HtmlTree(HtmlTag.SPAN); 640 nameSpan.setStyle(HtmlStyle.memberName); 641 if (configuration.linksource) { 642 Content name = new StringContent(name(element)); 643 writer.addSrcLink(element, name, nameSpan); 644 } else { 645 nameSpan.add(name(element)); 646 } 647 content.add(nameSpan); 648 } 649 650 /** 651 * Add the parameter and exception information of an executable member. 652 * 653 * @param paramTree the content tree containing the parameter information. 654 * @param exceptionTree the content tree containing the exception information. 655 */ 656 void addParametersAndExceptions(Content paramTree, Content exceptionTree) { 657 int indentSize = charCountFromNewline(); 658 659 if (paramTree.isEmpty()) { 660 content.add("()"); 661 } else { 662 content.add(Entity.ZERO_WIDTH_SPACE); 663 content.add("("); 664 content.add(HtmlTree.SPAN(HtmlStyle.arguments, paramTree)); 665 paramTree.add(")"); 666 } 667 668 if (!exceptionTree.isEmpty()) { 669 CharSequence indent = makeSpace(indentSize + 1 - 7); 670 content.add(DocletConstants.NL); 671 content.add(indent); 672 content.add("throws "); 673 content.add(HtmlTree.SPAN(HtmlStyle.exceptions, exceptionTree)); 674 } 675 } 676 677 /** 678 * Return the number of characters of plain text content since the last newline character. 679 * 680 * @return the number of plain text characters since the last newline character 681 */ 682 int charCountFromNewline() { 683 return content.charCount() - lastNewLine; 684 } 685 686 /** 687 * Return a HTML tree containing the member signature. 688 * 689 * @return the member signature 690 */ 691 Content toContent() { 692 return HtmlTree.DIV(HtmlStyle.memberSignature, content); 693 } 694 695 } 696 } |