OpenJDK / amber / amber
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>"); + } + +}