OpenJDK / amber / amber
changeset 57004:0fbfd52012af amber-demo-II
Automatic merge with records-and-sealed
author | mcimadamore |
---|---|
date | Mon, 19 Aug 2019 20:05:41 +0000 |
parents | 475bf8c9563b 4750d96927b1 |
children | b3b50e7ad342 |
files | src/java.base/share/classes/java/lang/annotation/ElementType.java test/langtools/tools/javac/records/RecordCompilationTests.java |
diffstat | 2 files changed, 84 insertions(+), 9 deletions(-) [+] |
line wrap: on
line diff
--- a/src/java.base/share/classes/java/lang/annotation/ElementType.java Fri Aug 16 21:15:43 2019 +0000 +++ b/src/java.base/share/classes/java/lang/annotation/ElementType.java Mon Aug 19 20:05:41 2019 +0000 @@ -114,5 +114,12 @@ * * @since 9 */ - MODULE + MODULE, + + /** + * Record component + * + * @since 14 + */ + RECORD_COMPONENT; }
--- a/test/langtools/tools/javac/records/RecordCompilationTests.java Fri Aug 16 21:15:43 2019 +0000 +++ b/test/langtools/tools/javac/records/RecordCompilationTests.java Mon Aug 19 20:05:41 2019 +0000 @@ -101,17 +101,18 @@ assertFail("compiler.err.premature.eof", "record R();"); assertFail("compiler.err.illegal.start.of.type", "record R(,) { }"); assertFail("compiler.err.illegal.start.of.type", "record R((int x)) { }"); + assertFail("compiler.err.expected", "record R { }"); assertFail("compiler.err.expected", "record R(foo) { }"); assertFail("compiler.err.expected", "record R(int int) { }"); - assertFail("compiler.err.restricted.type.not.allowed.here", "record R(var x) { }"); - assertFail("compiler.err.restricted.type.not.allowed.here", "record R(record x) { }"); - assertFail("compiler.err.record.cant.declare.field.modifiers", "record R(public String foo) { }"); - assertFail("compiler.err.record.cant.declare.field.modifiers", "record R(private String foo) { }"); assertFail("compiler.err.mod.not.allowed.here", "abstract record R(String foo) { }"); assertFail("compiler.err.illegal.combination.of.modifiers", "non-sealed record R(String foo) { }"); assertFail("compiler.err.repeated.modifier", "public public record R(String foo) { }"); assertFail("compiler.err.repeated.modifier", "private private record R(String foo) { }"); assertFail("compiler.err.record.cant.declare.duplicate.fields", "record R(int x, int x) {}"); + for (String s : List.of("var", "record")) + assertFail("compiler.err.restricted.type.not.allowed.here", "record R(# x) { }", s); + for (String s : List.of("public", "private", "volatile", "final")) + assertFail("compiler.err.record.cant.declare.field.modifiers", "record R(# String foo) { }", s); } public void testGoodDeclarations() { @@ -125,6 +126,18 @@ assertOK("record R<T>(T x, T y) { }"); } + public void testGoodMemberDeclarations() { + // @@@ Duplicates RecordsCanReDeclareMembersTest + String template = "public record R(int x) {\n" + + " public R(int x) { this.x = x; }\n" + + " public int x() { return x; }\n" + + " public boolean equals(Object o) { return true; }\n" + + " public int hashCode() { return 0; }\n" + + " public String toString() { return null; }\n" + + "}"; + assertOK(template); + } + public void testBadComponentNames() { // @@@ Duplicates IllegalRecordComponentNameTest for (String s : BAD_COMPONENT_NAMES) @@ -201,6 +214,8 @@ } public void testAccessorRedeclaration() { + // @@@ Duplicates BadAccessorsTest + // @@@ Duplicates UserDefinedAccessorsMustBePublic assertOK("public record R(int x) {\n" + " public int x() { return x; };" + "}"); @@ -219,6 +234,11 @@ " int x() { return 0; };" + "}"); + assertFail("compiler.err.method.must.be.public", + "public record R(int x) {\n" + + " private int x() { return 0; };" + + "}"); + // @@@ Error: should fail, but doesn't // assertFail("something", // "public record R(int x) {\n" + @@ -254,16 +274,64 @@ "import java.util.*;\n" + "record R(List<String> list) { # }", "R(List list) { this.list = list; }"); + + // ctor should not add checked exceptions + // @@@ Currently failing +// assertFail("compiler.err.constructor.with.same.erasure.as.canonical", +// "record R() { # }", +// "public R() throws Exception { }"); + + // but unchecked exceptions are OK + assertOK("record R() { # }", + "public R() throws IllegalArgumentException { }"); + + // @@@ Duplicates MismatchTest + // If types match, names must match + assertFail("compiler.err.canonical.with.name.mismatch", + "record R(int x, int y) { public R(int y, int x) { this.x = this.y = 0; }}"); } public void testAnnotationCriteria() { - // OK to anno with FIELD, METHOD, PARAM, TYPE_USE, and COMPONENT, no @Target, or group thereof - // Not OK to anno when @Target specified and none of those are available - // OK to redeclare with or without same annos + String imports = "import java.lang.annotation.*;\n"; + String A_COMPONENT = "@Target({ ElementType.RECORD_COMPONENT }) @interface A {}\n"; + String A_FIELD = "@Target({ ElementType.FIELD }) @interface A {}\n"; + String A_METHOD = "@Target({ ElementType.METHOD }) @interface A {}\n"; + String A_PARAM = "@Target({ ElementType.PARAMETER }) @interface A {}\n"; + String A_TYPE_USE = "@Target({ ElementType.TYPE_USE }) @interface A {}\n"; + String A_MULTI = "@Target({ ElementType.RECORD_COMPONENT, ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER, ElementType.TYPE_USE }) @interface A {}\n"; + String A_NONE = "@interface A {}\n"; + + String A_CTOR = "@Target({ ElementType.CONSTRUCTOR }) @interface A {}\n"; + String A_PACKAGE = "@Target({ ElementType.PACKAGE }) @interface A {}\n"; + String A_TYPE = "@Target({ ElementType.TYPE }) @interface A {}\n"; + String A_LOCAL = "@Target({ ElementType.LOCAL_VARIABLE }) @interface A {}\n"; + String A_ANNOTATION_TYPE = "@Target({ ElementType.ANNOTATION_TYPE }) @interface A {}\n"; + String A_TYPE_PARAMETER = "@Target({ ElementType.TYPE_PARAMETER }) @interface A {}\n"; + String A_MODULE = "@Target({ ElementType.MODULE }) @interface A {}\n"; + String A_MORE = "@Target({ ElementType.RECORD_COMPONENT, ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER, " + + "ElementType.TYPE_USE, ElementType.CONSTRUCTOR, " + + "ElementType.PACKAGE, ElementType.TYPE, ElementType.LOCAL_VARIABLE }) @interface A {}\n"; + + for (String s : List.of(A_COMPONENT, A_FIELD, A_METHOD, A_PARAM, A_TYPE_USE, A_MULTI, A_NONE, A_MORE)) + assertOK(imports + s + "record R(@A int x) { }"); + + // @@@ Should also fail for TYPE_PARAMETER + for (String s : List.of(A_PACKAGE, A_CTOR, A_TYPE, A_LOCAL, A_ANNOTATION_TYPE, /* A_TYPE_PARAMETER, */ A_MODULE)) + assertFail("compiler.err.annotation.type.not.applicable", imports + s + "record R(@A int x) { }"); + + // TODO: OK to redeclare with or without same annos } public void testIllegalSerializationMembers() { - // readResolve, writeReplace, readObject, writeObject, readObjectNoData, serialPersistentFields + // @@@ Should fail +// String template = "record R(int x) { # }"; +// for (String s : List.of("private static final java.io.ObjectStreamField[] serialPersistentFields = {};", +// "private void writeObject(java.io.ObjectOutputStream stream) { }", +// "private Object writeReplace() { }", +// "private Object readResolve() { }", +// "private void readObject(java.io.ObjectInputStream stream) { }", +// "private void readObjectNoData() { }")) +// assertFail("", template, s); } public void testLocalRecords() {