< prev index next >

src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/Utils.java

Print this page
rev 58565 : records: mark record related model API as preview


  30 import java.net.URI;
  31 import java.text.CollationKey;
  32 import java.text.Collator;
  33 import java.text.ParseException;
  34 import java.text.RuleBasedCollator;
  35 import java.util.*;
  36 import java.util.AbstractMap.SimpleEntry;
  37 import java.util.Map.Entry;
  38 import java.util.stream.Collectors;
  39 
  40 import javax.lang.model.SourceVersion;
  41 import javax.lang.model.element.AnnotationMirror;
  42 import javax.lang.model.element.AnnotationValue;
  43 import javax.lang.model.element.Element;
  44 import javax.lang.model.element.ElementKind;
  45 import javax.lang.model.element.ExecutableElement;
  46 import javax.lang.model.element.Modifier;
  47 import javax.lang.model.element.ModuleElement;
  48 import javax.lang.model.element.ModuleElement.RequiresDirective;
  49 import javax.lang.model.element.PackageElement;

  50 import javax.lang.model.element.TypeElement;
  51 import javax.lang.model.element.TypeParameterElement;
  52 import javax.lang.model.element.VariableElement;
  53 import javax.lang.model.type.ArrayType;
  54 import javax.lang.model.type.DeclaredType;
  55 import javax.lang.model.type.ErrorType;
  56 import javax.lang.model.type.ExecutableType;
  57 import javax.lang.model.type.NoType;
  58 import javax.lang.model.type.PrimitiveType;
  59 import javax.lang.model.type.TypeMirror;
  60 import javax.lang.model.type.TypeVariable;
  61 import javax.lang.model.type.WildcardType;
  62 import javax.lang.model.util.ElementFilter;
  63 import javax.lang.model.util.ElementKindVisitor9;
  64 import javax.lang.model.util.Elements;
  65 import javax.lang.model.util.SimpleElementVisitor9;
  66 import javax.lang.model.util.SimpleTypeVisitor9;
  67 import javax.lang.model.util.TypeKindVisitor9;
  68 import javax.lang.model.util.Types;
  69 import javax.tools.FileObject;
  70 import javax.tools.JavaFileManager;
  71 import javax.tools.JavaFileManager.Location;
  72 import javax.tools.StandardLocation;
  73 
  74 import com.sun.source.doctree.DocCommentTree;
  75 import com.sun.source.doctree.DocTree;
  76 import com.sun.source.doctree.DocTree.Kind;
  77 import com.sun.source.doctree.ParamTree;
  78 import com.sun.source.doctree.SerialFieldTree;
  79 import com.sun.source.tree.CompilationUnitTree;
  80 import com.sun.source.tree.LineMap;
  81 import com.sun.source.util.DocSourcePositions;
  82 import com.sun.source.util.DocTrees;
  83 import com.sun.source.util.TreePath;
  84 import com.sun.tools.javac.model.JavacTypes;
  85 import jdk.javadoc.internal.doclets.formats.html.SearchIndexItem;


 284             return loc;
 285 
 286         return defaultLocation();
 287     }
 288 
 289     private Location defaultLocation() {
 290         JavaFileManager fm = configuration.docEnv.getJavaFileManager();
 291         return fm.hasLocation(StandardLocation.SOURCE_PATH)
 292                 ? StandardLocation.SOURCE_PATH
 293                 : StandardLocation.CLASS_PATH;
 294     }
 295 
 296     public boolean isAnnotated(TypeMirror e) {
 297         return !e.getAnnotationMirrors().isEmpty();
 298     }
 299 
 300     public boolean isAnnotated(Element e) {
 301         return !e.getAnnotationMirrors().isEmpty();
 302     }
 303 

 304     public boolean isAnnotationType(Element e) {
 305         return new SimpleElementVisitor9<Boolean, Void>() {
 306             @Override
 307             public Boolean visitExecutable(ExecutableElement e, Void p) {
 308                 return visit(e.getEnclosingElement());
 309             }
 310 
 311             @Override
 312             public Boolean visitUnknown(Element e, Void p) {
 313                 return false;
 314             }
 315 
 316             @Override
 317             protected Boolean defaultAction(Element e, Void p) {
 318                 return e.getKind() == ANNOTATION_TYPE;
 319             }
 320         }.visit(e);
 321     }
 322 
 323     /**
 324      * An Enum implementation is almost identical, thus this method returns if
 325      * this element represents a CLASS or an ENUM


 399     public String getPropertyLabel(String name) {
 400         return name.substring(0, name.lastIndexOf("Property"));
 401     }
 402 
 403     public boolean isOverviewElement(Element e) {
 404         return e.getKind() == ElementKind.OTHER;
 405     }
 406 
 407     public boolean isStatic(Element e) {
 408         return e.getModifiers().contains(Modifier.STATIC);
 409     }
 410 
 411     public boolean isSerializable(TypeElement e) {
 412         return typeUtils.isSubtype(e.asType(), getSerializableType());
 413     }
 414 
 415     public boolean isExternalizable(TypeElement e) {
 416         return typeUtils.isSubtype(e.asType(), getExternalizableType());
 417     }
 418 




























 419     public SortedSet<VariableElement> serializableFields(TypeElement aclass) {
 420         return configuration.workArounds.getSerializableFields(aclass);
 421     }
 422 
 423     public SortedSet<ExecutableElement> serializationMethods(TypeElement aclass) {
 424         return configuration.workArounds.getSerializationMethods(aclass);
 425     }
 426 
 427     public boolean definesSerializableFields(TypeElement aclass) {
 428         return configuration.workArounds.definesSerializableFields( aclass);
 429     }
 430 

 431     public String modifiersToString(Element e, boolean trailingSpace) {
 432         SortedSet<Modifier> set = new TreeSet<>(e.getModifiers());
 433         set.remove(Modifier.NATIVE);
 434         set.remove(Modifier.STRICTFP);
 435         set.remove(Modifier.SYNCHRONIZED);
 436 
 437         return new ElementKindVisitor9<String, SortedSet<Modifier>>() {
 438             final StringBuilder sb = new StringBuilder();
 439 
 440             void addVisibilityModifier(Set<Modifier> modifiers) {
 441                 if (modifiers.contains(PUBLIC)) {
 442                     sb.append("public").append(" ");
 443                 } else if (modifiers.contains(PROTECTED)) {
 444                     sb.append("protected").append(" ");
 445                 } else if (modifiers.contains(PRIVATE)) {
 446                     sb.append("private").append(" ");
 447                 }
 448             }
 449 
 450             void addStatic(Set<Modifier> modifiers) {
 451                 if (modifiers.contains(STATIC)) {
 452                     sb.append("static").append(" ");
 453                 }
 454             }
 455 
 456             void addModifers(Set<Modifier> modifiers) {
 457                 String s = set.stream().map(Modifier::toString).collect(Collectors.joining(" "));
 458                 sb.append(s);
 459                 if (!s.isEmpty())


 460                     sb.append(" ");
 461             }


 462 
 463             String finalString(String s) {
 464                 sb.append(s);
 465                 if (trailingSpace) {
 466                     if (sb.lastIndexOf(" ") == sb.length() - 1) {
 467                         return sb.toString();
 468                     } else {
 469                         return sb.append(" ").toString();
 470                     }
 471                 } else {
 472                     return sb.toString().trim();
 473                 }

 474             }
 475 
 476             @Override
 477             public String visitTypeAsInterface(TypeElement e, SortedSet<Modifier> p) {
 478                 addVisibilityModifier(p);
 479                 addStatic(p);
 480                 return finalString("interface");
 481             }
 482 
 483             @Override
 484             public String visitTypeAsEnum(TypeElement e, SortedSet<Modifier> p) {
 485                 addVisibilityModifier(p);
 486                 addStatic(p);
 487                 return finalString("enum");
 488             }
 489 
 490             @Override
 491             public String visitTypeAsAnnotationType(TypeElement e, SortedSet<Modifier> p) {
 492                 addVisibilityModifier(p);
 493                 addStatic(p);
 494                 return finalString("@interface");
 495             }
 496 
 497             @Override
 498             public String visitTypeAsClass(TypeElement e, SortedSet<Modifier> p) {
 499                 addModifers(p);
 500                 return finalString("class");
 501             }
 502 
 503             @Override
 504             protected String defaultAction(Element e, SortedSet<Modifier> p) {
 505                 addModifers(p);

















 506                 return sb.toString().trim();
 507             }
 508 
 509         }.visit(e, set);
 510     }
 511 
 512     public boolean isFunctionalInterface(AnnotationMirror amirror) {
 513         return amirror.getAnnotationType().equals(getFunctionalInterface()) &&
 514                 configuration.docEnv.getSourceVersion()
 515                         .compareTo(SourceVersion.RELEASE_8) >= 0;
 516     }
 517 
 518     public boolean isNoType(TypeMirror t) {
 519         return t.getKind() == NONE;
 520     }
 521 
 522     public boolean isOrdinaryClass(TypeElement te) {
 523         if (isEnum(te) || isInterface(te) || isAnnotationType(te)) {
 524             return false;
 525         }
 526         if (isError(te) || isException(te)) {
 527             return false;
 528         }
 529         return true;


 576                 return true;
 577             default:
 578                 return false;
 579         }
 580     }
 581 
 582     public boolean isVariableElement(Element e) {
 583         ElementKind kind = e.getKind();
 584         switch(kind) {
 585               case ENUM_CONSTANT: case EXCEPTION_PARAMETER: case FIELD:
 586               case LOCAL_VARIABLE: case PARAMETER:
 587               case RESOURCE_VARIABLE:
 588                   return true;
 589               default:
 590                   return false;
 591         }
 592     }
 593 
 594     public boolean isTypeElement(Element e) {
 595         switch (e.getKind()) {
 596             case CLASS: case ENUM: case INTERFACE: case ANNOTATION_TYPE:
 597                 return true;
 598             default:
 599                 return false;
 600         }
 601     }
 602 
 603     /**
 604      * Get the signature. It is the parameter list, type is qualified.
 605      * For instance, for a method {@code mymethod(String x, int y)},
 606      * it will return {@code(java.lang.String,int)}.
 607      *
 608      * @param e
 609      * @return String
 610      */
 611     public String signature(ExecutableElement e) {
 612         return makeSignature(e, true);
 613     }
 614 
 615     /**
 616      * Get flat signature.  All types are not qualified.


1346             switch (ch) {
1347                 case '\n':
1348                     sb.append(text, pos, i);
1349                     sb.append(NL);
1350                     pos = i + 1;
1351                     break;
1352                 case '\r':
1353                     sb.append(text, pos, i);
1354                     sb.append(NL);
1355                     if (i + 1 < textLength && text.charAt(i + 1) == '\n')
1356                         i++;
1357                     pos = i + 1;
1358                     break;
1359             }
1360         }
1361         sb.append(text, pos, textLength);
1362         return sb;
1363     }
1364 
1365     /**
1366      * The documentation for values() and valueOf() in Enums are set by the
1367      * doclet only iff the user or overridden methods are missing.
1368      * @param elem
1369      */
1370     public void setEnumDocumentation(TypeElement elem) {
1371         for (Element e : getMethods(elem)) {
1372             ExecutableElement ee = (ExecutableElement)e;
1373             if (!getFullBody(e).isEmpty()) // ignore if already set
1374                 continue;
1375             if (ee.getSimpleName().contentEquals("values") && ee.getParameters().isEmpty()) {
1376                 removeCommentHelper(ee); // purge previous entry
1377                 configuration.cmtUtils.setEnumValuesTree(e);
1378             }
1379             if (ee.getSimpleName().contentEquals("valueOf") && ee.getParameters().size() == 1) {
1380                 removeCommentHelper(ee); // purge previous entry
1381                 configuration.cmtUtils.setEnumValueOfTree(e);
1382             }
1383         }
1384     }
1385 
1386     /**
1387      * Returns a locale independent upper cased String. That is, it
1388      * always uses US locale, this is a clone of the one in StringUtils.
1389      * @param s to convert
1390      * @return converted String
1391      */
1392     public static String toUpperCase(String s) {
1393         return s.toUpperCase(Locale.US);
1394     }
1395 
1396     /**
1397      * Returns a locale independent lower cased String. That is, it
1398      * always uses US locale, this is a clone of the one in StringUtils.
1399      * @param s to convert
1400      * @return converted String
1401      */
1402     public static String toLowerCase(String s) {
1403         return s.toLowerCase(Locale.US);
1404     }
1405 
1406     /**


1743      */
1744     public Comparator<Element> makeOverrideUseComparator() {
1745         if (overrideUseComparator == null) {
1746             overrideUseComparator = new Utils.ElementComparator() {
1747                 @Override
1748                 public int compare(Element o1, Element o2) {
1749                     int result = compareStrings(getSimpleName(o1), getSimpleName(o2));
1750                     if (result != 0) {
1751                         return result;
1752                     }
1753                     if (!isTypeElement(o1) && !isTypeElement(o2) && !isPackage(o1) && !isPackage(o2)) {
1754                         TypeElement t1 = getEnclosingTypeElement(o1);
1755                         TypeElement t2 = getEnclosingTypeElement(o2);
1756                         result = compareStrings(getSimpleName(t1), getSimpleName(t2));
1757                         if (result != 0)
1758                             return result;
1759                     }
1760                     result = compareStrings(getFullyQualifiedName(o1), getFullyQualifiedName(o2));
1761                     if (result != 0)
1762                         return result;
1763                     return compareElementTypeKinds(o1, o2);
1764                 }
1765             };
1766         }
1767         return overrideUseComparator;
1768     }
1769 
1770     private Comparator<Element> indexUseComparator = null;
1771     /**
1772      *  Returns a Comparator for index file presentations, and are sorted as follows.
1773      *  If comparing modules and/or packages then simply compare the qualified names,
1774      *  if comparing a module or a package with a type/member then compare the
1775      *  FullyQualifiedName of the module or a package with the SimpleName of the entity,
1776      *  otherwise:
1777      *  1. compare the ElementKind ex: Module, Package, Interface etc.
1778      *  2a. if equal and if the type is of ExecutableElement(Constructor, Methods),
1779      *      a case insensitive comparison of parameter the type signatures
1780      *  2b. if equal, case sensitive comparison of the type signatures
1781      *  3. finally, if equal, compare the FQNs of the entities
1782      * @return a comparator for index file use
1783      */


1792                  * @return a negative integer, zero, or a positive integer as the first
1793                  * argument is less than, equal to, or greater than the second.
1794                  */
1795                 @Override
1796                 public int compare(Element e1, Element e2) {
1797                     int result;
1798                     // first, compare names as appropriate
1799                     if ((isModule(e1) || isPackage(e1)) && (isModule(e2) || isPackage(e2))) {
1800                         result = compareFullyQualifiedNames(e1, e2);
1801                     } else if (isModule(e1) || isPackage(e1)) {
1802                         result = compareStrings(getFullyQualifiedName(e1), getSimpleName(e2));
1803                     } else if (isModule(e2) || isPackage(e2)) {
1804                         result = compareStrings(getSimpleName(e1), getFullyQualifiedName(e2));
1805                     } else {
1806                         result = compareNames(e1, e2);
1807                     }
1808                     if (result != 0) {
1809                         return result;
1810                     }
1811                     // if names are the same, compare element kinds
1812                     result = compareElementTypeKinds(e1, e2);
1813                     if (result != 0) {
1814                         return result;
1815                     }
1816                     // if element kinds are the same, and are methods,
1817                     // compare the method parameters
1818                     if (hasParameters(e1)) {
1819                         List<? extends VariableElement> parameters1 = ((ExecutableElement)e1).getParameters();
1820                         List<? extends VariableElement> parameters2 = ((ExecutableElement)e2).getParameters();
1821                         result = compareParameters(false, parameters1, parameters2);
1822                         if (result != 0) {
1823                             return result;
1824                         }
1825                         result = compareParameters(true, parameters1, parameters2);
1826                         if (result != 0) {
1827                             return result;
1828                         }
1829                     }
1830                     // else fall back on fully qualified names
1831                     return compareFullyQualifiedNames(e1, e2);
1832                 }


1900 
1901             @Override
1902             protected String defaultAction(TypeMirror t, Void p) {
1903                 return t.toString();
1904             }
1905 
1906         }.visit(t);
1907     }
1908 
1909     /**
1910      * A generic utility which returns the fully qualified names of an entity,
1911      * if the entity is not qualifiable then its enclosing entity, it is upto
1912      * the caller to add the elements name as required.
1913      * @param e the element to get FQN for.
1914      * @return the name
1915      */
1916     public String getFullyQualifiedName(Element e) {
1917         return getFullyQualifiedName(e, true);
1918     }
1919 

1920     public String getFullyQualifiedName(Element e, final boolean outer) {
1921         return new SimpleElementVisitor9<String, Void>() {
1922             @Override
1923             public String visitModule(ModuleElement e, Void p) {
1924                 return e.getQualifiedName().toString();
1925             }
1926 
1927             @Override
1928             public String visitPackage(PackageElement e, Void p) {
1929                 return e.getQualifiedName().toString();
1930             }
1931 
1932             @Override
1933             public String visitType(TypeElement e, Void p) {
1934                 return e.getQualifiedName().toString();
1935             }
1936 
1937             @Override
1938             protected String defaultAction(Element e, Void p) {
1939                 return outer ? visit(e.getEnclosingElement()) : e.getSimpleName().toString();
1940             }
1941         }.visit(e);


1968                         return result;
1969                     }
1970                     result = compareFullyQualifiedNames(e1, e2);
1971                     if (result != 0) {
1972                         return result;
1973                     }
1974                     if (hasParameters(e1) && hasParameters(e2)) {
1975                         @SuppressWarnings("unchecked")
1976                         List<VariableElement> parameters1 = (List<VariableElement>)((ExecutableElement)e1).getParameters();
1977                         @SuppressWarnings("unchecked")
1978                         List<VariableElement> parameters2 = (List<VariableElement>)((ExecutableElement)e2).getParameters();
1979                         result = compareParameters(false, parameters1, parameters2);
1980                         if (result != 0) {
1981                             return result;
1982                         }
1983                         result = compareParameters(true, parameters1, parameters2);
1984                     }
1985                     if (result != 0) {
1986                         return result;
1987                     }
1988                     return compareElementTypeKinds(e1, e2);
1989                 }
1990             };
1991         }
1992         return classUseComparator;
1993     }
1994 
1995     /**
1996      * A general purpose comparator to sort Element entities, basically provides the building blocks
1997      * for creating specific comparators for an use-case.
1998      */
1999     private abstract class ElementComparator implements Comparator<Element> {


2000         /**
2001          * compares two parameter arrays by first comparing the length of the arrays, and
2002          * then each Type of the parameter in the array.
2003          * @param params1 the first parameter array.
2004          * @param params2 the first parameter array.
2005          * @return a negative integer, zero, or a positive integer as the first
2006          *         argument is less than, equal to, or greater than the second.
2007          */
2008         final EnumMap<ElementKind, Integer> elementKindOrder;
2009         public ElementComparator() {
2010             elementKindOrder = new EnumMap<>(ElementKind.class);
2011             elementKindOrder.put(ElementKind.MODULE, 0);
2012             elementKindOrder.put(ElementKind.PACKAGE, 1);
2013             elementKindOrder.put(ElementKind.CLASS, 2);
2014             elementKindOrder.put(ElementKind.ENUM, 3);
2015             elementKindOrder.put(ElementKind.ENUM_CONSTANT, 4);
2016             elementKindOrder.put(ElementKind.INTERFACE, 5);
2017             elementKindOrder.put(ElementKind.ANNOTATION_TYPE, 6);
2018             elementKindOrder.put(ElementKind.FIELD, 7);
2019             elementKindOrder.put(ElementKind.CONSTRUCTOR, 8);
2020             elementKindOrder.put(ElementKind.METHOD, 9);
2021         }
2022 
2023         protected int compareParameters(boolean caseSensitive, List<? extends VariableElement> params1,
2024                                                                List<? extends VariableElement> params2) {
2025 
2026             return compareStrings(caseSensitive, getParametersAsString(params1),
2027                                                  getParametersAsString(params2));
2028         }
2029 
2030         String getParametersAsString(List<? extends VariableElement> params) {
2031             StringBuilder sb = new StringBuilder();
2032             for (VariableElement param : params) {
2033                 TypeMirror t = param.asType();
2034                 // prefix P for primitive and R for reference types, thus items will
2035                 // be ordered lexically and correctly.
2036                 sb.append(getTypeCode(t)).append("-").append(t).append("-");
2037             }
2038             return sb.toString();
2039         }
2040 
2041         private String getTypeCode(TypeMirror t) {
2042             return new SimpleTypeVisitor9<String, Void>() {


2065          * @return a negative integer, zero, or a positive integer as the first
2066          *         argument is less than, equal to, or greater than the second.
2067          */
2068         protected int compareNames(Element e1, Element e2) {
2069             return compareStrings(getSimpleName(e1), getSimpleName(e2));
2070         }
2071 
2072         /**
2073          * Compares the fully qualified names of the entities
2074          * @param e1 the first Element.
2075          * @param e2 the first Element.
2076          * @return a negative integer, zero, or a positive integer as the first
2077          *         argument is less than, equal to, or greater than the second.
2078          */
2079         protected int compareFullyQualifiedNames(Element e1, Element e2) {
2080             // add simplename to be compatible
2081             String thisElement = getFullyQualifiedName(e1);
2082             String thatElement = getFullyQualifiedName(e2);
2083             return compareStrings(thisElement, thatElement);
2084         }
2085         protected int compareElementTypeKinds(Element e1, Element e2) {
2086             return Integer.compare(elementKindOrder.get(e1.getKind()),
2087                                    elementKindOrder.get(e2.getKind()));
2088         }



















2089         boolean hasParameters(Element e) {
2090             return new SimpleElementVisitor9<Boolean, Void>() {
2091                 @Override
2092                 public Boolean visitExecutable(ExecutableElement e, Void p) {
2093                     return true;
2094                 }
2095 
2096                 @Override
2097                 protected Boolean defaultAction(Element e, Void p) {
2098                     return false;
2099                 }
2100 
2101             }.visit(e);
2102         }
2103 
2104         /**
2105          * The fully qualified names of the entities, used solely by the comparator.
2106          *
2107          * @return a negative integer, zero, or a positive integer as the first argument is less
2108          * than, equal to, or greater than the second.
2109          */

2110         private String getFullyQualifiedName(Element e) {
2111             return new SimpleElementVisitor9<String, Void>() {
2112                 @Override
2113                 public String visitModule(ModuleElement e, Void p) {
2114                     return e.getQualifiedName().toString();
2115                 }
2116 
2117                 @Override
2118                 public String visitPackage(PackageElement e, Void p) {
2119                     return e.getQualifiedName().toString();
2120                 }
2121 
2122                 @Override
2123                 public String visitExecutable(ExecutableElement e, Void p) {
2124                     // For backward compatibility
2125                     return getFullyQualifiedName(e.getEnclosingElement())
2126                             + "." + e.getSimpleName().toString();
2127                 }
2128 
2129                 @Override
2130                 public String visitType(TypeElement e, Void p) {
2131                     return e.getQualifiedName().toString();


2170     public Comparator<SearchIndexItem> makeGenericSearchIndexComparator() {
2171         if (genericSearchIndexComparator == null) {
2172             genericSearchIndexComparator = (SearchIndexItem sii1, SearchIndexItem sii2) -> {
2173                 int result = compareStrings(sii1.getLabel(), sii2.getLabel());
2174                 if (result == 0) {
2175                     // TreeSet needs this to be consistent with equal so we do
2176                     // a plain comparison of string representations as fallback.
2177                     result = sii1.toString().compareTo(sii2.toString());
2178                 }
2179                 return result;
2180             };
2181         }
2182         return genericSearchIndexComparator;
2183     }
2184 
2185     public Iterable<TypeElement> getEnclosedTypeElements(PackageElement pkg) {
2186         List<TypeElement> out = getInterfaces(pkg);
2187         out.addAll(getClasses(pkg));
2188         out.addAll(getEnums(pkg));
2189         out.addAll(getAnnotationTypes(pkg));

2190         return out;
2191     }
2192 
2193     // Element related methods
2194     public List<Element> getAnnotationMembers(TypeElement aClass) {
2195         List<Element> members = getAnnotationFields(aClass);
2196         members.addAll(getAnnotationMethods(aClass));
2197         return members;
2198     }
2199 
2200     public List<Element> getAnnotationFields(TypeElement aClass) {
2201         return getItems0(aClass, true, FIELD);
2202     }
2203 
2204     List<Element> getAnnotationFieldsUnfiltered(TypeElement aClass) {
2205         return getItems0(aClass, true, FIELD);
2206     }
2207 
2208     public List<Element> getAnnotationMethods(TypeElement aClass) {
2209         return getItems0(aClass, true, METHOD);
2210     }
2211 
2212     public List<TypeElement> getAnnotationTypes(Element e) {
2213         return convertToTypeElement(getItems(e, true, ANNOTATION_TYPE));
2214     }
2215 
2216     public List<TypeElement> getAnnotationTypesUnfiltered(Element e) {
2217         return convertToTypeElement(getItems(e, false, ANNOTATION_TYPE));
2218     }
2219 










2220     public List<VariableElement> getFields(Element e) {
2221         return convertToVariableElement(getItems(e, true, FIELD));
2222     }
2223 
2224     public List<VariableElement> getFieldsUnfiltered(Element e) {
2225         return convertToVariableElement(getItems(e, false, FIELD));
2226     }
2227 
2228     public List<TypeElement> getClasses(Element e) {
2229        return convertToTypeElement(getItems(e, true, CLASS));
2230     }
2231 
2232     public List<TypeElement> getClassesUnfiltered(Element e) {
2233        return convertToTypeElement(getItems(e, false, CLASS));
2234     }
2235 
2236     public List<ExecutableElement> getConstructors(Element e) {
2237         return convertToExecutableElement(getItems(e, true, CONSTRUCTOR));
2238     }
2239 


2354     public List<TypeElement> getInterfacesUnfiltered(Element e)  {
2355         return convertToTypeElement(getItems(e, false, INTERFACE));
2356     }
2357 
2358     public List<Element> getEnumConstants(Element e) {
2359         return getItems(e, true, ENUM_CONSTANT);
2360     }
2361 
2362     public List<TypeElement> getEnums(Element e) {
2363         return convertToTypeElement(getItems(e, true, ENUM));
2364     }
2365 
2366     public List<TypeElement> getEnumsUnfiltered(Element e) {
2367         return convertToTypeElement(getItems(e, false, ENUM));
2368     }
2369 
2370     public SortedSet<TypeElement> getAllClassesUnfiltered(Element e) {
2371         List<TypeElement> clist = getClassesUnfiltered(e);
2372         clist.addAll(getInterfacesUnfiltered(e));
2373         clist.addAll(getAnnotationTypesUnfiltered(e));

2374         SortedSet<TypeElement> oset = new TreeSet<>(makeGeneralPurposeComparator());
2375         oset.addAll(clist);
2376         return oset;
2377     }
2378 
2379     private final HashMap<Element, SortedSet<TypeElement>> cachedClasses = new HashMap<>();
2380     /**
2381      * Returns a list containing classes and interfaces,
2382      * including annotation types.
2383      * @param e Element
2384      * @return List
2385      */
2386     public SortedSet<TypeElement> getAllClasses(Element e) {
2387         SortedSet<TypeElement> oset = cachedClasses.get(e);
2388         if (oset != null)
2389             return oset;
2390         List<TypeElement> clist = getClasses(e);
2391         clist.addAll(getInterfaces(e));
2392         clist.addAll(getAnnotationTypes(e));
2393         clist.addAll(getEnums(e));

2394         oset = new TreeSet<>(makeGeneralPurposeComparator());
2395         oset.addAll(clist);
2396         cachedClasses.put(e, oset);
2397         return oset;
2398     }
2399 
2400     /*
2401      * Get all the elements unfiltered and filter them finally based
2402      * on its visibility, this works differently from the other getters.
2403      */
2404     private List<TypeElement> getInnerClasses(Element e, boolean filter) {
2405         List<TypeElement> olist = new ArrayList<>();
2406         for (TypeElement te : getClassesUnfiltered(e)) {
2407             if (!filter || configuration.docEnv.isSelected(te)) {
2408                 olist.add(te);
2409             }
2410         }
2411         for (TypeElement te : getInterfacesUnfiltered(e)) {
2412             if (!filter || configuration.docEnv.isSelected(te)) {
2413                 olist.add(te);


2442     public List<TypeElement> getOrdinaryClasses(Element e) {
2443         return getClasses(e).stream()
2444                 .filter(te -> (!isException(te) && !isError(te)))
2445                 .collect(Collectors.toList());
2446     }
2447 
2448     public List<TypeElement> getErrors(Element e) {
2449         return getClasses(e)
2450                 .stream()
2451                 .filter(this::isError)
2452                 .collect(Collectors.toList());
2453     }
2454 
2455     public List<TypeElement> getExceptions(Element e) {
2456         return getClasses(e)
2457                 .stream()
2458                 .filter(this::isException)
2459                 .collect(Collectors.toList());
2460     }
2461 

2462     List<Element> getItems(Element e, boolean filter, ElementKind select) {
2463         List<Element> elements = new ArrayList<>();
2464         return new SimpleElementVisitor9<List<Element>, Void>() {
2465 
2466             @Override
2467             public List<Element> visitPackage(PackageElement e, Void p) {
2468                 recursiveGetItems(elements, e, filter, select);
2469                 return elements;
2470             }
2471 
2472             @Override
2473             protected List<Element> defaultAction(Element e0, Void p) {
2474                 return getItems0(e0, filter, select);
2475             }
2476 
2477         }.visit(e);
2478     }
2479 
2480     EnumSet<ElementKind> nestedKinds = EnumSet.of(ANNOTATION_TYPE, CLASS, ENUM, INTERFACE);
2481     void recursiveGetItems(Collection<Element> list, Element e, boolean filter, ElementKind... select) {
2482         list.addAll(getItems0(e, filter, select));
2483         List<Element> classes = getItems0(e, filter, nestedKinds);
2484         for (Element c : classes) {


2489         }
2490     }
2491 
2492     private List<Element> getItems0(Element te, boolean filter, ElementKind... select) {
2493         EnumSet<ElementKind> kinds = EnumSet.copyOf(Arrays.asList(select));
2494         return getItems0(te, filter, kinds);
2495     }
2496 
2497     private List<Element> getItems0(Element te, boolean filter, Set<ElementKind> kinds) {
2498         List<Element> elements = new ArrayList<>();
2499         for (Element e : te.getEnclosedElements()) {
2500             if (kinds.contains(e.getKind())) {
2501                 if (!filter || shouldDocument(e)) {
2502                     elements.add(e);
2503                 }
2504             }
2505         }
2506         return elements;
2507     }
2508 
2509     private SimpleElementVisitor9<Boolean, Void> shouldDocumentVisitor = null;

2510 
2511     protected boolean shouldDocument(Element e) {

2512         if (shouldDocumentVisitor == null) {
2513             shouldDocumentVisitor = new SimpleElementVisitor9<Boolean, Void>() {
2514                 private boolean hasSource(TypeElement e) {
2515                     return configuration.docEnv.getFileKind(e) ==
2516                             javax.tools.JavaFileObject.Kind.SOURCE;
2517                 }
2518 
2519                 // handle types
2520                 @Override
2521                 public Boolean visitType(TypeElement e, Void p) {
2522                     // treat inner classes etc as members
2523                     if (e.getNestingKind().isNested()) {
2524                         return defaultAction(e, p);
2525                     }
2526                     return configuration.docEnv.isSelected(e) && hasSource(e);
2527                 }
2528 
2529                 // handle everything else
2530                 @Override
2531                 protected Boolean defaultAction(Element e, Void p) {
2532                     return configuration.docEnv.isSelected(e);
2533                 }


2543 
2544     /*
2545      * nameCache is maintained for improving the comparator
2546      * performance, noting that the Collator used by the comparators
2547      * use Strings, as of this writing.
2548      * TODO: when those APIs handle charSequences, the use of
2549      * this nameCache must be re-investigated and removed.
2550      */
2551     private final Map<Element, String> nameCache = new LinkedHashMap<>();
2552 
2553     /**
2554      * Returns the name of the element after the last dot of the package name.
2555      * This emulates the behavior of the old doclet.
2556      * @param e an element whose name is required
2557      * @return the name
2558      */
2559     public String getSimpleName(Element e) {
2560         return nameCache.computeIfAbsent(e, this::getSimpleName0);
2561     }
2562 
2563     private SimpleElementVisitor9<String, Void> snvisitor = null;

2564 

2565     private String getSimpleName0(Element e) {
2566         if (snvisitor == null) {
2567             snvisitor = new SimpleElementVisitor9<String, Void>() {
2568                 @Override
2569                 public String visitModule(ModuleElement e, Void p) {
2570                     return e.getQualifiedName().toString();  // temp fix for 8182736
2571                 }
2572 
2573                 @Override
2574                 public String visitType(TypeElement e, Void p) {
2575                     StringBuilder sb = new StringBuilder(e.getSimpleName());
2576                     Element enclosed = e.getEnclosingElement();
2577                     while (enclosed != null
2578                             && (enclosed.getKind().isClass() || enclosed.getKind().isInterface())) {
2579                         sb.insert(0, enclosed.getSimpleName() + ".");
2580                         enclosed = enclosed.getEnclosingElement();
2581                     }
2582                     return sb.toString();
2583                 }
2584 
2585                 @Override
2586                 public String visitExecutable(ExecutableElement e, Void p) {
2587                     if (e.getKind() == CONSTRUCTOR || e.getKind() == STATIC_INIT) {


2728             final String chars = "0123456789abcdef";
2729             buf.append("\\u");
2730             buf.append(chars.charAt(15 & (c>>12)));
2731             buf.append(chars.charAt(15 & (c>>8)));
2732             buf.append(chars.charAt(15 & (c>>4)));
2733             buf.append(chars.charAt(15 & (c>>0)));
2734         }
2735         private boolean isPrintableAscii(char c) {
2736             return c >= ' ' && c <= '~';
2737         }
2738     }
2739 
2740     public boolean isEnclosingPackageIncluded(TypeElement te) {
2741         return isIncluded(containingPackage(te));
2742     }
2743 
2744     public boolean isIncluded(Element e) {
2745         return configuration.docEnv.isIncluded(e);
2746     }
2747 
2748     private SimpleElementVisitor9<Boolean, Void> specifiedVisitor = null;


2749     public boolean isSpecified(Element e) {
2750         if (specifiedVisitor == null) {
2751             specifiedVisitor = new SimpleElementVisitor9<Boolean, Void>() {
2752                 @Override
2753                 public Boolean visitModule(ModuleElement e, Void p) {
2754                     return configuration.getSpecifiedModuleElements().contains(e);
2755                 }
2756 
2757                 @Override
2758                 public Boolean visitPackage(PackageElement e, Void p) {
2759                     return configuration.getSpecifiedPackageElements().contains(e);
2760                 }
2761 
2762                 @Override
2763                 public Boolean visitType(TypeElement e, Void p) {
2764                     return configuration.getSpecifiedTypeElements().contains(e);
2765                 }
2766 
2767                 @Override
2768                 protected Boolean defaultAction(Element e, Void p) {
2769                     return false;
2770                 }
2771             };


3179     public List<? extends DocTree> getProvidesTrees(Element element) {
3180         return getBlockTags(element, PROVIDES);
3181     }
3182 
3183     public List<? extends DocTree> getSeeTrees(Element element) {
3184         return getBlockTags(element, SEE);
3185     }
3186 
3187     public List<? extends DocTree> getSerialTrees(Element element) {
3188         return getBlockTags(element, SERIAL);
3189     }
3190 
3191     public List<? extends DocTree> getSerialFieldTrees(VariableElement field) {
3192         return getBlockTags(field, DocTree.Kind.SERIAL_FIELD);
3193     }
3194 
3195     public List<? extends DocTree> getThrowsTrees(Element element) {
3196         return getBlockTags(element, DocTree.Kind.EXCEPTION, DocTree.Kind.THROWS);
3197     }
3198 
3199     public List<? extends DocTree> getTypeParamTrees(Element element) {
3200         return getParamTrees(element, true);
3201     }
3202 
3203     public List<? extends DocTree> getParamTrees(Element element) {
3204         return getParamTrees(element, false);
3205     }
3206 
3207     private  List<? extends DocTree> getParamTrees(Element element, boolean isTypeParameters) {
3208         List<DocTree> out = new ArrayList<>();
3209         for (DocTree dt : getBlockTags(element, PARAM)) {
3210             ParamTree pt = (ParamTree) dt;
3211             if (pt.isTypeParameter() == isTypeParameters) {
3212                 out.add(dt);
3213             }
3214         }
3215         return out;
3216     }
3217 
3218     public  List<? extends DocTree> getReturnTrees(Element element) {
3219         List<DocTree> out = new ArrayList<>();
3220         for (DocTree dt : getBlockTags(element, RETURN)) {
3221             out.add(dt);
3222         }
3223         return out;
3224     }
3225 
3226     public List<? extends DocTree> getUsesTrees(Element element) {
3227         return getBlockTags(element, USES);
3228     }
3229 
3230     public List<? extends DocTree> getFirstSentenceTrees(Element element) {
3231         DocCommentTree dcTree = getDocCommentTree(element);
3232         if (dcTree == null) {




  30 import java.net.URI;
  31 import java.text.CollationKey;
  32 import java.text.Collator;
  33 import java.text.ParseException;
  34 import java.text.RuleBasedCollator;
  35 import java.util.*;
  36 import java.util.AbstractMap.SimpleEntry;
  37 import java.util.Map.Entry;
  38 import java.util.stream.Collectors;
  39 
  40 import javax.lang.model.SourceVersion;
  41 import javax.lang.model.element.AnnotationMirror;
  42 import javax.lang.model.element.AnnotationValue;
  43 import javax.lang.model.element.Element;
  44 import javax.lang.model.element.ElementKind;
  45 import javax.lang.model.element.ExecutableElement;
  46 import javax.lang.model.element.Modifier;
  47 import javax.lang.model.element.ModuleElement;
  48 import javax.lang.model.element.ModuleElement.RequiresDirective;
  49 import javax.lang.model.element.PackageElement;
  50 import javax.lang.model.element.RecordComponentElement;
  51 import javax.lang.model.element.TypeElement;
  52 import javax.lang.model.element.TypeParameterElement;
  53 import javax.lang.model.element.VariableElement;
  54 import javax.lang.model.type.ArrayType;
  55 import javax.lang.model.type.DeclaredType;
  56 import javax.lang.model.type.ErrorType;
  57 import javax.lang.model.type.ExecutableType;
  58 import javax.lang.model.type.NoType;
  59 import javax.lang.model.type.PrimitiveType;
  60 import javax.lang.model.type.TypeMirror;
  61 import javax.lang.model.type.TypeVariable;
  62 import javax.lang.model.type.WildcardType;
  63 import javax.lang.model.util.ElementFilter;
  64 import javax.lang.model.util.ElementKindVisitor14;
  65 import javax.lang.model.util.Elements;
  66 import javax.lang.model.util.SimpleElementVisitor14;
  67 import javax.lang.model.util.SimpleTypeVisitor9;
  68 import javax.lang.model.util.TypeKindVisitor9;
  69 import javax.lang.model.util.Types;
  70 import javax.tools.FileObject;
  71 import javax.tools.JavaFileManager;
  72 import javax.tools.JavaFileManager.Location;
  73 import javax.tools.StandardLocation;
  74 
  75 import com.sun.source.doctree.DocCommentTree;
  76 import com.sun.source.doctree.DocTree;
  77 import com.sun.source.doctree.DocTree.Kind;
  78 import com.sun.source.doctree.ParamTree;
  79 import com.sun.source.doctree.SerialFieldTree;
  80 import com.sun.source.tree.CompilationUnitTree;
  81 import com.sun.source.tree.LineMap;
  82 import com.sun.source.util.DocSourcePositions;
  83 import com.sun.source.util.DocTrees;
  84 import com.sun.source.util.TreePath;
  85 import com.sun.tools.javac.model.JavacTypes;
  86 import jdk.javadoc.internal.doclets.formats.html.SearchIndexItem;


 285             return loc;
 286 
 287         return defaultLocation();
 288     }
 289 
 290     private Location defaultLocation() {
 291         JavaFileManager fm = configuration.docEnv.getJavaFileManager();
 292         return fm.hasLocation(StandardLocation.SOURCE_PATH)
 293                 ? StandardLocation.SOURCE_PATH
 294                 : StandardLocation.CLASS_PATH;
 295     }
 296 
 297     public boolean isAnnotated(TypeMirror e) {
 298         return !e.getAnnotationMirrors().isEmpty();
 299     }
 300 
 301     public boolean isAnnotated(Element e) {
 302         return !e.getAnnotationMirrors().isEmpty();
 303     }
 304 
 305     @SuppressWarnings("preview")
 306     public boolean isAnnotationType(Element e) {
 307         return new SimpleElementVisitor14<Boolean, Void>() {
 308             @Override
 309             public Boolean visitExecutable(ExecutableElement e, Void p) {
 310                 return visit(e.getEnclosingElement());
 311             }
 312 
 313             @Override
 314             public Boolean visitUnknown(Element e, Void p) {
 315                 return false;
 316             }
 317 
 318             @Override
 319             protected Boolean defaultAction(Element e, Void p) {
 320                 return e.getKind() == ANNOTATION_TYPE;
 321             }
 322         }.visit(e);
 323     }
 324 
 325     /**
 326      * An Enum implementation is almost identical, thus this method returns if
 327      * this element represents a CLASS or an ENUM


 401     public String getPropertyLabel(String name) {
 402         return name.substring(0, name.lastIndexOf("Property"));
 403     }
 404 
 405     public boolean isOverviewElement(Element e) {
 406         return e.getKind() == ElementKind.OTHER;
 407     }
 408 
 409     public boolean isStatic(Element e) {
 410         return e.getModifiers().contains(Modifier.STATIC);
 411     }
 412 
 413     public boolean isSerializable(TypeElement e) {
 414         return typeUtils.isSubtype(e.asType(), getSerializableType());
 415     }
 416 
 417     public boolean isExternalizable(TypeElement e) {
 418         return typeUtils.isSubtype(e.asType(), getExternalizableType());
 419     }
 420 
 421     @SuppressWarnings("preview")
 422     public boolean isRecord(TypeElement e) {
 423         return e.getKind() == ElementKind.RECORD;
 424     }
 425 
 426     @SuppressWarnings("preview")
 427     public boolean isCanonicalRecordConstructor(ExecutableElement ee) {
 428         TypeElement te = (TypeElement) ee.getEnclosingElement();
 429         List<? extends RecordComponentElement> stateComps = te.getRecordComponents();
 430         List<? extends VariableElement> params = ee.getParameters();
 431         if (stateComps.size() != params.size()) {
 432             return false;
 433         }
 434 
 435         Iterator<? extends RecordComponentElement> stateIter = stateComps.iterator();
 436         Iterator<? extends VariableElement> paramIter = params.iterator();
 437         while (paramIter.hasNext() && stateIter.hasNext()) {
 438             VariableElement param = paramIter.next();
 439             RecordComponentElement comp = stateIter.next();
 440             if (!Objects.equals(param.getSimpleName(), comp.getSimpleName())
 441                     || !typeUtils.isSameType(param.asType(), comp.asType())) {
 442                 return false;
 443             }
 444         }
 445 
 446         return true;
 447     }
 448 
 449     public SortedSet<VariableElement> serializableFields(TypeElement aclass) {
 450         return configuration.workArounds.getSerializableFields(aclass);
 451     }
 452 
 453     public SortedSet<ExecutableElement> serializationMethods(TypeElement aclass) {
 454         return configuration.workArounds.getSerializationMethods(aclass);
 455     }
 456 
 457     public boolean definesSerializableFields(TypeElement aclass) {
 458         return configuration.workArounds.definesSerializableFields( aclass);
 459     }
 460 
 461     @SuppressWarnings("preview")
 462     public String modifiersToString(Element e, boolean trailingSpace) {
 463         SortedSet<Modifier> modifiers = new TreeSet<>(e.getModifiers());
 464         modifiers.remove(NATIVE);
 465         modifiers.remove(STRICTFP);
 466         modifiers.remove(SYNCHRONIZED);
 467 
 468         return new ElementKindVisitor14<String, SortedSet<Modifier>>() {
 469             final StringBuilder sb = new StringBuilder();
 470 
 471             void addVisibilityModifier(Set<Modifier> modifiers) {
 472                 if (modifiers.contains(PUBLIC)) {
 473                     append("public");
 474                 } else if (modifiers.contains(PROTECTED)) {
 475                     append("protected");
 476                 } else if (modifiers.contains(PRIVATE)) {
 477                     append("private");
 478                 }
 479             }
 480 
 481             void addStatic(Set<Modifier> modifiers) {
 482                 if (modifiers.contains(STATIC)) {
 483                     append("static");
 484                 }
 485             }
 486 
 487             void addModifiers(Set<Modifier> modifiers) {
 488                 modifiers.stream().map(Modifier::toString).forEach(this::append);
 489             }
 490 
 491             void append(String s) {
 492                 if (sb.length() > 0) {
 493                     sb.append(" ");
 494                 }
 495                 sb.append(s);
 496             }
 497 
 498             String finalString(String s) {
 499                 append(s);
 500                 if (trailingSpace) {
 501                     sb.append(" ");






 502                     }
 503                 return sb.toString();
 504             }
 505 
 506             @Override
 507             public String visitTypeAsInterface(TypeElement e, SortedSet<Modifier> mods) {
 508                 addVisibilityModifier(mods);
 509                 addStatic(mods);
 510                 return finalString("interface");
 511             }
 512 
 513             @Override
 514             public String visitTypeAsEnum(TypeElement e, SortedSet<Modifier> mods) {
 515                 addVisibilityModifier(mods);
 516                 addStatic(mods);
 517                 return finalString("enum");
 518             }
 519 
 520             @Override
 521             public String visitTypeAsAnnotationType(TypeElement e, SortedSet<Modifier> mods) {
 522                 addVisibilityModifier(mods);
 523                 addStatic(mods);
 524                 return finalString("@interface");
 525             }
 526 
 527             @Override
 528             public String visitTypeAsRecord(TypeElement e, SortedSet<Modifier> mods) {
 529                 mods.remove(FINAL); // suppress the implicit `final`
 530                 return visitTypeAsClass(e, mods);
 531             }
 532 
 533             @Override
 534             @SuppressWarnings("preview")
 535             public String visitTypeAsClass(TypeElement e, SortedSet<Modifier> mods) {
 536                 Set<Modifier> beforeSealed = EnumSet.noneOf(Modifier.class);
 537                 Set<Modifier> afterSealed = EnumSet.noneOf(Modifier.class);
 538                 Set<Modifier> set = beforeSealed;
 539                 for (Modifier m : Modifier.values()) {
 540                     if (mods.contains(m)) {
 541                         set.add(m);
 542                     }
 543                 }
 544                 addModifiers(beforeSealed);
 545                 addModifiers(afterSealed);
 546                 String keyword = e.getKind() == ElementKind.RECORD ? "record" : "class";
 547                 return finalString(keyword);
 548             }
 549 
 550             @Override
 551             protected String defaultAction(Element e, SortedSet<Modifier> mods) {
 552                 addModifiers(mods);
 553                 return sb.toString().trim();
 554             }
 555 
 556         }.visit(e, modifiers);
 557     }
 558 
 559     public boolean isFunctionalInterface(AnnotationMirror amirror) {
 560         return amirror.getAnnotationType().equals(getFunctionalInterface()) &&
 561                 configuration.docEnv.getSourceVersion()
 562                         .compareTo(SourceVersion.RELEASE_8) >= 0;
 563     }
 564 
 565     public boolean isNoType(TypeMirror t) {
 566         return t.getKind() == NONE;
 567     }
 568 
 569     public boolean isOrdinaryClass(TypeElement te) {
 570         if (isEnum(te) || isInterface(te) || isAnnotationType(te)) {
 571             return false;
 572         }
 573         if (isError(te) || isException(te)) {
 574             return false;
 575         }
 576         return true;


 623                 return true;
 624             default:
 625                 return false;
 626         }
 627     }
 628 
 629     public boolean isVariableElement(Element e) {
 630         ElementKind kind = e.getKind();
 631         switch(kind) {
 632               case ENUM_CONSTANT: case EXCEPTION_PARAMETER: case FIELD:
 633               case LOCAL_VARIABLE: case PARAMETER:
 634               case RESOURCE_VARIABLE:
 635                   return true;
 636               default:
 637                   return false;
 638         }
 639     }
 640 
 641     public boolean isTypeElement(Element e) {
 642         switch (e.getKind()) {
 643             case CLASS: case ENUM: case INTERFACE: case ANNOTATION_TYPE: case RECORD:
 644                 return true;
 645             default:
 646                 return false;
 647         }
 648     }
 649 
 650     /**
 651      * Get the signature. It is the parameter list, type is qualified.
 652      * For instance, for a method {@code mymethod(String x, int y)},
 653      * it will return {@code(java.lang.String,int)}.
 654      *
 655      * @param e
 656      * @return String
 657      */
 658     public String signature(ExecutableElement e) {
 659         return makeSignature(e, true);
 660     }
 661 
 662     /**
 663      * Get flat signature.  All types are not qualified.


1393             switch (ch) {
1394                 case '\n':
1395                     sb.append(text, pos, i);
1396                     sb.append(NL);
1397                     pos = i + 1;
1398                     break;
1399                 case '\r':
1400                     sb.append(text, pos, i);
1401                     sb.append(NL);
1402                     if (i + 1 < textLength && text.charAt(i + 1) == '\n')
1403                         i++;
1404                     pos = i + 1;
1405                     break;
1406             }
1407         }
1408         sb.append(text, pos, textLength);
1409         return sb;
1410     }
1411 
1412     /**





















1413      * Returns a locale independent upper cased String. That is, it
1414      * always uses US locale, this is a clone of the one in StringUtils.
1415      * @param s to convert
1416      * @return converted String
1417      */
1418     public static String toUpperCase(String s) {
1419         return s.toUpperCase(Locale.US);
1420     }
1421 
1422     /**
1423      * Returns a locale independent lower cased String. That is, it
1424      * always uses US locale, this is a clone of the one in StringUtils.
1425      * @param s to convert
1426      * @return converted String
1427      */
1428     public static String toLowerCase(String s) {
1429         return s.toLowerCase(Locale.US);
1430     }
1431 
1432     /**


1769      */
1770     public Comparator<Element> makeOverrideUseComparator() {
1771         if (overrideUseComparator == null) {
1772             overrideUseComparator = new Utils.ElementComparator() {
1773                 @Override
1774                 public int compare(Element o1, Element o2) {
1775                     int result = compareStrings(getSimpleName(o1), getSimpleName(o2));
1776                     if (result != 0) {
1777                         return result;
1778                     }
1779                     if (!isTypeElement(o1) && !isTypeElement(o2) && !isPackage(o1) && !isPackage(o2)) {
1780                         TypeElement t1 = getEnclosingTypeElement(o1);
1781                         TypeElement t2 = getEnclosingTypeElement(o2);
1782                         result = compareStrings(getSimpleName(t1), getSimpleName(t2));
1783                         if (result != 0)
1784                             return result;
1785                     }
1786                     result = compareStrings(getFullyQualifiedName(o1), getFullyQualifiedName(o2));
1787                     if (result != 0)
1788                         return result;
1789                     return compareElementKinds(o1, o2);
1790                 }
1791             };
1792         }
1793         return overrideUseComparator;
1794     }
1795 
1796     private Comparator<Element> indexUseComparator = null;
1797     /**
1798      *  Returns a Comparator for index file presentations, and are sorted as follows.
1799      *  If comparing modules and/or packages then simply compare the qualified names,
1800      *  if comparing a module or a package with a type/member then compare the
1801      *  FullyQualifiedName of the module or a package with the SimpleName of the entity,
1802      *  otherwise:
1803      *  1. compare the ElementKind ex: Module, Package, Interface etc.
1804      *  2a. if equal and if the type is of ExecutableElement(Constructor, Methods),
1805      *      a case insensitive comparison of parameter the type signatures
1806      *  2b. if equal, case sensitive comparison of the type signatures
1807      *  3. finally, if equal, compare the FQNs of the entities
1808      * @return a comparator for index file use
1809      */


1818                  * @return a negative integer, zero, or a positive integer as the first
1819                  * argument is less than, equal to, or greater than the second.
1820                  */
1821                 @Override
1822                 public int compare(Element e1, Element e2) {
1823                     int result;
1824                     // first, compare names as appropriate
1825                     if ((isModule(e1) || isPackage(e1)) && (isModule(e2) || isPackage(e2))) {
1826                         result = compareFullyQualifiedNames(e1, e2);
1827                     } else if (isModule(e1) || isPackage(e1)) {
1828                         result = compareStrings(getFullyQualifiedName(e1), getSimpleName(e2));
1829                     } else if (isModule(e2) || isPackage(e2)) {
1830                         result = compareStrings(getSimpleName(e1), getFullyQualifiedName(e2));
1831                     } else {
1832                         result = compareNames(e1, e2);
1833                     }
1834                     if (result != 0) {
1835                         return result;
1836                     }
1837                     // if names are the same, compare element kinds
1838                     result = compareElementKinds(e1, e2);
1839                     if (result != 0) {
1840                         return result;
1841                     }
1842                     // if element kinds are the same, and are methods,
1843                     // compare the method parameters
1844                     if (hasParameters(e1)) {
1845                         List<? extends VariableElement> parameters1 = ((ExecutableElement)e1).getParameters();
1846                         List<? extends VariableElement> parameters2 = ((ExecutableElement)e2).getParameters();
1847                         result = compareParameters(false, parameters1, parameters2);
1848                         if (result != 0) {
1849                             return result;
1850                         }
1851                         result = compareParameters(true, parameters1, parameters2);
1852                         if (result != 0) {
1853                             return result;
1854                         }
1855                     }
1856                     // else fall back on fully qualified names
1857                     return compareFullyQualifiedNames(e1, e2);
1858                 }


1926 
1927             @Override
1928             protected String defaultAction(TypeMirror t, Void p) {
1929                 return t.toString();
1930             }
1931 
1932         }.visit(t);
1933     }
1934 
1935     /**
1936      * A generic utility which returns the fully qualified names of an entity,
1937      * if the entity is not qualifiable then its enclosing entity, it is upto
1938      * the caller to add the elements name as required.
1939      * @param e the element to get FQN for.
1940      * @return the name
1941      */
1942     public String getFullyQualifiedName(Element e) {
1943         return getFullyQualifiedName(e, true);
1944     }
1945 
1946     @SuppressWarnings("preview")
1947     public String getFullyQualifiedName(Element e, final boolean outer) {
1948         return new SimpleElementVisitor14<String, Void>() {
1949             @Override
1950             public String visitModule(ModuleElement e, Void p) {
1951                 return e.getQualifiedName().toString();
1952             }
1953 
1954             @Override
1955             public String visitPackage(PackageElement e, Void p) {
1956                 return e.getQualifiedName().toString();
1957             }
1958 
1959             @Override
1960             public String visitType(TypeElement e, Void p) {
1961                 return e.getQualifiedName().toString();
1962             }
1963 
1964             @Override
1965             protected String defaultAction(Element e, Void p) {
1966                 return outer ? visit(e.getEnclosingElement()) : e.getSimpleName().toString();
1967             }
1968         }.visit(e);


1995                         return result;
1996                     }
1997                     result = compareFullyQualifiedNames(e1, e2);
1998                     if (result != 0) {
1999                         return result;
2000                     }
2001                     if (hasParameters(e1) && hasParameters(e2)) {
2002                         @SuppressWarnings("unchecked")
2003                         List<VariableElement> parameters1 = (List<VariableElement>)((ExecutableElement)e1).getParameters();
2004                         @SuppressWarnings("unchecked")
2005                         List<VariableElement> parameters2 = (List<VariableElement>)((ExecutableElement)e2).getParameters();
2006                         result = compareParameters(false, parameters1, parameters2);
2007                         if (result != 0) {
2008                             return result;
2009                         }
2010                         result = compareParameters(true, parameters1, parameters2);
2011                     }
2012                     if (result != 0) {
2013                         return result;
2014                     }
2015                     return compareElementKinds(e1, e2);
2016                 }
2017             };
2018         }
2019         return classUseComparator;
2020     }
2021 
2022     /**
2023      * A general purpose comparator to sort Element entities, basically provides the building blocks
2024      * for creating specific comparators for an use-case.
2025      */
2026     private abstract class ElementComparator implements Comparator<Element> {
2027         public ElementComparator() { }
2028 
2029         /**
2030          * compares two parameter arrays by first comparing the length of the arrays, and
2031          * then each Type of the parameter in the array.
2032          * @param params1 the first parameter array.
2033          * @param params2 the first parameter array.
2034          * @return a negative integer, zero, or a positive integer as the first
2035          *         argument is less than, equal to, or greater than the second.
2036          */















2037         protected int compareParameters(boolean caseSensitive, List<? extends VariableElement> params1,
2038                                                                List<? extends VariableElement> params2) {
2039 
2040             return compareStrings(caseSensitive, getParametersAsString(params1),
2041                                                  getParametersAsString(params2));
2042         }
2043 
2044         String getParametersAsString(List<? extends VariableElement> params) {
2045             StringBuilder sb = new StringBuilder();
2046             for (VariableElement param : params) {
2047                 TypeMirror t = param.asType();
2048                 // prefix P for primitive and R for reference types, thus items will
2049                 // be ordered lexically and correctly.
2050                 sb.append(getTypeCode(t)).append("-").append(t).append("-");
2051             }
2052             return sb.toString();
2053         }
2054 
2055         private String getTypeCode(TypeMirror t) {
2056             return new SimpleTypeVisitor9<String, Void>() {


2079          * @return a negative integer, zero, or a positive integer as the first
2080          *         argument is less than, equal to, or greater than the second.
2081          */
2082         protected int compareNames(Element e1, Element e2) {
2083             return compareStrings(getSimpleName(e1), getSimpleName(e2));
2084         }
2085 
2086         /**
2087          * Compares the fully qualified names of the entities
2088          * @param e1 the first Element.
2089          * @param e2 the first Element.
2090          * @return a negative integer, zero, or a positive integer as the first
2091          *         argument is less than, equal to, or greater than the second.
2092          */
2093         protected int compareFullyQualifiedNames(Element e1, Element e2) {
2094             // add simplename to be compatible
2095             String thisElement = getFullyQualifiedName(e1);
2096             String thatElement = getFullyQualifiedName(e2);
2097             return compareStrings(thisElement, thatElement);
2098         }
2099 
2100         protected int compareElementKinds(Element e1, Element e2) {
2101             return Integer.compare(getKindIndex(e1), getKindIndex(e2));
2102         }
2103 
2104         private int getKindIndex(Element e) {
2105             switch (e.getKind()) {
2106                 case MODULE:            return 0;
2107                 case PACKAGE:           return 1;
2108                 case CLASS:             return 2;
2109                 case ENUM:              return 3;
2110                 case ENUM_CONSTANT:     return 4;
2111                 case RECORD:            return 5;
2112                 case INTERFACE:         return 6;
2113                 case ANNOTATION_TYPE:   return 7;
2114                 case FIELD:             return 8;
2115                 case CONSTRUCTOR:       return 9;
2116                 case METHOD:            return 10;
2117                 default: throw new IllegalArgumentException(e.getKind().toString());
2118             }
2119         }
2120 
2121         @SuppressWarnings("preview")
2122         boolean hasParameters(Element e) {
2123             return new SimpleElementVisitor14<Boolean, Void>() {
2124                 @Override
2125                 public Boolean visitExecutable(ExecutableElement e, Void p) {
2126                     return true;
2127                 }
2128 
2129                 @Override
2130                 protected Boolean defaultAction(Element e, Void p) {
2131                     return false;
2132                 }
2133 
2134             }.visit(e);
2135         }
2136 
2137         /**
2138          * The fully qualified names of the entities, used solely by the comparator.
2139          *
2140          * @return a negative integer, zero, or a positive integer as the first argument is less
2141          * than, equal to, or greater than the second.
2142          */
2143         @SuppressWarnings("preview")
2144         private String getFullyQualifiedName(Element e) {
2145             return new SimpleElementVisitor14<String, Void>() {
2146                 @Override
2147                 public String visitModule(ModuleElement e, Void p) {
2148                     return e.getQualifiedName().toString();
2149                 }
2150 
2151                 @Override
2152                 public String visitPackage(PackageElement e, Void p) {
2153                     return e.getQualifiedName().toString();
2154                 }
2155 
2156                 @Override
2157                 public String visitExecutable(ExecutableElement e, Void p) {
2158                     // For backward compatibility
2159                     return getFullyQualifiedName(e.getEnclosingElement())
2160                             + "." + e.getSimpleName().toString();
2161                 }
2162 
2163                 @Override
2164                 public String visitType(TypeElement e, Void p) {
2165                     return e.getQualifiedName().toString();


2204     public Comparator<SearchIndexItem> makeGenericSearchIndexComparator() {
2205         if (genericSearchIndexComparator == null) {
2206             genericSearchIndexComparator = (SearchIndexItem sii1, SearchIndexItem sii2) -> {
2207                 int result = compareStrings(sii1.getLabel(), sii2.getLabel());
2208                 if (result == 0) {
2209                     // TreeSet needs this to be consistent with equal so we do
2210                     // a plain comparison of string representations as fallback.
2211                     result = sii1.toString().compareTo(sii2.toString());
2212                 }
2213                 return result;
2214             };
2215         }
2216         return genericSearchIndexComparator;
2217     }
2218 
2219     public Iterable<TypeElement> getEnclosedTypeElements(PackageElement pkg) {
2220         List<TypeElement> out = getInterfaces(pkg);
2221         out.addAll(getClasses(pkg));
2222         out.addAll(getEnums(pkg));
2223         out.addAll(getAnnotationTypes(pkg));
2224         out.addAll(getRecords(pkg));
2225         return out;
2226     }
2227 
2228     // Element related methods
2229     public List<Element> getAnnotationMembers(TypeElement aClass) {
2230         List<Element> members = getAnnotationFields(aClass);
2231         members.addAll(getAnnotationMethods(aClass));
2232         return members;
2233     }
2234 
2235     public List<Element> getAnnotationFields(TypeElement aClass) {
2236         return getItems0(aClass, true, FIELD);
2237     }
2238 
2239     List<Element> getAnnotationFieldsUnfiltered(TypeElement aClass) {
2240         return getItems0(aClass, true, FIELD);
2241     }
2242 
2243     public List<Element> getAnnotationMethods(TypeElement aClass) {
2244         return getItems0(aClass, true, METHOD);
2245     }
2246 
2247     public List<TypeElement> getAnnotationTypes(Element e) {
2248         return convertToTypeElement(getItems(e, true, ANNOTATION_TYPE));
2249     }
2250 
2251     public List<TypeElement> getAnnotationTypesUnfiltered(Element e) {
2252         return convertToTypeElement(getItems(e, false, ANNOTATION_TYPE));
2253     }
2254 
2255     @SuppressWarnings("preview")
2256     public List<TypeElement> getRecords(Element e) {
2257         return convertToTypeElement(getItems(e, true, RECORD));
2258     }
2259 
2260     @SuppressWarnings("preview")
2261     public List<TypeElement> getRecordsUnfiltered(Element e) {
2262         return convertToTypeElement(getItems(e, false, RECORD));
2263     }
2264 
2265     public List<VariableElement> getFields(Element e) {
2266         return convertToVariableElement(getItems(e, true, FIELD));
2267     }
2268 
2269     public List<VariableElement> getFieldsUnfiltered(Element e) {
2270         return convertToVariableElement(getItems(e, false, FIELD));
2271     }
2272 
2273     public List<TypeElement> getClasses(Element e) {
2274        return convertToTypeElement(getItems(e, true, CLASS));
2275     }
2276 
2277     public List<TypeElement> getClassesUnfiltered(Element e) {
2278        return convertToTypeElement(getItems(e, false, CLASS));
2279     }
2280 
2281     public List<ExecutableElement> getConstructors(Element e) {
2282         return convertToExecutableElement(getItems(e, true, CONSTRUCTOR));
2283     }
2284 


2399     public List<TypeElement> getInterfacesUnfiltered(Element e)  {
2400         return convertToTypeElement(getItems(e, false, INTERFACE));
2401     }
2402 
2403     public List<Element> getEnumConstants(Element e) {
2404         return getItems(e, true, ENUM_CONSTANT);
2405     }
2406 
2407     public List<TypeElement> getEnums(Element e) {
2408         return convertToTypeElement(getItems(e, true, ENUM));
2409     }
2410 
2411     public List<TypeElement> getEnumsUnfiltered(Element e) {
2412         return convertToTypeElement(getItems(e, false, ENUM));
2413     }
2414 
2415     public SortedSet<TypeElement> getAllClassesUnfiltered(Element e) {
2416         List<TypeElement> clist = getClassesUnfiltered(e);
2417         clist.addAll(getInterfacesUnfiltered(e));
2418         clist.addAll(getAnnotationTypesUnfiltered(e));
2419         clist.addAll(getRecordsUnfiltered(e));
2420         SortedSet<TypeElement> oset = new TreeSet<>(makeGeneralPurposeComparator());
2421         oset.addAll(clist);
2422         return oset;
2423     }
2424 
2425     private final HashMap<Element, SortedSet<TypeElement>> cachedClasses = new HashMap<>();
2426     /**
2427      * Returns a list containing classes and interfaces,
2428      * including annotation types.
2429      * @param e Element
2430      * @return List
2431      */
2432     public SortedSet<TypeElement> getAllClasses(Element e) {
2433         SortedSet<TypeElement> oset = cachedClasses.get(e);
2434         if (oset != null)
2435             return oset;
2436         List<TypeElement> clist = getClasses(e);
2437         clist.addAll(getInterfaces(e));
2438         clist.addAll(getAnnotationTypes(e));
2439         clist.addAll(getEnums(e));
2440         clist.addAll(getRecords(e));
2441         oset = new TreeSet<>(makeGeneralPurposeComparator());
2442         oset.addAll(clist);
2443         cachedClasses.put(e, oset);
2444         return oset;
2445     }
2446 
2447     /*
2448      * Get all the elements unfiltered and filter them finally based
2449      * on its visibility, this works differently from the other getters.
2450      */
2451     private List<TypeElement> getInnerClasses(Element e, boolean filter) {
2452         List<TypeElement> olist = new ArrayList<>();
2453         for (TypeElement te : getClassesUnfiltered(e)) {
2454             if (!filter || configuration.docEnv.isSelected(te)) {
2455                 olist.add(te);
2456             }
2457         }
2458         for (TypeElement te : getInterfacesUnfiltered(e)) {
2459             if (!filter || configuration.docEnv.isSelected(te)) {
2460                 olist.add(te);


2489     public List<TypeElement> getOrdinaryClasses(Element e) {
2490         return getClasses(e).stream()
2491                 .filter(te -> (!isException(te) && !isError(te)))
2492                 .collect(Collectors.toList());
2493     }
2494 
2495     public List<TypeElement> getErrors(Element e) {
2496         return getClasses(e)
2497                 .stream()
2498                 .filter(this::isError)
2499                 .collect(Collectors.toList());
2500     }
2501 
2502     public List<TypeElement> getExceptions(Element e) {
2503         return getClasses(e)
2504                 .stream()
2505                 .filter(this::isException)
2506                 .collect(Collectors.toList());
2507     }
2508 
2509     @SuppressWarnings("preview")
2510     List<Element> getItems(Element e, boolean filter, ElementKind select) {
2511         List<Element> elements = new ArrayList<>();
2512         return new SimpleElementVisitor14<List<Element>, Void>() {
2513 
2514             @Override
2515             public List<Element> visitPackage(PackageElement e, Void p) {
2516                 recursiveGetItems(elements, e, filter, select);
2517                 return elements;
2518             }
2519 
2520             @Override
2521             protected List<Element> defaultAction(Element e0, Void p) {
2522                 return getItems0(e0, filter, select);
2523             }
2524 
2525         }.visit(e);
2526     }
2527 
2528     EnumSet<ElementKind> nestedKinds = EnumSet.of(ANNOTATION_TYPE, CLASS, ENUM, INTERFACE);
2529     void recursiveGetItems(Collection<Element> list, Element e, boolean filter, ElementKind... select) {
2530         list.addAll(getItems0(e, filter, select));
2531         List<Element> classes = getItems0(e, filter, nestedKinds);
2532         for (Element c : classes) {


2537         }
2538     }
2539 
2540     private List<Element> getItems0(Element te, boolean filter, ElementKind... select) {
2541         EnumSet<ElementKind> kinds = EnumSet.copyOf(Arrays.asList(select));
2542         return getItems0(te, filter, kinds);
2543     }
2544 
2545     private List<Element> getItems0(Element te, boolean filter, Set<ElementKind> kinds) {
2546         List<Element> elements = new ArrayList<>();
2547         for (Element e : te.getEnclosedElements()) {
2548             if (kinds.contains(e.getKind())) {
2549                 if (!filter || shouldDocument(e)) {
2550                     elements.add(e);
2551                 }
2552             }
2553         }
2554         return elements;
2555     }
2556 
2557     @SuppressWarnings("preview")
2558     private SimpleElementVisitor14<Boolean, Void> shouldDocumentVisitor = null;
2559 
2560     @SuppressWarnings("preview")
2561     public boolean shouldDocument(Element e) {
2562         if (shouldDocumentVisitor == null) {
2563             shouldDocumentVisitor = new SimpleElementVisitor14<Boolean, Void>() {
2564                 private boolean hasSource(TypeElement e) {
2565                     return configuration.docEnv.getFileKind(e) ==
2566                             javax.tools.JavaFileObject.Kind.SOURCE;
2567                 }
2568 
2569                 // handle types
2570                 @Override
2571                 public Boolean visitType(TypeElement e, Void p) {
2572                     // treat inner classes etc as members
2573                     if (e.getNestingKind().isNested()) {
2574                         return defaultAction(e, p);
2575                     }
2576                     return configuration.docEnv.isSelected(e) && hasSource(e);
2577                 }
2578 
2579                 // handle everything else
2580                 @Override
2581                 protected Boolean defaultAction(Element e, Void p) {
2582                     return configuration.docEnv.isSelected(e);
2583                 }


2593 
2594     /*
2595      * nameCache is maintained for improving the comparator
2596      * performance, noting that the Collator used by the comparators
2597      * use Strings, as of this writing.
2598      * TODO: when those APIs handle charSequences, the use of
2599      * this nameCache must be re-investigated and removed.
2600      */
2601     private final Map<Element, String> nameCache = new LinkedHashMap<>();
2602 
2603     /**
2604      * Returns the name of the element after the last dot of the package name.
2605      * This emulates the behavior of the old doclet.
2606      * @param e an element whose name is required
2607      * @return the name
2608      */
2609     public String getSimpleName(Element e) {
2610         return nameCache.computeIfAbsent(e, this::getSimpleName0);
2611     }
2612 
2613     @SuppressWarnings("preview")
2614     private SimpleElementVisitor14<String, Void> snvisitor = null;
2615 
2616     @SuppressWarnings("preview")
2617     private String getSimpleName0(Element e) {
2618         if (snvisitor == null) {
2619             snvisitor = new SimpleElementVisitor14<String, Void>() {
2620                 @Override
2621                 public String visitModule(ModuleElement e, Void p) {
2622                     return e.getQualifiedName().toString();  // temp fix for 8182736
2623                 }
2624 
2625                 @Override
2626                 public String visitType(TypeElement e, Void p) {
2627                     StringBuilder sb = new StringBuilder(e.getSimpleName());
2628                     Element enclosed = e.getEnclosingElement();
2629                     while (enclosed != null
2630                             && (enclosed.getKind().isClass() || enclosed.getKind().isInterface())) {
2631                         sb.insert(0, enclosed.getSimpleName() + ".");
2632                         enclosed = enclosed.getEnclosingElement();
2633                     }
2634                     return sb.toString();
2635                 }
2636 
2637                 @Override
2638                 public String visitExecutable(ExecutableElement e, Void p) {
2639                     if (e.getKind() == CONSTRUCTOR || e.getKind() == STATIC_INIT) {


2780             final String chars = "0123456789abcdef";
2781             buf.append("\\u");
2782             buf.append(chars.charAt(15 & (c>>12)));
2783             buf.append(chars.charAt(15 & (c>>8)));
2784             buf.append(chars.charAt(15 & (c>>4)));
2785             buf.append(chars.charAt(15 & (c>>0)));
2786         }
2787         private boolean isPrintableAscii(char c) {
2788             return c >= ' ' && c <= '~';
2789         }
2790     }
2791 
2792     public boolean isEnclosingPackageIncluded(TypeElement te) {
2793         return isIncluded(containingPackage(te));
2794     }
2795 
2796     public boolean isIncluded(Element e) {
2797         return configuration.docEnv.isIncluded(e);
2798     }
2799 
2800     @SuppressWarnings("preview")
2801     private SimpleElementVisitor14<Boolean, Void> specifiedVisitor = null;
2802     @SuppressWarnings("preview")
2803     public boolean isSpecified(Element e) {
2804         if (specifiedVisitor == null) {
2805             specifiedVisitor = new SimpleElementVisitor14<Boolean, Void>() {
2806                 @Override
2807                 public Boolean visitModule(ModuleElement e, Void p) {
2808                     return configuration.getSpecifiedModuleElements().contains(e);
2809                 }
2810 
2811                 @Override
2812                 public Boolean visitPackage(PackageElement e, Void p) {
2813                     return configuration.getSpecifiedPackageElements().contains(e);
2814                 }
2815 
2816                 @Override
2817                 public Boolean visitType(TypeElement e, Void p) {
2818                     return configuration.getSpecifiedTypeElements().contains(e);
2819                 }
2820 
2821                 @Override
2822                 protected Boolean defaultAction(Element e, Void p) {
2823                     return false;
2824                 }
2825             };


3233     public List<? extends DocTree> getProvidesTrees(Element element) {
3234         return getBlockTags(element, PROVIDES);
3235     }
3236 
3237     public List<? extends DocTree> getSeeTrees(Element element) {
3238         return getBlockTags(element, SEE);
3239     }
3240 
3241     public List<? extends DocTree> getSerialTrees(Element element) {
3242         return getBlockTags(element, SERIAL);
3243     }
3244 
3245     public List<? extends DocTree> getSerialFieldTrees(VariableElement field) {
3246         return getBlockTags(field, DocTree.Kind.SERIAL_FIELD);
3247     }
3248 
3249     public List<? extends DocTree> getThrowsTrees(Element element) {
3250         return getBlockTags(element, DocTree.Kind.EXCEPTION, DocTree.Kind.THROWS);
3251     }
3252 
3253     public List<? extends ParamTree> getTypeParamTrees(Element element) {
3254         return getParamTrees(element, true);
3255     }
3256 
3257     public List<? extends ParamTree> getParamTrees(Element element) {
3258         return getParamTrees(element, false);
3259     }
3260 
3261     private  List<? extends ParamTree> getParamTrees(Element element, boolean isTypeParameters) {
3262         List<ParamTree> out = new ArrayList<>();
3263         for (DocTree dt : getBlockTags(element, PARAM)) {
3264             ParamTree pt = (ParamTree) dt;
3265             if (pt.isTypeParameter() == isTypeParameters) {
3266                 out.add(pt);
3267             }
3268         }
3269         return out;
3270     }
3271 
3272     public  List<? extends DocTree> getReturnTrees(Element element) {
3273         List<DocTree> out = new ArrayList<>();
3274         for (DocTree dt : getBlockTags(element, RETURN)) {
3275             out.add(dt);
3276         }
3277         return out;
3278     }
3279 
3280     public List<? extends DocTree> getUsesTrees(Element element) {
3281         return getBlockTags(element, USES);
3282     }
3283 
3284     public List<? extends DocTree> getFirstSentenceTrees(Element element) {
3285         DocCommentTree dcTree = getDocCommentTree(element);
3286         if (dcTree == null) {


< prev index next >