8009742: Bad lambda name for lambda in a static initializer or ctor
authorrfield
Mon, 11 Mar 2013 10:02:55 -0700
changeset 16337 181ac468ab24
parent 16336 cf436a619e34
child 16338 7d42d41478e6
8009742: Bad lambda name for lambda in a static initializer or ctor Reviewed-by: mcimadamore
langtools/src/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java
langtools/test/tools/javac/lambda/SerializedLambdaInInit.java
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java	Mon Mar 11 15:35:13 2013 +0000
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java	Mon Mar 11 10:02:55 2013 -0700
@@ -1296,7 +1296,12 @@
         private Name serializedLambdaName(Symbol owner) {
             StringBuilder buf = new StringBuilder();
             buf.append(names.lambda);
-            buf.append(owner.name);
+            String methodName = owner.name.toString();
+            if (methodName.equals("<clinit>"))
+                methodName = "static";
+            else if (methodName.equals("<init>"))
+                methodName = "new";
+            buf.append(methodName);
             buf.append('$');
             int methTypeHash = methodSig(owner.type).hashCode();
             buf.append(Integer.toHexString(methTypeHash));
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/SerializedLambdaInInit.java	Mon Mar 11 10:02:55 2013 -0700
@@ -0,0 +1,118 @@
+/*
+ * Copyright (c) 2013, 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 8009742
+@summary Bad method name: Serialized lambda in a constructor or class init
+*/
+
+import java.io.*;
+import java.lang.reflect.Method;
+
+public class SerializedLambdaInInit {
+    static int assertionCount = 0;
+
+    static void assertTrue(boolean cond) {
+        assertionCount++;
+        if (!cond)
+            throw new AssertionError();
+    }
+
+    static LSI cvisi = z -> "[" + z + "]";
+    static LSI cisi;
+
+    static {
+        cisi = z -> z + z;
+    }
+
+    LSI ivsi = z -> "blah";
+    LSI iisi;
+
+    SerializedLambdaInInit() {
+        iisi = z -> "*" + z;
+    }
+
+    public static void main(String[] args) throws Exception {
+        try {
+            // Write lambdas out
+            ByteArrayOutputStream baos = new ByteArrayOutputStream();
+            ObjectOutput out = new ObjectOutputStream(baos);
+            SerializedLambdaInInit slii = new SerializedLambdaInInit();
+
+            write(out, cvisi );
+            write(out, cisi );
+            write(out, slii.ivsi );
+            write(out, slii.iisi );
+            out.flush();
+            out.close();
+
+            // Read them back
+            ByteArrayInputStream bais =
+                new ByteArrayInputStream(baos.toByteArray());
+            ObjectInputStream in = new ObjectInputStream(bais);
+            readAssert(in, "[X]");
+            readAssert(in, "XX");
+            readAssert(in, "blah");
+            readAssert(in, "*X");
+            in.close();
+
+            // Reflectively test for valid method names
+            for (Method meth : slii.getClass().getDeclaredMethods()) {
+                checkIdentifier(meth.getName());
+            }
+        } catch (IOException e) {
+            e.printStackTrace();
+            throw e;
+        }
+        assertTrue(assertionCount == 4);
+    }
+
+    static void write(ObjectOutput out, LSI lamb) throws IOException {
+        out.writeObject(lamb);
+    }
+
+    static void readAssert(ObjectInputStream in, String expected)  throws IOException, ClassNotFoundException {
+        LSI ls = (LSI) in.readObject();
+        String result = ls.convert("X");
+        System.out.printf("Result: %s\n", result);
+        assertTrue(result.equals(expected));
+    }
+
+    public static void checkIdentifier(String str) throws Exception {
+        // null and zero length identifers will throw their own exceptions
+        char[] chars = str.toCharArray();
+        if (!Character.isJavaIdentifierStart(chars[0])) {
+            throw new IllegalArgumentException(str + ": bad identifier start character: '" + chars[0] + "'");
+        }
+        for (char ch : chars) {
+            if (!Character.isJavaIdentifierPart(ch)) {
+                throw new IllegalArgumentException(str + ": bad identifier character: '" + ch + "'");
+            }
+        }
+    }
+}
+
+interface LSI extends Serializable {
+    String convert(String x);
+}