changeset 56966:49696396c60c amber-demo-II

Automatic merge with records-and-sealed
author mcimadamore
date Sat, 03 Aug 2019 00:49:50 +0000
parents 9a1e6004ac08 f71ddaa59037
children 1245f81d7e7c
files
diffstat 8 files changed, 177 insertions(+), 52 deletions(-) [+]
line wrap: on
line diff
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlDoclet.java	Fri Aug 02 18:30:37 2019 +0000
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlDoclet.java	Sat Aug 03 00:49:50 2019 +0000
@@ -236,22 +236,21 @@
      * {@inheritDoc}
      */
     @Override // defined by AbstractDoclet
-    protected void generateClassFiles(SortedSet<TypeElement> arr, ClassTree classtree)
+    protected void generateClassFiles(SortedSet<TypeElement> typeElems, ClassTree classTree)
             throws DocletException {
-        List<TypeElement> list = new ArrayList<>(arr);
-        for (TypeElement klass : list) {
-            if (utils.hasHiddenTag(klass) ||
-                    !(configuration.isGeneratedDoc(klass) && utils.isIncluded(klass))) {
+        for (TypeElement te : typeElems) {
+            if (utils.hasHiddenTag(te) ||
+                    !(configuration.isGeneratedDoc(te) && utils.isIncluded(te))) {
                 continue;
             }
-            if (utils.isAnnotationType(klass)) {
+            if (utils.isAnnotationType(te)) {
                 AbstractBuilder annotationTypeBuilder =
                     configuration.getBuilderFactory()
-                        .getAnnotationTypeBuilder(klass);
+                        .getAnnotationTypeBuilder(te);
                 annotationTypeBuilder.build();
             } else {
                 AbstractBuilder classBuilder =
-                    configuration.getBuilderFactory().getClassBuilder(klass, classtree);
+                    configuration.getBuilderFactory().getClassBuilder(te, classTree);
                 classBuilder.build();
             }
         }
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/builders/ClassBuilder.java	Fri Aug 02 18:30:37 2019 +0000
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/builders/ClassBuilder.java	Sat Aug 03 00:49:50 2019 +0000
@@ -70,6 +70,11 @@
     private final boolean isEnum;
 
     /**
+     * Keep track of whether or not this typeElement is an record.
+     */
+    private final boolean isRecord;
+
+    /**
      * The content tree for the class documentation.
      */
     private Content contentTree;
@@ -91,13 +96,20 @@
         if (utils.isInterface(typeElement)) {
             isInterface = true;
             isEnum = false;
+            isRecord = false;
         } else if (utils.isEnum(typeElement)) {
             isInterface = false;
             isEnum = true;
+            isRecord = false;
             utils.setEnumDocumentation(typeElement);
+        } else if (utils.isRecord(typeElement)) {
+            isInterface = false;
+            isEnum = false;
+            isRecord = true;
         } else {
             isInterface = false;
             isEnum = false;
+            isRecord = false;
         }
     }
 
@@ -133,6 +145,8 @@
             key = "doclet.Interface";
         } else if (isEnum) {
             key = "doclet.Enum";
+        } else if (isRecord) {
+            key = "doclet.Record";
         } else {
             key = "doclet.Class";
         }
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/resources/doclets.properties	Fri Aug 02 18:30:37 2019 +0000
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/resources/doclets.properties	Sat Aug 03 00:49:50 2019 +0000
@@ -137,6 +137,7 @@
 doclet.interfaces=interfaces
 doclet.class=class
 doclet.classes=classes
+doclet.Record=Record
 doclet.Error=Error
 doclet.error=error
 doclet.errors=errors
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/taglets/TagletManager.java	Fri Aug 02 18:30:37 2019 +0000
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/taglets/TagletManager.java	Sat Aug 03 00:49:50 2019 +0000
@@ -521,6 +521,7 @@
             case INTERFACE:
             case CLASS:
             case ENUM:
+            case RECORD:
                 return blockTagletsBySite.get(Site.TYPE);
             case MODULE:
                 return blockTagletsBySite.get(Site.MODULE);
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/Utils.java	Fri Aug 02 18:30:37 2019 +0000
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/Utils.java	Sat Aug 03 00:49:50 2019 +0000
@@ -427,6 +427,10 @@
         return typeUtils.isSubtype(e.asType(), getExternalizableType());
     }
 
+    public boolean isRecord(TypeElement e) {
+        return e.getKind() == ElementKind.RECORD;
+    }
+
     public SortedSet<VariableElement> serializableFields(TypeElement aclass) {
         return configuration.workArounds.getSerializableFields(this, aclass);
     }
@@ -440,11 +444,11 @@
     }
 
     public String modifiersToString(Element e, boolean trailingSpace) {
-        SortedSet<Modifier> set = new TreeSet<>(e.getModifiers());
-        set.remove(NATIVE);
-        set.remove(STRICTFP);
-        set.remove(SYNCHRONIZED);
-        set.remove(SEALED);
+        SortedSet<Modifier> modifiers = new TreeSet<>(e.getModifiers());
+        modifiers.remove(NATIVE);
+        modifiers.remove(STRICTFP);
+        modifiers.remove(SYNCHRONIZED);
+        modifiers.remove(SEALED);
 
         return new ElementKindVisitor9<String, SortedSet<Modifier>>() {
             final StringBuilder sb = new StringBuilder();
@@ -503,29 +507,35 @@
             }
 
             @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);
                 addSealed(e);
                 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) {
+            public String visitTypeAsRecord(TypeElement e, SortedSet<Modifier> mods) {
+                mods.remove(FINAL); // suppress the implicit `final`
+                return visitTypeAsClass(e, mods);
+            }
+
+            @Override
+            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;
@@ -533,23 +543,24 @@
                     if (m == SEALED) {
                         set = afterSealed;
                     }
-                    if (p.contains(m)) {
+                    if (mods.contains(m)) {
                         set.add(m);
                     }
                 }
                 addModifiers(beforeSealed);
                 addSealed(e);
                 addModifiers(afterSealed);
-                return finalString("class");
+                String keyword = e.getKind() == ElementKind.RECORD ? "record" : "class";
+                return finalString(keyword);
             }
 
             @Override
-            protected String defaultAction(Element e, SortedSet<Modifier> p) {
-                addModifiers(p);
+            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) {
@@ -1800,7 +1811,7 @@
                     result = compareStrings(getFullyQualifiedName(o1), getFullyQualifiedName(o2));
                     if (result != 0)
                         return result;
-                    return compareElementTypeKinds(o1, o2);
+                    return compareElementKinds(o1, o2);
                 }
             };
         }
@@ -1849,7 +1860,7 @@
                         return result;
                     }
                     // if names are the same, compare element kinds
-                    result = compareElementTypeKinds(e1, e2);
+                    result = compareElementKinds(e1, e2);
                     if (result != 0) {
                         return result;
                     }
@@ -2025,7 +2036,7 @@
                     if (result != 0) {
                         return result;
                     }
-                    return compareElementTypeKinds(e1, e2);
+                    return compareElementKinds(e1, e2);
                 }
             };
         }
@@ -2037,6 +2048,8 @@
      * 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.
@@ -2045,21 +2058,6 @@
          * @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) {
 
@@ -2122,10 +2120,28 @@
             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());
+            }
+        }
+
         boolean hasParameters(Element e) {
             return new SimpleElementVisitor9<Boolean, Void>() {
                 @Override
@@ -2227,6 +2243,7 @@
         out.addAll(getClasses(pkg));
         out.addAll(getEnums(pkg));
         out.addAll(getAnnotationTypes(pkg));
+        out.addAll(getRecords(pkg));
         return out;
     }
 
@@ -2257,6 +2274,14 @@
         return convertToTypeElement(getItems(e, false, ANNOTATION_TYPE));
     }
 
+    public List<TypeElement> getRecords(Element e) {
+        return convertToTypeElement(getItems(e, true, RECORD));
+    }
+
+    public List<TypeElement> getRecordsUnfiltered(Element e) {
+        return convertToTypeElement(getItems(e, false, RECORD));
+    }
+
     public List<VariableElement> getFields(Element e) {
         return convertToVariableElement(getItems(e, true, FIELD));
     }
@@ -2431,6 +2456,7 @@
         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);
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/ElementsTable.java	Fri Aug 02 18:30:37 2019 +0000
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/ElementsTable.java	Sat Aug 03 00:49:50 2019 +0000
@@ -1200,7 +1200,7 @@
                                                     ElementKind.PACKAGE,
                                                     ElementKind.MODULE);
 
-        // all possible accesss levels allowed for each element
+        // all possible access levels allowed for each element
         private final EnumMap<ElementKind, EnumSet<AccessKind>> filterMap =
                 new EnumMap<>(ElementKind.class);
 
@@ -1285,7 +1285,7 @@
             switch (kind) {
                 case CLASS: case METHOD: case MODULE: case PACKAGE:
                     return kind;
-                case ANNOTATION_TYPE: case ENUM: case INTERFACE:
+                case RECORD: case ANNOTATION_TYPE: case ENUM: case INTERFACE:
                     return ElementKind.CLASS;
                 case CONSTRUCTOR: case ENUM_CONSTANT: case EXCEPTION_PARAMETER:
                 case FIELD: case INSTANCE_INIT: case LOCAL_VARIABLE: case PARAMETER:
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/langtools/jdk/javadoc/doclet/testRecordTypes/TestRecordTypes.java	Sat Aug 03 00:49:50 2019 +0000
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug      8225055
+ * @summary  Record types
+ * @library  /tools/lib ../../lib
+ * @modules jdk.javadoc/jdk.javadoc.internal.tool
+ * @build    toolbox.ToolBox javadoc.tester.*
+ * @run main TestRecordTypes
+ */
+
+
+import java.io.IOException;
+import java.nio.file.Path;
+
+import javadoc.tester.JavadocTester;
+import toolbox.ToolBox;
+
+public class TestRecordTypes extends JavadocTester {
+
+    public static void main(String... args) throws Exception {
+        TestRecordTypes tester = new TestRecordTypes();
+        tester.runTests(m -> new Object[] { Path.of(m.getName()) });
+    }
+
+    private final ToolBox tb = new ToolBox();
+
+    @Test
+    public void testRecordKeywordUnnamedPackage(Path base) throws IOException {
+        Path src = base.resolve("src");
+        tb.writeJavaFiles(src,
+                "public record A(int a) { }");
+
+        javadoc("-d", base.resolve("out").toString(),
+                "-sourcepath", src.toString(),
+                src.resolve("A.java").toString());
+        checkExit(Exit.OK);
+
+        checkOutput("A.html", true,
+                "<h1 title=\"Record A\" class=\"title\">Record A</h1>",
+                "public record <span class=\"typeNameLabel\">A</span>",
+                "<code><span class=\"memberNameLink\"><a href=\"#%3Cinit%3E(int)\">A</a></span>&#8203;(int&nbsp;a)</code>");
+    }
+
+    @Test
+    public void testRecordKeywordNamedPackage(Path base) throws IOException {
+        Path src = base.resolve("src");
+        tb.writeJavaFiles(src,
+                "package p; public record A(int a) { }");
+
+        javadoc("-d", base.resolve("out").toString(),
+                "-sourcepath", src.toString(),
+                "p");
+        checkExit(Exit.OK);
+
+        checkOutput("p/A.html", true,
+                "<h1 title=\"Record A\" class=\"title\">Record A</h1>",
+                "public record <span class=\"typeNameLabel\">A</span>",
+                "<code><span class=\"memberNameLink\"><a href=\"#%3Cinit%3E(int)\">A</a></span>&#8203;(int&nbsp;a)</code>");
+    }
+
+}
--- a/test/langtools/tools/lib/toolbox/ToolBox.java	Fri Aug 02 18:30:37 2019 +0000
+++ b/test/langtools/tools/lib/toolbox/ToolBox.java	Sat Aug 03 00:49:50 2019 +0000
@@ -650,7 +650,7 @@
         private static Pattern packagePattern =
                 Pattern.compile("package\\s+(((?:\\w+\\.)*)(?:\\w+))");
         private static Pattern classPattern =
-                Pattern.compile("(?:public\\s+)?(?:class|enum|interface)\\s+(\\w+)");
+                Pattern.compile("(?:public\\s+)?(?:class|enum|interface|record)\\s+(\\w+)");
 
         /**
          * Extracts the Java file name from the class declaration.