< 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

@@ -45,10 +45,11 @@
 import javax.lang.model.element.ExecutableElement;
 import javax.lang.model.element.Modifier;
 import javax.lang.model.element.ModuleElement;
 import javax.lang.model.element.ModuleElement.RequiresDirective;
 import javax.lang.model.element.PackageElement;
+import javax.lang.model.element.RecordComponentElement;
 import javax.lang.model.element.TypeElement;
 import javax.lang.model.element.TypeParameterElement;
 import javax.lang.model.element.VariableElement;
 import javax.lang.model.type.ArrayType;
 import javax.lang.model.type.DeclaredType;

@@ -58,13 +59,13 @@
 import javax.lang.model.type.PrimitiveType;
 import javax.lang.model.type.TypeMirror;
 import javax.lang.model.type.TypeVariable;
 import javax.lang.model.type.WildcardType;
 import javax.lang.model.util.ElementFilter;
-import javax.lang.model.util.ElementKindVisitor9;
+import javax.lang.model.util.ElementKindVisitor14;
 import javax.lang.model.util.Elements;
-import javax.lang.model.util.SimpleElementVisitor9;
+import javax.lang.model.util.SimpleElementVisitor14;
 import javax.lang.model.util.SimpleTypeVisitor9;
 import javax.lang.model.util.TypeKindVisitor9;
 import javax.lang.model.util.Types;
 import javax.tools.FileObject;
 import javax.tools.JavaFileManager;

@@ -299,12 +300,13 @@
 
     public boolean isAnnotated(Element e) {
         return !e.getAnnotationMirrors().isEmpty();
     }
 
+    @SuppressWarnings("preview")
     public boolean isAnnotationType(Element e) {
-        return new SimpleElementVisitor9<Boolean, Void>() {
+        return new SimpleElementVisitor14<Boolean, Void>() {
             @Override
             public Boolean visitExecutable(ExecutableElement e, Void p) {
                 return visit(e.getEnclosingElement());
             }
 

@@ -414,10 +416,38 @@
 
     public boolean isExternalizable(TypeElement e) {
         return typeUtils.isSubtype(e.asType(), getExternalizableType());
     }
 
+    @SuppressWarnings("preview")
+    public boolean isRecord(TypeElement e) {
+        return e.getKind() == ElementKind.RECORD;
+    }
+
+    @SuppressWarnings("preview")
+    public boolean isCanonicalRecordConstructor(ExecutableElement ee) {
+        TypeElement te = (TypeElement) ee.getEnclosingElement();
+        List<? extends RecordComponentElement> stateComps = te.getRecordComponents();
+        List<? extends VariableElement> params = ee.getParameters();
+        if (stateComps.size() != params.size()) {
+            return false;
+        }
+
+        Iterator<? extends RecordComponentElement> stateIter = stateComps.iterator();
+        Iterator<? extends VariableElement> paramIter = params.iterator();
+        while (paramIter.hasNext() && stateIter.hasNext()) {
+            VariableElement param = paramIter.next();
+            RecordComponentElement comp = stateIter.next();
+            if (!Objects.equals(param.getSimpleName(), comp.getSimpleName())
+                    || !typeUtils.isSameType(param.asType(), comp.asType())) {
+                return false;
+            }
+        }
+
+        return true;
+    }
+
     public SortedSet<VariableElement> serializableFields(TypeElement aclass) {
         return configuration.workArounds.getSerializableFields(aclass);
     }
 
     public SortedSet<ExecutableElement> serializationMethods(TypeElement aclass) {

@@ -426,89 +456,106 @@
 
     public boolean definesSerializableFields(TypeElement aclass) {
         return configuration.workArounds.definesSerializableFields( aclass);
     }
 
+    @SuppressWarnings("preview")
     public String modifiersToString(Element e, boolean trailingSpace) {
-        SortedSet<Modifier> set = new TreeSet<>(e.getModifiers());
-        set.remove(Modifier.NATIVE);
-        set.remove(Modifier.STRICTFP);
-        set.remove(Modifier.SYNCHRONIZED);
+        SortedSet<Modifier> modifiers = new TreeSet<>(e.getModifiers());
+        modifiers.remove(NATIVE);
+        modifiers.remove(STRICTFP);
+        modifiers.remove(SYNCHRONIZED);
 
-        return new ElementKindVisitor9<String, SortedSet<Modifier>>() {
+        return new ElementKindVisitor14<String, SortedSet<Modifier>>() {
             final StringBuilder sb = new StringBuilder();
 
             void addVisibilityModifier(Set<Modifier> modifiers) {
                 if (modifiers.contains(PUBLIC)) {
-                    sb.append("public").append(" ");
+                    append("public");
                 } else if (modifiers.contains(PROTECTED)) {
-                    sb.append("protected").append(" ");
+                    append("protected");
                 } else if (modifiers.contains(PRIVATE)) {
-                    sb.append("private").append(" ");
+                    append("private");
                 }
             }
 
             void addStatic(Set<Modifier> modifiers) {
                 if (modifiers.contains(STATIC)) {
-                    sb.append("static").append(" ");
+                    append("static");
                 }
             }
 
-            void addModifers(Set<Modifier> modifiers) {
-                String s = set.stream().map(Modifier::toString).collect(Collectors.joining(" "));
-                sb.append(s);
-                if (!s.isEmpty())
+            void addModifiers(Set<Modifier> modifiers) {
+                modifiers.stream().map(Modifier::toString).forEach(this::append);
+            }
+
+            void append(String s) {
+                if (sb.length() > 0) {
                     sb.append(" ");
             }
+                sb.append(s);
+            }
 
             String finalString(String s) {
-                sb.append(s);
+                append(s);
                 if (trailingSpace) {
-                    if (sb.lastIndexOf(" ") == sb.length() - 1) {
-                        return sb.toString();
-                    } else {
-                        return sb.append(" ").toString();
-                    }
-                } else {
-                    return sb.toString().trim();
+                    sb.append(" ");
                 }
+                return sb.toString();
             }
 
             @Override
-            public String visitTypeAsInterface(TypeElement e, SortedSet<Modifier> p) {
-                addVisibilityModifier(p);
-                addStatic(p);
+            public String visitTypeAsInterface(TypeElement e, SortedSet<Modifier> mods) {
+                addVisibilityModifier(mods);
+                addStatic(mods);
                 return finalString("interface");
             }
 
             @Override
-            public String visitTypeAsEnum(TypeElement e, SortedSet<Modifier> p) {
-                addVisibilityModifier(p);
-                addStatic(p);
+            public String visitTypeAsEnum(TypeElement e, SortedSet<Modifier> mods) {
+                addVisibilityModifier(mods);
+                addStatic(mods);
                 return finalString("enum");
             }
 
             @Override
-            public String visitTypeAsAnnotationType(TypeElement e, SortedSet<Modifier> p) {
-                addVisibilityModifier(p);
-                addStatic(p);
+            public String visitTypeAsAnnotationType(TypeElement e, SortedSet<Modifier> mods) {
+                addVisibilityModifier(mods);
+                addStatic(mods);
                 return finalString("@interface");
             }
 
             @Override
-            public String visitTypeAsClass(TypeElement e, SortedSet<Modifier> p) {
-                addModifers(p);
-                return finalString("class");
+            public String visitTypeAsRecord(TypeElement e, SortedSet<Modifier> mods) {
+                mods.remove(FINAL); // suppress the implicit `final`
+                return visitTypeAsClass(e, mods);
             }
 
             @Override
-            protected String defaultAction(Element e, SortedSet<Modifier> p) {
-                addModifers(p);
+            @SuppressWarnings("preview")
+            public String visitTypeAsClass(TypeElement e, SortedSet<Modifier> mods) {
+                Set<Modifier> beforeSealed = EnumSet.noneOf(Modifier.class);
+                Set<Modifier> afterSealed = EnumSet.noneOf(Modifier.class);
+                Set<Modifier> set = beforeSealed;
+                for (Modifier m : Modifier.values()) {
+                    if (mods.contains(m)) {
+                        set.add(m);
+                    }
+                }
+                addModifiers(beforeSealed);
+                addModifiers(afterSealed);
+                String keyword = e.getKind() == ElementKind.RECORD ? "record" : "class";
+                return finalString(keyword);
+            }
+
+            @Override
+            protected String defaultAction(Element e, SortedSet<Modifier> mods) {
+                addModifiers(mods);
                 return sb.toString().trim();
             }
 
-        }.visit(e, set);
+        }.visit(e, modifiers);
     }
 
     public boolean isFunctionalInterface(AnnotationMirror amirror) {
         return amirror.getAnnotationType().equals(getFunctionalInterface()) &&
                 configuration.docEnv.getSourceVersion()

@@ -591,11 +638,11 @@
         }
     }
 
     public boolean isTypeElement(Element e) {
         switch (e.getKind()) {
-            case CLASS: case ENUM: case INTERFACE: case ANNOTATION_TYPE:
+            case CLASS: case ENUM: case INTERFACE: case ANNOTATION_TYPE: case RECORD:
                 return true;
             default:
                 return false;
         }
     }

@@ -1361,31 +1408,10 @@
         sb.append(text, pos, textLength);
         return sb;
     }
 
     /**
-     * The documentation for values() and valueOf() in Enums are set by the
-     * doclet only iff the user or overridden methods are missing.
-     * @param elem
-     */
-    public void setEnumDocumentation(TypeElement elem) {
-        for (Element e : getMethods(elem)) {
-            ExecutableElement ee = (ExecutableElement)e;
-            if (!getFullBody(e).isEmpty()) // ignore if already set
-                continue;
-            if (ee.getSimpleName().contentEquals("values") && ee.getParameters().isEmpty()) {
-                removeCommentHelper(ee); // purge previous entry
-                configuration.cmtUtils.setEnumValuesTree(e);
-            }
-            if (ee.getSimpleName().contentEquals("valueOf") && ee.getParameters().size() == 1) {
-                removeCommentHelper(ee); // purge previous entry
-                configuration.cmtUtils.setEnumValueOfTree(e);
-            }
-        }
-    }
-
-    /**
      * Returns a locale independent upper cased String. That is, it
      * always uses US locale, this is a clone of the one in StringUtils.
      * @param s to convert
      * @return converted String
      */

@@ -1758,11 +1784,11 @@
                             return result;
                     }
                     result = compareStrings(getFullyQualifiedName(o1), getFullyQualifiedName(o2));
                     if (result != 0)
                         return result;
-                    return compareElementTypeKinds(o1, o2);
+                    return compareElementKinds(o1, o2);
                 }
             };
         }
         return overrideUseComparator;
     }

@@ -1807,11 +1833,11 @@
                     }
                     if (result != 0) {
                         return result;
                     }
                     // if names are the same, compare element kinds
-                    result = compareElementTypeKinds(e1, e2);
+                    result = compareElementKinds(e1, e2);
                     if (result != 0) {
                         return result;
                     }
                     // if element kinds are the same, and are methods,
                     // compare the method parameters

@@ -1915,12 +1941,13 @@
      */
     public String getFullyQualifiedName(Element e) {
         return getFullyQualifiedName(e, true);
     }
 
+    @SuppressWarnings("preview")
     public String getFullyQualifiedName(Element e, final boolean outer) {
-        return new SimpleElementVisitor9<String, Void>() {
+        return new SimpleElementVisitor14<String, Void>() {
             @Override
             public String visitModule(ModuleElement e, Void p) {
                 return e.getQualifiedName().toString();
             }
 

@@ -1983,11 +2010,11 @@
                         result = compareParameters(true, parameters1, parameters2);
                     }
                     if (result != 0) {
                         return result;
                     }
-                    return compareElementTypeKinds(e1, e2);
+                    return compareElementKinds(e1, e2);
                 }
             };
         }
         return classUseComparator;
     }

@@ -1995,33 +2022,20 @@
     /**
      * A general purpose comparator to sort Element entities, basically provides the building blocks
      * for creating specific comparators for an use-case.
      */
     private abstract class ElementComparator implements Comparator<Element> {
+        public ElementComparator() { }
+
         /**
          * compares two parameter arrays by first comparing the length of the arrays, and
          * then each Type of the parameter in the array.
          * @param params1 the first parameter array.
          * @param params2 the first parameter array.
          * @return a negative integer, zero, or a positive integer as the first
          *         argument is less than, equal to, or greater than the second.
          */
-        final EnumMap<ElementKind, Integer> elementKindOrder;
-        public ElementComparator() {
-            elementKindOrder = new EnumMap<>(ElementKind.class);
-            elementKindOrder.put(ElementKind.MODULE, 0);
-            elementKindOrder.put(ElementKind.PACKAGE, 1);
-            elementKindOrder.put(ElementKind.CLASS, 2);
-            elementKindOrder.put(ElementKind.ENUM, 3);
-            elementKindOrder.put(ElementKind.ENUM_CONSTANT, 4);
-            elementKindOrder.put(ElementKind.INTERFACE, 5);
-            elementKindOrder.put(ElementKind.ANNOTATION_TYPE, 6);
-            elementKindOrder.put(ElementKind.FIELD, 7);
-            elementKindOrder.put(ElementKind.CONSTRUCTOR, 8);
-            elementKindOrder.put(ElementKind.METHOD, 9);
-        }
-
         protected int compareParameters(boolean caseSensitive, List<? extends VariableElement> params1,
                                                                List<? extends VariableElement> params2) {
 
             return compareStrings(caseSensitive, getParametersAsString(params1),
                                                  getParametersAsString(params2));

@@ -2080,16 +2094,35 @@
             // add simplename to be compatible
             String thisElement = getFullyQualifiedName(e1);
             String thatElement = getFullyQualifiedName(e2);
             return compareStrings(thisElement, thatElement);
         }
-        protected int compareElementTypeKinds(Element e1, Element e2) {
-            return Integer.compare(elementKindOrder.get(e1.getKind()),
-                                   elementKindOrder.get(e2.getKind()));
+
+        protected int compareElementKinds(Element e1, Element e2) {
+            return Integer.compare(getKindIndex(e1), getKindIndex(e2));
         }
+
+        private int getKindIndex(Element e) {
+            switch (e.getKind()) {
+                case MODULE:            return 0;
+                case PACKAGE:           return 1;
+                case CLASS:             return 2;
+                case ENUM:              return 3;
+                case ENUM_CONSTANT:     return 4;
+                case RECORD:            return 5;
+                case INTERFACE:         return 6;
+                case ANNOTATION_TYPE:   return 7;
+                case FIELD:             return 8;
+                case CONSTRUCTOR:       return 9;
+                case METHOD:            return 10;
+                default: throw new IllegalArgumentException(e.getKind().toString());
+            }
+        }
+
+        @SuppressWarnings("preview")
         boolean hasParameters(Element e) {
-            return new SimpleElementVisitor9<Boolean, Void>() {
+            return new SimpleElementVisitor14<Boolean, Void>() {
                 @Override
                 public Boolean visitExecutable(ExecutableElement e, Void p) {
                     return true;
                 }
 

@@ -2105,12 +2138,13 @@
          * The fully qualified names of the entities, used solely by the comparator.
          *
          * @return a negative integer, zero, or a positive integer as the first argument is less
          * than, equal to, or greater than the second.
          */
+        @SuppressWarnings("preview")
         private String getFullyQualifiedName(Element e) {
-            return new SimpleElementVisitor9<String, Void>() {
+            return new SimpleElementVisitor14<String, Void>() {
                 @Override
                 public String visitModule(ModuleElement e, Void p) {
                     return e.getQualifiedName().toString();
                 }
 

@@ -2185,10 +2219,11 @@
     public Iterable<TypeElement> getEnclosedTypeElements(PackageElement pkg) {
         List<TypeElement> out = getInterfaces(pkg);
         out.addAll(getClasses(pkg));
         out.addAll(getEnums(pkg));
         out.addAll(getAnnotationTypes(pkg));
+        out.addAll(getRecords(pkg));
         return out;
     }
 
     // Element related methods
     public List<Element> getAnnotationMembers(TypeElement aClass) {

@@ -2215,10 +2250,20 @@
 
     public List<TypeElement> getAnnotationTypesUnfiltered(Element e) {
         return convertToTypeElement(getItems(e, false, ANNOTATION_TYPE));
     }
 
+    @SuppressWarnings("preview")
+    public List<TypeElement> getRecords(Element e) {
+        return convertToTypeElement(getItems(e, true, RECORD));
+    }
+
+    @SuppressWarnings("preview")
+    public List<TypeElement> getRecordsUnfiltered(Element e) {
+        return convertToTypeElement(getItems(e, false, RECORD));
+    }
+
     public List<VariableElement> getFields(Element e) {
         return convertToVariableElement(getItems(e, true, FIELD));
     }
 
     public List<VariableElement> getFieldsUnfiltered(Element e) {

@@ -2369,10 +2414,11 @@
 
     public SortedSet<TypeElement> getAllClassesUnfiltered(Element e) {
         List<TypeElement> clist = getClassesUnfiltered(e);
         clist.addAll(getInterfacesUnfiltered(e));
         clist.addAll(getAnnotationTypesUnfiltered(e));
+        clist.addAll(getRecordsUnfiltered(e));
         SortedSet<TypeElement> oset = new TreeSet<>(makeGeneralPurposeComparator());
         oset.addAll(clist);
         return oset;
     }
 

@@ -2389,10 +2435,11 @@
             return oset;
         List<TypeElement> clist = getClasses(e);
         clist.addAll(getInterfaces(e));
         clist.addAll(getAnnotationTypes(e));
         clist.addAll(getEnums(e));
+        clist.addAll(getRecords(e));
         oset = new TreeSet<>(makeGeneralPurposeComparator());
         oset.addAll(clist);
         cachedClasses.put(e, oset);
         return oset;
     }

@@ -2457,13 +2504,14 @@
                 .stream()
                 .filter(this::isException)
                 .collect(Collectors.toList());
     }
 
+    @SuppressWarnings("preview")
     List<Element> getItems(Element e, boolean filter, ElementKind select) {
         List<Element> elements = new ArrayList<>();
-        return new SimpleElementVisitor9<List<Element>, Void>() {
+        return new SimpleElementVisitor14<List<Element>, Void>() {
 
             @Override
             public List<Element> visitPackage(PackageElement e, Void p) {
                 recursiveGetItems(elements, e, filter, select);
                 return elements;

@@ -2504,15 +2552,17 @@
             }
         }
         return elements;
     }
 
-    private SimpleElementVisitor9<Boolean, Void> shouldDocumentVisitor = null;
+    @SuppressWarnings("preview")
+    private SimpleElementVisitor14<Boolean, Void> shouldDocumentVisitor = null;
 
-    protected boolean shouldDocument(Element e) {
+    @SuppressWarnings("preview")
+    public boolean shouldDocument(Element e) {
         if (shouldDocumentVisitor == null) {
-            shouldDocumentVisitor = new SimpleElementVisitor9<Boolean, Void>() {
+            shouldDocumentVisitor = new SimpleElementVisitor14<Boolean, Void>() {
                 private boolean hasSource(TypeElement e) {
                     return configuration.docEnv.getFileKind(e) ==
                             javax.tools.JavaFileObject.Kind.SOURCE;
                 }
 

@@ -2558,15 +2608,17 @@
      */
     public String getSimpleName(Element e) {
         return nameCache.computeIfAbsent(e, this::getSimpleName0);
     }
 
-    private SimpleElementVisitor9<String, Void> snvisitor = null;
+    @SuppressWarnings("preview")
+    private SimpleElementVisitor14<String, Void> snvisitor = null;
 
+    @SuppressWarnings("preview")
     private String getSimpleName0(Element e) {
         if (snvisitor == null) {
-            snvisitor = new SimpleElementVisitor9<String, Void>() {
+            snvisitor = new SimpleElementVisitor14<String, Void>() {
                 @Override
                 public String visitModule(ModuleElement e, Void p) {
                     return e.getQualifiedName().toString();  // temp fix for 8182736
                 }
 

@@ -2743,14 +2795,16 @@
 
     public boolean isIncluded(Element e) {
         return configuration.docEnv.isIncluded(e);
     }
 
-    private SimpleElementVisitor9<Boolean, Void> specifiedVisitor = null;
+    @SuppressWarnings("preview")
+    private SimpleElementVisitor14<Boolean, Void> specifiedVisitor = null;
+    @SuppressWarnings("preview")
     public boolean isSpecified(Element e) {
         if (specifiedVisitor == null) {
-            specifiedVisitor = new SimpleElementVisitor9<Boolean, Void>() {
+            specifiedVisitor = new SimpleElementVisitor14<Boolean, Void>() {
                 @Override
                 public Boolean visitModule(ModuleElement e, Void p) {
                     return configuration.getSpecifiedModuleElements().contains(e);
                 }
 

@@ -3194,24 +3248,24 @@
 
     public List<? extends DocTree> getThrowsTrees(Element element) {
         return getBlockTags(element, DocTree.Kind.EXCEPTION, DocTree.Kind.THROWS);
     }
 
-    public List<? extends DocTree> getTypeParamTrees(Element element) {
+    public List<? extends ParamTree> getTypeParamTrees(Element element) {
         return getParamTrees(element, true);
     }
 
-    public List<? extends DocTree> getParamTrees(Element element) {
+    public List<? extends ParamTree> getParamTrees(Element element) {
         return getParamTrees(element, false);
     }
 
-    private  List<? extends DocTree> getParamTrees(Element element, boolean isTypeParameters) {
-        List<DocTree> out = new ArrayList<>();
+    private  List<? extends ParamTree> getParamTrees(Element element, boolean isTypeParameters) {
+        List<ParamTree> out = new ArrayList<>();
         for (DocTree dt : getBlockTags(element, PARAM)) {
             ParamTree pt = (ParamTree) dt;
             if (pt.isTypeParameter() == isTypeParameters) {
-                out.add(dt);
+                out.add(pt);
             }
         }
         return out;
     }
 
< prev index next >