changeset 56959:7096235cdd87 amber-demo-II

Automatic merge with records-and-sealed
author mcimadamore
date Wed, 31 Jul 2019 21:05:39 +0000
parents 86541bf0ae13 d0d29c0bc571
children 888ef8b908e2
files
diffstat 2 files changed, 209 insertions(+), 21 deletions(-) [+]
line wrap: on
line diff
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/Utils.java	Wed Jul 31 20:50:40 2019 +0000
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/Utils.java	Wed Jul 31 21:05:39 2019 +0000
@@ -441,53 +441,72 @@
 
     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);
+        set.remove(NATIVE);
+        set.remove(STRICTFP);
+        set.remove(SYNCHRONIZED);
+        set.remove(SEALED);
 
         return new ElementKindVisitor9<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 addSealed(TypeElement e) {
+                if (elementUtils.isSealed(e)) {
+                    append("sealed");
+                } else if (needsNonSealed(e)) {
+                    append("non-sealed");
                 }
             }
 
-            void addModifers(Set<Modifier> modifiers) {
-                String s = set.stream().map(Modifier::toString).collect(Collectors.joining(" "));
+            boolean needsNonSealed(TypeElement te) {
+                return isSealed(te.getSuperclass())
+                        || te.getInterfaces().stream().anyMatch(this::isSealed);
+            }
+
+            boolean isSealed(TypeMirror tm) {
+                return tm.getKind() == DECLARED
+                        && elementUtils.isSealed((TypeElement) (typeUtils.asElement(tm)));
+            }
+
+            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);
-                if (!s.isEmpty())
-                    sb.append(" ");
             }
 
             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);
+                addSealed(e);
                 return finalString("interface");
             }
 
@@ -507,13 +526,26 @@
 
             @Override
             public String visitTypeAsClass(TypeElement e, SortedSet<Modifier> p) {
-                addModifers(p);
+                Set<Modifier> beforeSealed = EnumSet.noneOf(Modifier.class);
+                Set<Modifier> afterSealed = EnumSet.noneOf(Modifier.class);
+                Set<Modifier> set = beforeSealed;
+                for (Modifier m : Modifier.values()) {
+                    if (m == SEALED) {
+                        set = afterSealed;
+                    }
+                    if (p.contains(m)) {
+                        set.add(m);
+                    }
+                }
+                addModifiers(beforeSealed);
+                addSealed(e);
+                addModifiers(afterSealed);
                 return finalString("class");
             }
 
             @Override
             protected String defaultAction(Element e, SortedSet<Modifier> p) {
-                addModifers(p);
+                addModifiers(p);
                 return sb.toString().trim();
             }
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/langtools/jdk/javadoc/doclet/testSealedTypes/TestSealedTypes.java	Wed Jul 31 21:05:39 2019 +0000
@@ -0,0 +1,156 @@
+/*
+ * 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      8227047
+ * @summary  Sealed types
+ * @library  /tools/lib ../../lib
+ * @modules jdk.javadoc/jdk.javadoc.internal.tool
+ * @build    toolbox.ToolBox javadoc.tester.*
+ * @run main TestSealedTypes
+ */
+
+
+import java.io.IOException;
+import java.nio.file.Path;
+
+import javadoc.tester.JavadocTester;
+import toolbox.ToolBox;
+
+public class TestSealedTypes extends JavadocTester {
+
+    public static void main(String... args) throws Exception {
+        TestSealedTypes tester = new TestSealedTypes();
+        tester.runTests(m -> new Object[] { Path.of(m.getName()) });
+    }
+
+    private final ToolBox tb = new ToolBox();
+
+    @Test
+    public void testSealedModifierClass(Path base) throws IOException {
+        Path src = base.resolve("src");
+        tb.writeJavaFiles(src,
+                "package p; public sealed class A { }");
+
+        javadoc("-d", base.resolve("out").toString(),
+                "-sourcepath", src.toString(),
+                "p");
+        checkExit(Exit.OK);
+
+        checkOutput("p/A.html", true,
+                "public sealed class <span class=\"typeNameLabel\">A</span>");
+    }
+
+    @Test
+    public void testSealedModifierInterface(Path base) throws IOException {
+        Path src = base.resolve("src");
+        tb.writeJavaFiles(src,
+                "package p; public sealed interface A { }");
+
+        javadoc("-d", base.resolve("out").toString(),
+                "-sourcepath", src.toString(),
+                "p");
+        checkExit(Exit.OK);
+
+        checkOutput("p/A.html", true,
+                "public sealed interface <span class=\"typeNameLabel\">A</span>");
+    }
+
+    @Test
+    public void testNonSealedModifierClass(Path base) throws IOException {
+        Path src = base.resolve("src");
+        tb.writeJavaFiles(src,
+                "package p; public sealed class A permits B { }",
+                "package p; public non-sealed class B extends A { }");
+
+        javadoc("-d", base.resolve("out").toString(),
+                "--source-path", src.toString(),
+                "p");
+        checkExit(Exit.OK);
+
+        checkOutput("p/A.html", true,
+                "public sealed class <span class=\"typeNameLabel\">A</span>");
+
+        checkOutput("p/B.html", true,
+                "public non-sealed class <span class=\"typeNameLabel\">B</span>");
+    }
+
+    @Test
+    public void testNonSealedModifierInterface(Path base) throws IOException {
+        Path src = base.resolve("src");
+        tb.writeJavaFiles(src,
+                "package p; public sealed interface A permits B { }",
+                "package p; public non-sealed interface B extends A { }");
+
+        javadoc("-d", base.resolve("out").toString(),
+                "--source-path", src.toString(),
+                "p");
+        checkExit(Exit.OK);
+
+        checkOutput("p/A.html", true,
+                "public sealed interface <span class=\"typeNameLabel\">A</span>");
+
+        checkOutput("p/B.html", true,
+                "public non-sealed interface <span class=\"typeNameLabel\">B</span>");
+    }
+
+    @Test
+    public void testImplicitSealedModifierClass(Path base) throws IOException {
+        Path src = base.resolve("src");
+        tb.writeJavaFiles(src,
+                "package p; public sealed class A permits B { }",
+                "package p; public abstract class B extends A { }");
+
+        javadoc("-d", base.resolve("out").toString(),
+                "--source-path", src.toString(),
+                "p");
+        checkExit(Exit.OK);
+
+        checkOutput("p/A.html", true,
+                "public sealed class <span class=\"typeNameLabel\">A</span>");
+
+        checkOutput("p/B.html", true,
+                "public abstract sealed class <span class=\"typeNameLabel\">B</span>");
+    }
+
+    @Test
+    public void testImplicitSealedModifierInterface(Path base) throws IOException {
+        Path src = base.resolve("src");
+        tb.writeJavaFiles(src,
+                "package p; public sealed interface A permits B { }",
+                "package p; public interface B extends A { }");
+
+        javadoc("-d", base.resolve("out").toString(),
+                "--source-path", src.toString(),
+                "p");
+        checkExit(Exit.OK);
+
+        checkOutput("p/A.html", true,
+                "public sealed interface <span class=\"typeNameLabel\">A</span>");
+
+        checkOutput("p/B.html", true,
+                "public sealed interface <span class=\"typeNameLabel\">B</span>");
+    }
+
+}