changeset 56902:88397728dd30 records-and-sealed

generate the MethodParameters attribute for the canonical constructor
author vromero
date Wed, 26 Jun 2019 15:52:31 -0400
parents f44032b6dbad
children 268daac2afd7 8d093ef9814e
files src/jdk.compiler/share/classes/com/sun/tools/javac/comp/TypeEnter.java src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassWriter.java test/langtools/tools/javac/records/mandated_members/canonical_constructor/CanonicalConstructorTest.java test/langtools/tools/javac/records/mandated_members/canonical_constructor/MethodParametersForCanonicalConstructorTest.java
diffstat 4 files changed, 99 insertions(+), 2 deletions(-) [+]
line wrap: on
line diff
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/TypeEnter.java	Wed Jun 26 11:42:07 2019 -0400
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/TypeEnter.java	Wed Jun 26 15:52:31 2019 -0400
@@ -1218,6 +1218,8 @@
                     if (!initParamNames.equals(recordComponentNames)) {
                         log.error(canonicalDecl, Errors.CanonicalWithNameMismatch);
                     }
+                    // let's use the RECORD flag to mark it as the canonical constructor
+                    canonicalInit.flags_field |= Flags.RECORD;
                 }
             }
 
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassWriter.java	Wed Jun 26 11:42:07 2019 -0400
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassWriter.java	Wed Jun 26 15:52:31 2019 -0400
@@ -1005,7 +1005,7 @@
             endAttr(alenIdx);
             acount++;
         }
-        if (options.isSet(PARAMETERS) && target.hasMethodParameters()) {
+        if (target.hasMethodParameters() && (options.isSet(PARAMETERS) || m.isConstructor() && m.isRecord())) {
             if (!m.isLambdaMethod()) // Per JDK-8138729, do not emit parameters table for lambda bodies.
                 acount += writeMethodParametersAttr(m);
         }
--- a/test/langtools/tools/javac/records/mandated_members/canonical_constructor/CanonicalConstructorTest.java	Wed Jun 26 11:42:07 2019 -0400
+++ b/test/langtools/tools/javac/records/mandated_members/canonical_constructor/CanonicalConstructorTest.java	Wed Jun 26 15:52:31 2019 -0400
@@ -54,6 +54,9 @@
         R3 r3 = new R3(1, 2);
         R4 r4 = new R4(1, 2);
 
-        Assert.check(r1.i == r2.i && r2.i == r3.i && r3.i == r4.i && r4.i == 1 && r1.j == r2.j && r2.j == r3.j && r3.j == r4.j && r4.j == 2, "unexpected value of record component");
+        Assert.check(r1.i == r2.i && r2.i == r3.i &&
+                r3.i == r4.i && r4.i == 1 &&
+                r1.j == r2.j && r2.j == r3.j &&
+                r3.j == r4.j && r4.j == 2, "unexpected value of record component");
     }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/langtools/tools/javac/records/mandated_members/canonical_constructor/MethodParametersForCanonicalConstructorTest.java	Wed Jun 26 15:52:31 2019 -0400
@@ -0,0 +1,92 @@
+/*
+ * 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
+ * @summary check that members of abtract datum has protected access
+ * @modules jdk.jdeps/com.sun.tools.classfile
+ *          jdk.compiler/com.sun.tools.javac.util
+ * @compile MethodParametersForCanonicalConstructorTest.java
+ * @run main MethodParametersForCanonicalConstructorTest
+ */
+
+import java.io.*;
+
+import com.sun.tools.classfile.*;
+
+public class MethodParametersForCanonicalConstructorTest {
+
+    record R1(int i, int j);
+
+    record R2(int i, int j) {
+        public R2 {}
+    }
+
+    record R3(int i, int j) {
+        public R3(int i, int j) {}
+    }
+
+    public static void main(String args[]) throws Throwable {
+        new MethodParametersForCanonicalConstructorTest().run();
+    }
+
+    void run() throws Throwable {
+        checkCanonical("R1", "i", "j");
+        checkCanonical("R2", "i", "j");
+        checkCanonical("R3", "i", "j");
+    }
+
+    void checkCanonical(String className, String... expectedParamNames) throws Throwable {
+        if (expectedParamNames == null) {
+            return;
+        }
+        File testClasses = new File(System.getProperty("test.classes"));
+        File file = new File(testClasses,
+                MethodParametersForCanonicalConstructorTest.class.getName() + "$" + className +".class");
+        ClassFile classFile = ClassFile.read(file);
+        boolean found = false;
+        for (Method m : classFile.methods) {
+            if (m.getName(classFile.constant_pool).equals("<init>")) {
+                for (Attribute attribute : m.attributes) {
+                    if (attribute instanceof MethodParameters_attribute) {
+                        found = true;
+                        MethodParameters_attribute mpa = (MethodParameters_attribute)attribute;
+                        if (mpa.method_parameter_table_length != expectedParamNames.length) {
+                            throw new AssertionError("unexpected method parameter table lenght");
+                        }
+                        int i = 0;
+                        for (MethodParameters_attribute.Entry entry : mpa.method_parameter_table) {
+                            if (!classFile.constant_pool.getUTF8Value(entry.name_index).equals(expectedParamNames[i])) {
+                                throw new AssertionError("unexpected name at position " + i);
+                            }
+                            i++;
+                        }
+                    }
+                }
+            }
+        }
+        if (!found) {
+            throw new AssertionError("attribute MethodParameters not found");
+        }
+    }
+}