changeset 57051:033fe61e28ad amber-demo-II

Automatic merge with records-and-sealed
author mcimadamore
date Tue, 27 Aug 2019 20:30:53 +0000
parents 40988e0ec912 7cf9d1e04cb1
children c84f723610a4
files test/langtools/tools/javac/records/RecordMemberTests.java test/langtools/tools/javac/records/nested_records_must_be_static_and_final/NestedRecordsMustBeStaticAndFinalTest.java
diffstat 4 files changed, 187 insertions(+), 189 deletions(-) [+]
line wrap: on
line diff
--- a/test/langtools/tools/javac/records/RecordCompilationTests.java	Tue Aug 27 20:25:43 2019 +0000
+++ b/test/langtools/tools/javac/records/RecordCompilationTests.java	Tue Aug 27 20:30:53 2019 +0000
@@ -63,6 +63,8 @@
     private static String[] PREVIEW_OPTIONS = {"--enable-preview", "-source",
             Integer.toString(Runtime.version().feature())};
 
+    // -- test framework code --
+
     @AfterMethod
     public void dumpTemplateIfError(ITestResult result) {
         // Make sure offending template ends up in log file on failure
@@ -123,6 +125,7 @@
             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);
+        assertFail("compiler.err.varargs.must.be.last", "record R(int... x, int... y) {}");
     }
 
     public void testGoodDeclarations() {
@@ -131,6 +134,8 @@
         assertOK("record R() implements java.io.Serializable, Runnable { public void run() { } }");
         assertOK("record R(int x) { }");
         assertOK("record R(int x, int y) { }");
+        assertOK("record R(int... xs) { }");
+        assertOK("record R(String... ss) { }");
         assertOK("@Deprecated record R(int x, int y) { }");
         assertOK("record R(@Deprecated int x, int y) { }");
         assertOK("record R<T>(T x, T y) { }");
@@ -145,17 +150,6 @@
                 + "    public String toString() { return null; }\n"
                 + "}";
         assertOK(template);
-
-        // now with varargs
-        template = "public record R(int i, int... j) {\n"
-                + "    public R(int i, int... j) { this.i = i; this.j = j; }\n"
-                + "    public int i() { return i; }\n"
-                + "    public int[] j() { return j; }\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() {
@@ -283,6 +277,11 @@
         assertFail("compiler.err.var.might.not.have.been.initialized", "record R(int x, int y) { # }",
                    "public R(int x, int y) { this.x = x; }");
 
+        // Not OK to rearrange or change names
+        for (String s : List.of("public R(int y, int x) { this.x = x; this.y = y; }",
+                                "public R(int _x, int _y) { this.x = _x; this.y = _y; }"))
+            assertFail("compiler.err.canonical.with.name.mismatch", "record R(int x, int y) { # }", s);
+
         // canonical ctor must be public
         for (String s : List.of("", "protected", "private"))
             assertFail("compiler.err.canonical.constructor.must.be.public", "record R(int x, int y) { # }",
--- a/test/langtools/tools/javac/records/RecordMemberTests.java	Tue Aug 27 20:25:43 2019 +0000
+++ b/test/langtools/tools/javac/records/RecordMemberTests.java	Tue Aug 27 20:30:53 2019 +0000
@@ -29,6 +29,7 @@
 import java.lang.reflect.Modifier;
 import java.lang.reflect.Parameter;
 import java.util.List;
+import java.util.function.Supplier;
 
 import org.testng.annotations.*;
 import static org.testng.Assert.*;
@@ -64,14 +65,11 @@
         public R5 { this.i = this.j = 0; }
     }
 
-    record R6(int... i) {}
-
     R1 r1 = new R1(1, 2);
     R2 r2 = new R2(1, 2);
     R3 r3 = new R3(1, 2);
     R4 r4 = new R4(1, 2);
     R5 r5 = new R5(1, 2);
-    R6 r6 = new R6(1, 2);
 
     public void testConstruction() {
         for (int i : new int[] { r1.i, r2.i, r3.i, r4.i,
@@ -84,12 +82,10 @@
 
         assertEquals(r5.i, 0);
         assertEquals(r5.j, 0);
-        assertEquals(r6.i()[0], 1);
-        assertEquals(r6.i()[1], 2);
     }
 
     public void testConstructorParameterNames() throws ReflectiveOperationException {
-        for (Class cl : List.of(R1.class, R2.class, R3.class, R4.class, R5.class)) {
+        for (Class cl : List.of(R1.class, R2.class, R3.class, R4.class)) {
             Constructor c = cl.getConstructor(int.class, int.class);
             assertNotNull(c);
             Parameter[] parameters = c.getParameters();
@@ -97,13 +93,6 @@
             assertEquals(parameters[0].getName(), "i");
             assertEquals(parameters[1].getName(), "j");
         }
-
-        // R6, varargs
-        Constructor c = R6.class.getConstructor(int[].class);
-        assertNotNull(c);
-        Parameter[] parameters = c.getParameters();
-        assertEquals(parameters.length, 1);
-        assertEquals(parameters[0].getName(), "i");
     }
 
     public void testSuperclass() {
@@ -123,13 +112,6 @@
             assertTrue((iField.getModifiers() & Modifier.FINAL) != 0);
         }
 
-        // R6, varargs
-        Field iField = R6.class.getDeclaredField("i");
-        assertEquals(iField.getType(), int[].class);
-        assertEquals((iField.getModifiers() & Modifier.STATIC), 0);
-        assertTrue((iField.getModifiers() & Modifier.PRIVATE) != 0);
-        assertTrue((iField.getModifiers() & Modifier.FINAL) != 0);
-
         // methods are present, of the right descriptor, and public/instance/concrete
         for (String s : List.of("i", "j")) {
             Method iMethod = R1.class.getDeclaredMethod(s);
@@ -138,27 +120,16 @@
             assertEquals((iMethod.getModifiers() & (Modifier.PRIVATE | Modifier.PROTECTED | Modifier.STATIC | Modifier.ABSTRACT)), 0);
         }
 
-        // R6, varargs
-        Method iMethod = R6.class.getDeclaredMethod("i");
-        assertEquals(iMethod.getReturnType(), int[].class);
-        assertEquals(iMethod.getParameterCount(), 0);
-        assertEquals((iMethod.getModifiers() & (Modifier.PRIVATE | Modifier.PROTECTED | Modifier.STATIC | Modifier.ABSTRACT)), 0);
-
         Constructor c = R1.class.getConstructor(int.class, int.class);
         R1 r1 = (R1) c.newInstance(1, 2);
         assertEquals(r1.i(), 1);
         assertEquals(r1.j(), 2);
-
-        c = R6.class.getConstructor(int[].class);
-        R6 r6 = (R6) c.newInstance(new int[]{1, 2});
-        assertEquals(r6.i()[0], 1);
-        assertEquals(r6.i()[1], 2);
     }
 
     record OrdinaryMembers(int x) {
         public static String ss;
-        public static String ssf() { return ss; }
-        public String sf() { return "instance"; }
+        public static String ssf () { return ss; }
+        public String sf () { return "instance"; }
     }
 
     public void testOrdinaryMembers() {
@@ -167,4 +138,82 @@
         OrdinaryMembers o = new OrdinaryMembers(3);
         assertEquals(o.sf(), "instance");
     }
+
+    // @@@ Fails with error message about invalid static members
+//    class InstanceNestedRecordHelper {
+//        record R(int x) { }
+//    }
+//
+//    public void testNestedRecordsStatic() {
+//        assertTrue((InstanceNestedRecordHelper.R.class.getModifiers() & Modifier.STATIC) != 0);
+//    }
+
+    class LocalRecordHelper {
+        Class<?> m(int x) {
+            record R (int x) { }
+            assertEquals(new R(x).x(), x);
+            return R.class;
+        }
+    }
+
+    public void testLocalRecordsStatic() {
+        Class<?> c = new LocalRecordHelper().m(3);
+        assertTrue(c.isRecord());
+        assertTrue((c.getModifiers() & Modifier.STATIC) != 0);
+        assertTrue((c.getModifiers() & Modifier.FINAL) != 0);
+    }
+
+    static class NestedRecordHelper {
+        record R1(int x) { }
+
+        static class Nested {
+            record R2(int x) { }
+        }
+
+//        Runnable r = new Runnable() {
+//            record R3(int x) { }
+//            public void run() { }
+//        };
+
+        Class<?> m() {
+            record R4(int x) { }
+            return R4.class;
+        }
+
+        Class<?> m2() {
+            Supplier<Class<?>> s = () -> {
+                record R5(int x) { }
+                return R5.class;
+            };
+            return s.get();
+        }
+
+        static Class<?> m3() {
+            record R6(int x) { }
+            return R6.class;
+        }
+
+        static Class<?> m4() {
+            Supplier<Class<?>> s = () -> {
+                record R7(int x) { }
+                return R7.class;
+            };
+            return s.get();
+        }
+    }
+
+    public void testNestedRecordsStatic() {
+        NestedRecordHelper n = new NestedRecordHelper();
+        for (Class<?> c : List.of(NestedRecordHelper.R1.class,
+                                  NestedRecordHelper.Nested.R2.class,
+                                  n.m(),
+                                  n.m2(),
+                                  NestedRecordHelper.m3(),
+                                  NestedRecordHelper.m4())) {
+            assertTrue(c.isRecord());
+            assertTrue((c.getModifiers() & Modifier.STATIC) != 0);
+            assertTrue((c.getModifiers() & Modifier.FINAL) != 0);
+        }
+    }
 }
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/langtools/tools/javac/records/VarargsRecordsTest.java	Tue Aug 27 20:30:53 2019 +0000
@@ -0,0 +1,95 @@
+/*
+ * 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.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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.
+ */
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.lang.reflect.Parameter;
+
+import org.testng.annotations.Test;
+import static org.testng.Assert.*;
+
+/**
+ * VarargsRecordsTest
+ *
+ * @test
+ * @run testng VarargsRecordsTest
+ */
+@Test
+public class VarargsRecordsTest {
+    record RI(int... xs) { }
+    record RII(int x, int... xs) { }
+
+    RI r1 = new RI();
+    RI r2 = new RI(1);
+    RI r3 = new RI(1, 2);
+    RII r4 = new RII(1);
+    RII r5 = new RII(1, 2);
+    RII r6 = new RII(1, 2, 3);
+
+    public void assertVarargsInstances() {
+        assertEquals(r1.xs.length, 0);
+        assertEquals(r2.xs.length, 1);
+        assertEquals(r3.xs.length, 2);
+        assertEquals(r4.xs.length, 0);
+        assertEquals(r5.xs.length, 1);
+        assertEquals(r6.xs.length, 2);
+
+        assertEquals(r2.xs[0], 1);
+        assertEquals(r3.xs[0], 1);
+        assertEquals(r3.xs[1], 2);
+
+        assertEquals(r5.xs[0], 2);
+        assertEquals(r6.xs[0], 2);
+        assertEquals(r6.xs[1], 3);
+    }
+
+    public void testMembers() throws ReflectiveOperationException {
+        Constructor c = RI.class.getConstructor(int[].class);
+        assertNotNull(c);
+        assertTrue(c.isVarArgs());
+        Parameter[] parameters = c.getParameters();
+        assertEquals(parameters.length, 1);
+        assertEquals(parameters[0].getName(), "xs");
+
+        RI ri = (RI) c.newInstance(new int[]{1, 2});
+        assertEquals(ri.xs()[0], 1);
+        assertEquals(ri.xs()[1], 2);
+
+        Field xsField = RI.class.getDeclaredField("xs");
+        assertEquals(xsField.getType(), int[].class);
+        assertEquals((xsField.getModifiers() & Modifier.STATIC), 0);
+        assertTrue((xsField.getModifiers() & Modifier.PRIVATE) != 0);
+        assertTrue((xsField.getModifiers() & Modifier.FINAL) != 0);
+        assertEquals(((int[]) xsField.get(ri))[0], 1);
+
+        Method xsMethod = RI.class.getDeclaredMethod("xs");
+        assertEquals(xsMethod.getReturnType(), int[].class);
+        assertEquals(xsMethod.getParameterCount(), 0);
+        assertEquals((xsMethod.getModifiers() & (Modifier.PRIVATE | Modifier.PROTECTED | Modifier.STATIC | Modifier.ABSTRACT)), 0);
+        assertEquals(((int[]) xsMethod.invoke(ri))[0], 1);
+    }
+}
--- a/test/langtools/tools/javac/records/nested_records_must_be_static_and_final/NestedRecordsMustBeStaticAndFinalTest.java	Tue Aug 27 20:25:43 2019 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,145 +0,0 @@
-/*
- * Copyright (c) 2017, 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
- * @summary check that records are always static
- * @library /tools/javac/lib
- * @modules jdk.compiler/com.sun.source.util
- *          jdk.compiler/com.sun.tools.javac.api
- *          jdk.compiler/com.sun.tools.javac.code
- *          jdk.compiler/com.sun.tools.javac.file
- *          jdk.compiler/com.sun.tools.javac.tree
- *          jdk.compiler/com.sun.tools.javac.util
- * @build DPrinter
- * @run main NestedRecordsMustBeStaticAndFinalTest
- */
-
-import java.io.*;
-import java.net.URI;
-import java.util.Arrays;
-
-import javax.tools.JavaCompiler;
-import javax.tools.JavaFileObject;
-import javax.tools.SimpleJavaFileObject;
-import javax.tools.ToolProvider;
-
-import com.sun.source.tree.CompilationUnitTree;
-import com.sun.source.util.JavacTask;
-import com.sun.source.util.Trees;
-import com.sun.tools.javac.api.JavacTrees;
-import com.sun.tools.javac.file.JavacFileManager;
-import com.sun.tools.javac.tree.JCTree;
-import com.sun.tools.javac.util.Assert;
-import com.sun.tools.javac.util.Context;
-
-public class NestedRecordsMustBeStaticAndFinalTest {
-    public static void main(String... args) throws Exception {
-        new NestedRecordsMustBeStaticAndFinalTest().run();
-    }
-
-    void run() throws Exception {
-        Context context = new Context();
-        JavacFileManager.preRegister(context);
-        Trees trees = JavacTrees.instance(context);
-        strOut = new StringWriter();
-        PrintWriter pw = new PrintWriter(strOut);
-        dprinter = new DPrinter(pw, trees);
-        tool = ToolProvider.getSystemJavaCompiler();
-        test("Foo.java", source1);
-        test("Foo2.java", source11);
-        test("Foo3.java", source111);
-        test("Bar.java", source2);
-        test("Bar2.java", source3);
-        test("Baz.java", source4);
-    }
-
-    StringWriter strOut;
-    DPrinter dprinter;
-    JavaCompiler tool;
-
-    void test(String fileName, String source) throws Exception {
-        JavacTask ct = (JavacTask)tool.getTask(null, null, null, null, null, Arrays.asList(new JavaSource(fileName, source)));
-        Iterable<? extends CompilationUnitTree> elements = ct.parse();
-        Assert.check(elements.iterator().hasNext());
-        dprinter.treeTypes(true).printTree("", (JCTree)elements.iterator().next());
-        String output = strOut.toString();
-        Assert.check(output.contains("flags: [static, final, record]"), "nested records should be static and final");
-    }
-
-    static final String source1 =
-            "class Foo {\n" +
-            "    record R (int x);\n" +
-            "}";
-
-    static final String source11 =
-            "class Foo2 {\n" +
-            "    class Inner {\n" +
-            "        record R (int x);\n" +
-            "    }\n" +
-            "}";
-    static final String source111 =
-            "class Foo3 {\n" +
-            "    Runnable r = new Runnable() {\n" +
-            "        record R(int i);\n" +
-            "        public void run() {}\n" +
-            "    };" +
-            "}";
-    static final String source2 =
-            "class Bar {\n" +
-            "    void m() {\n" +
-            "        record R (int x);\n" +
-            "    }\n" +
-            "}";
-
-    static final String source3 =
-            "class Bar2 {\n" +
-            "    void m() {\n" +
-            "        static record R (int x);\n" +
-            "    }\n" +
-            "}";
-
-    static final String source4 =
-            "class Baz {\n" +
-            "    void m() {\n" +
-            "        Runnable r = () -> {" +
-            "            record R (int x);\n" +
-            "        };\n" +
-            "    }\n" +
-            "}";
-
-    static class JavaSource extends SimpleJavaFileObject {
-
-        String source;
-
-        public JavaSource(String fileName, String source) {
-            super(URI.create("myfo:/" + fileName), JavaFileObject.Kind.SOURCE);
-            this.source = source;
-        }
-
-        @Override
-        public CharSequence getCharContent(boolean ignoreEncodingErrors) {
-            return source;
-        }
-    }
-}