< prev index next >

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

Print this page




  31 import javax.lang.model.element.VariableElement;
  32 import javax.lang.model.type.TypeKind;
  33 import javax.lang.model.type.TypeMirror;
  34 import javax.lang.model.util.Elements;
  35 import javax.lang.model.util.SimpleElementVisitor14;
  36 import java.lang.ref.SoftReference;
  37 import java.util.ArrayList;
  38 import java.util.Collections;
  39 import java.util.EnumMap;
  40 import java.util.EnumSet;
  41 import java.util.HashMap;
  42 import java.util.LinkedHashMap;
  43 import java.util.LinkedHashSet;
  44 import java.util.List;
  45 import java.util.Map;
  46 import java.util.Set;
  47 import java.util.function.Predicate;
  48 import java.util.stream.Collectors;
  49 
  50 import jdk.javadoc.internal.doclets.toolkit.BaseConfiguration;

  51 import jdk.javadoc.internal.doclets.toolkit.PropertyUtils;
  52 
  53 /**
  54  * This class computes the main data structure for the doclet's
  55  * operations. Essentially, the implementation encapsulating the
  56  * javax.lang.models view of what can be documented about a
  57  * type element's members.
  58  * <p>
  59  * The general operations are as follows:
  60  * <p>
  61  * Members: these are the members from jx.l.m's view but
  62  * are structured along the kinds of this class.
  63  * <p>
  64  * Extra Members: these are members enclosed in an undocumented
  65  * package-private type element, and may not be linkable (or documented),
  66  * however, the members of such a type element may be documented, as if
  67  * declared in the sub type, only if the enclosing type is not being
  68  * documented by a filter such as -public, -protected, etc.
  69  * <p>
  70  * Visible Members: these are the members that are "visible"


  89 
  90     public enum Kind {
  91         INNER_CLASSES,
  92         ENUM_CONSTANTS,
  93         FIELDS,
  94         CONSTRUCTORS,
  95         METHODS,
  96         ANNOTATION_TYPE_FIELDS,
  97         ANNOTATION_TYPE_MEMBER_OPTIONAL,
  98         ANNOTATION_TYPE_MEMBER_REQUIRED,
  99         PROPERTIES;
 100 
 101         public static final EnumSet<Kind> summarySet = EnumSet.range(INNER_CLASSES, METHODS);
 102         public static final EnumSet<Kind> detailSet = EnumSet.range(ENUM_CONSTANTS, METHODS);
 103     }
 104 
 105     final TypeElement te;
 106     final TypeElement parent;
 107 
 108     final BaseConfiguration config;

 109     final Utils utils;
 110     final VisibleMemberCache mcache;
 111 
 112     private List<VisibleMemberTable> allSuperclasses;
 113     private List<VisibleMemberTable> allSuperinterfaces;
 114     private List<VisibleMemberTable> parents;
 115 
 116 
 117     private Map<Kind, List<Element>> extraMembers = new EnumMap<>(Kind.class);
 118     private Map<Kind, List<Element>> visibleMembers = null;
 119     private Map<ExecutableElement, PropertyMembers> propertyMap = new HashMap<>();
 120 
 121     // Keeps track of method overrides
 122     Map<ExecutableElement, OverridingMethodInfo> overriddenMethodTable
 123             = new LinkedHashMap<>();
 124 
 125     protected VisibleMemberTable(TypeElement typeElement, BaseConfiguration configuration,
 126                                  VisibleMemberCache mcache) {
 127         config = configuration;
 128         utils = configuration.utils;

 129         te = typeElement;
 130         parent = utils.getSuperClass(te);
 131         this.mcache = mcache;
 132         allSuperclasses = new ArrayList<>();
 133         allSuperinterfaces = new ArrayList<>();
 134         parents = new ArrayList<>();
 135     }
 136 
 137     private synchronized void ensureInitialized() {
 138         if (visibleMembers != null)
 139             return;
 140 
 141         visibleMembers = new EnumMap<>(Kind.class);
 142         for (Kind kind : Kind.values()) {
 143             visibleMembers.put(kind, new ArrayList<>());
 144         }
 145         computeParents();
 146         computeVisibleMembers();
 147     }
 148 


 641      * contains the members in the declaration order, additionally a
 642      * HashMap is maintained for performance optimization to lookup
 643      * members. As a future enhancement is perhaps to consolidate the ordering
 644      * into a Map, capturing the insertion order, thereby eliminating an
 645      * ordered list.
 646      */
 647     class LocalMemberTable {
 648 
 649         // Maintains declaration order
 650         private final Map<Kind, List<Element>> orderedMembers;
 651 
 652         // Performance optimization
 653         private final Map<Kind, Map<String, List<Element>>> memberMap;
 654 
 655         LocalMemberTable() {
 656             orderedMembers = new EnumMap<>(Kind.class);
 657             memberMap = new EnumMap<>(Kind.class);
 658 
 659             List<? extends Element> elements = te.getEnclosedElements();
 660             for (Element e : elements) {
 661                 if (config.nodeprecated && utils.isDeprecated(e)) {
 662                     continue;
 663                 }
 664                 switch (e.getKind()) {
 665                     case CLASS:
 666                     case INTERFACE:
 667                     case ENUM:
 668                     case ANNOTATION_TYPE:
 669                     case RECORD:
 670                         addMember(e, Kind.INNER_CLASSES);
 671                         break;
 672                     case FIELD:
 673                         addMember(e, Kind.FIELDS);
 674                         addMember(e, Kind.ANNOTATION_TYPE_FIELDS);
 675                         break;
 676                     case METHOD:
 677                         ExecutableElement ee = (ExecutableElement)e;
 678                         if (utils.isAnnotationType(te)) {
 679                             addMember(e, ee.getDefaultValue() == null
 680                                     ? Kind.ANNOTATION_TYPE_MEMBER_REQUIRED
 681                                     : Kind.ANNOTATION_TYPE_MEMBER_OPTIONAL);


 783      * Property field, one may or may not exist and could be private, and
 784      * should match the property-method.
 785      *
 786      * A property-setter is a method starting with "set", and the
 787      * first character of the upper-cased starting character of the property name, the
 788      * method must take 1 argument and must return a <code>void</code>.
 789      *
 790      * Using the above example {@code void setAcme(Something s)} can be
 791      * considered as a property-setter of the property "acme".
 792      *
 793      * A property-getter is a method  starting with "get" and the first character
 794      * upper-cased property-name, having no parameters. A method that does not take any
 795      * parameters and starting with "is" and an upper-cased property-name,
 796      * returning a primitive type boolean or BooleanProperty can also be
 797      * considered as a getter, however there must be only one getter for every property.
 798      *
 799      * For example {@code Object getAcme()} is a property-getter, and
 800      * {@code boolean isFoo()}
 801      */
 802     private void computeVisibleProperties(LocalMemberTable lmt) {
 803         if (!config.javafx)
 804             return;
 805 
 806         PropertyUtils pUtils = config.propertyUtils;
 807         List<ExecutableElement> list = visibleMembers.getOrDefault(Kind.METHODS, Collections.emptyList())
 808                 .stream()
 809                 .map(m -> (ExecutableElement)m)
 810                 .filter(pUtils::isPropertyMethod)
 811                 .collect(Collectors.toList());
 812 
 813         visibleMembers.put(Kind.PROPERTIES, Collections.unmodifiableList(list));
 814 
 815         List<ExecutableElement> propertyMethods = list.stream()
 816                 .filter(e -> utils.getEnclosingTypeElement(e) == te)
 817                 .collect(Collectors.toList());
 818 
 819         // Compute additional properties related sundries.
 820         for (ExecutableElement propertyMethod : propertyMethods) {
 821             String baseName = pUtils.getBaseName(propertyMethod);
 822             List<Element> flist = lmt.getMembers(baseName, Kind.FIELDS);
 823             Element field = flist.isEmpty() ? null : flist.get(0);




  31 import javax.lang.model.element.VariableElement;
  32 import javax.lang.model.type.TypeKind;
  33 import javax.lang.model.type.TypeMirror;
  34 import javax.lang.model.util.Elements;
  35 import javax.lang.model.util.SimpleElementVisitor14;
  36 import java.lang.ref.SoftReference;
  37 import java.util.ArrayList;
  38 import java.util.Collections;
  39 import java.util.EnumMap;
  40 import java.util.EnumSet;
  41 import java.util.HashMap;
  42 import java.util.LinkedHashMap;
  43 import java.util.LinkedHashSet;
  44 import java.util.List;
  45 import java.util.Map;
  46 import java.util.Set;
  47 import java.util.function.Predicate;
  48 import java.util.stream.Collectors;
  49 
  50 import jdk.javadoc.internal.doclets.toolkit.BaseConfiguration;
  51 import jdk.javadoc.internal.doclets.toolkit.BaseOptions;
  52 import jdk.javadoc.internal.doclets.toolkit.PropertyUtils;
  53 
  54 /**
  55  * This class computes the main data structure for the doclet's
  56  * operations. Essentially, the implementation encapsulating the
  57  * javax.lang.models view of what can be documented about a
  58  * type element's members.
  59  * <p>
  60  * The general operations are as follows:
  61  * <p>
  62  * Members: these are the members from jx.l.m's view but
  63  * are structured along the kinds of this class.
  64  * <p>
  65  * Extra Members: these are members enclosed in an undocumented
  66  * package-private type element, and may not be linkable (or documented),
  67  * however, the members of such a type element may be documented, as if
  68  * declared in the sub type, only if the enclosing type is not being
  69  * documented by a filter such as -public, -protected, etc.
  70  * <p>
  71  * Visible Members: these are the members that are "visible"


  90 
  91     public enum Kind {
  92         INNER_CLASSES,
  93         ENUM_CONSTANTS,
  94         FIELDS,
  95         CONSTRUCTORS,
  96         METHODS,
  97         ANNOTATION_TYPE_FIELDS,
  98         ANNOTATION_TYPE_MEMBER_OPTIONAL,
  99         ANNOTATION_TYPE_MEMBER_REQUIRED,
 100         PROPERTIES;
 101 
 102         public static final EnumSet<Kind> summarySet = EnumSet.range(INNER_CLASSES, METHODS);
 103         public static final EnumSet<Kind> detailSet = EnumSet.range(ENUM_CONSTANTS, METHODS);
 104     }
 105 
 106     final TypeElement te;
 107     final TypeElement parent;
 108 
 109     final BaseConfiguration config;
 110     final BaseOptions options;
 111     final Utils utils;
 112     final VisibleMemberCache mcache;
 113 
 114     private List<VisibleMemberTable> allSuperclasses;
 115     private List<VisibleMemberTable> allSuperinterfaces;
 116     private List<VisibleMemberTable> parents;
 117 
 118 
 119     private Map<Kind, List<Element>> extraMembers = new EnumMap<>(Kind.class);
 120     private Map<Kind, List<Element>> visibleMembers = null;
 121     private Map<ExecutableElement, PropertyMembers> propertyMap = new HashMap<>();
 122 
 123     // Keeps track of method overrides
 124     Map<ExecutableElement, OverridingMethodInfo> overriddenMethodTable
 125             = new LinkedHashMap<>();
 126 
 127     protected VisibleMemberTable(TypeElement typeElement, BaseConfiguration configuration,
 128                                  VisibleMemberCache mcache) {
 129         config = configuration;
 130         utils = configuration.utils;
 131         options = configuration.getOptions();
 132         te = typeElement;
 133         parent = utils.getSuperClass(te);
 134         this.mcache = mcache;
 135         allSuperclasses = new ArrayList<>();
 136         allSuperinterfaces = new ArrayList<>();
 137         parents = new ArrayList<>();
 138     }
 139 
 140     private synchronized void ensureInitialized() {
 141         if (visibleMembers != null)
 142             return;
 143 
 144         visibleMembers = new EnumMap<>(Kind.class);
 145         for (Kind kind : Kind.values()) {
 146             visibleMembers.put(kind, new ArrayList<>());
 147         }
 148         computeParents();
 149         computeVisibleMembers();
 150     }
 151 


 644      * contains the members in the declaration order, additionally a
 645      * HashMap is maintained for performance optimization to lookup
 646      * members. As a future enhancement is perhaps to consolidate the ordering
 647      * into a Map, capturing the insertion order, thereby eliminating an
 648      * ordered list.
 649      */
 650     class LocalMemberTable {
 651 
 652         // Maintains declaration order
 653         private final Map<Kind, List<Element>> orderedMembers;
 654 
 655         // Performance optimization
 656         private final Map<Kind, Map<String, List<Element>>> memberMap;
 657 
 658         LocalMemberTable() {
 659             orderedMembers = new EnumMap<>(Kind.class);
 660             memberMap = new EnumMap<>(Kind.class);
 661 
 662             List<? extends Element> elements = te.getEnclosedElements();
 663             for (Element e : elements) {
 664                 if (options.noDeprecated && utils.isDeprecated(e)) {
 665                     continue;
 666                 }
 667                 switch (e.getKind()) {
 668                     case CLASS:
 669                     case INTERFACE:
 670                     case ENUM:
 671                     case ANNOTATION_TYPE:
 672                     case RECORD:
 673                         addMember(e, Kind.INNER_CLASSES);
 674                         break;
 675                     case FIELD:
 676                         addMember(e, Kind.FIELDS);
 677                         addMember(e, Kind.ANNOTATION_TYPE_FIELDS);
 678                         break;
 679                     case METHOD:
 680                         ExecutableElement ee = (ExecutableElement)e;
 681                         if (utils.isAnnotationType(te)) {
 682                             addMember(e, ee.getDefaultValue() == null
 683                                     ? Kind.ANNOTATION_TYPE_MEMBER_REQUIRED
 684                                     : Kind.ANNOTATION_TYPE_MEMBER_OPTIONAL);


 786      * Property field, one may or may not exist and could be private, and
 787      * should match the property-method.
 788      *
 789      * A property-setter is a method starting with "set", and the
 790      * first character of the upper-cased starting character of the property name, the
 791      * method must take 1 argument and must return a <code>void</code>.
 792      *
 793      * Using the above example {@code void setAcme(Something s)} can be
 794      * considered as a property-setter of the property "acme".
 795      *
 796      * A property-getter is a method  starting with "get" and the first character
 797      * upper-cased property-name, having no parameters. A method that does not take any
 798      * parameters and starting with "is" and an upper-cased property-name,
 799      * returning a primitive type boolean or BooleanProperty can also be
 800      * considered as a getter, however there must be only one getter for every property.
 801      *
 802      * For example {@code Object getAcme()} is a property-getter, and
 803      * {@code boolean isFoo()}
 804      */
 805     private void computeVisibleProperties(LocalMemberTable lmt) {
 806         if (!options.javafx)
 807             return;
 808 
 809         PropertyUtils pUtils = config.propertyUtils;
 810         List<ExecutableElement> list = visibleMembers.getOrDefault(Kind.METHODS, Collections.emptyList())
 811                 .stream()
 812                 .map(m -> (ExecutableElement)m)
 813                 .filter(pUtils::isPropertyMethod)
 814                 .collect(Collectors.toList());
 815 
 816         visibleMembers.put(Kind.PROPERTIES, Collections.unmodifiableList(list));
 817 
 818         List<ExecutableElement> propertyMethods = list.stream()
 819                 .filter(e -> utils.getEnclosingTypeElement(e) == te)
 820                 .collect(Collectors.toList());
 821 
 822         // Compute additional properties related sundries.
 823         for (ExecutableElement propertyMethod : propertyMethods) {
 824             String baseName = pUtils.getBaseName(propertyMethod);
 825             List<Element> flist = lmt.getMembers(baseName, Kind.FIELDS);
 826             Element field = flist.isEmpty() ? null : flist.get(0);


< prev index next >