test/tools/javac/lambda/lambdaNaming/TestNonSerializableLambdaNameStability.java

Wed, 16 Sep 2015 10:56:23 +0200

author
jlahoda
date
Wed, 16 Sep 2015 10:56:23 +0200
changeset 3111
51997141b15c
parent 2701
6906fc8bc514
permissions
-rw-r--r--

8067422: Lambda method names are unnecessarily unstable
Summary: Lambda method numbers are now assigned per class for non-serializable lambdas.
Reviewed-by: mcimadamore, rfield, vromero

jlahoda@2701 1 /*
jlahoda@2701 2 * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
jlahoda@2701 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
jlahoda@2701 4 *
jlahoda@2701 5 * This code is free software; you can redistribute it and/or modify it
jlahoda@2701 6 * under the terms of the GNU General Public License version 2 only, as
jlahoda@2701 7 * published by the Free Software Foundation.
jlahoda@2701 8 *
jlahoda@2701 9 * This code is distributed in the hope that it will be useful, but WITHOUT
jlahoda@2701 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
jlahoda@2701 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
jlahoda@2701 12 * version 2 for more details (a copy is included in the LICENSE file that
jlahoda@2701 13 * accompanied this code).
jlahoda@2701 14 *
jlahoda@2701 15 * You should have received a copy of the GNU General Public License version
jlahoda@2701 16 * 2 along with this work; if not, write to the Free Software Foundation,
jlahoda@2701 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
jlahoda@2701 18 *
jlahoda@2701 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
jlahoda@2701 20 * or visit www.oracle.com if you need additional information or have any
jlahoda@2701 21 * questions.
jlahoda@2701 22 */
jlahoda@2701 23
jlahoda@2701 24 /*
jlahoda@2701 25 * @test
jlahoda@2701 26 * @bug 8067422
jlahoda@2701 27 * @summary Check that the lambda names are not unnecessarily unstable
jlahoda@2701 28 * @run main TestNonSerializableLambdaNameStability
jlahoda@2701 29 */
jlahoda@2701 30
jlahoda@2701 31 import com.sun.tools.classfile.ClassFile;
jlahoda@2701 32 import com.sun.tools.classfile.Method;
jlahoda@2701 33
jlahoda@2701 34 import java.io.ByteArrayInputStream;
jlahoda@2701 35 import java.io.ByteArrayOutputStream;
jlahoda@2701 36 import java.io.IOException;
jlahoda@2701 37 import java.io.InputStream;
jlahoda@2701 38 import java.io.OutputStream;
jlahoda@2701 39 import java.net.URI;
jlahoda@2701 40 import java.net.URISyntaxException;
jlahoda@2701 41 import java.util.ArrayList;
jlahoda@2701 42 import java.util.HashMap;
jlahoda@2701 43 import java.util.List;
jlahoda@2701 44 import java.util.Map;
jlahoda@2701 45
jlahoda@2701 46 import javax.tools.FileObject;
jlahoda@2701 47 import javax.tools.ForwardingJavaFileManager;
jlahoda@2701 48 import javax.tools.JavaCompiler;
jlahoda@2701 49 import javax.tools.JavaFileManager;
jlahoda@2701 50 import javax.tools.JavaFileObject;
jlahoda@2701 51 import javax.tools.JavaFileObject.Kind;
jlahoda@2701 52 import javax.tools.SimpleJavaFileObject;
jlahoda@2701 53 import javax.tools.ToolProvider;
jlahoda@2701 54
jlahoda@2701 55 public class TestNonSerializableLambdaNameStability {
jlahoda@2701 56
jlahoda@2701 57 public static void main(String... args) throws Exception {
jlahoda@2701 58 new TestNonSerializableLambdaNameStability().run();
jlahoda@2701 59 }
jlahoda@2701 60
jlahoda@2701 61 String lambdaSource = "public class L%d {\n" +
jlahoda@2701 62 " public static class A {\n" +
jlahoda@2701 63 " private Runnable r = () -> { };\n" +
jlahoda@2701 64 " }\n" +
jlahoda@2701 65 " public static class B {\n" +
jlahoda@2701 66 " private Runnable r = () -> { };\n" +
jlahoda@2701 67 " }\n" +
jlahoda@2701 68 " private Runnable r = () -> { };\n" +
jlahoda@2701 69 "}\n";
jlahoda@2701 70
jlahoda@2701 71 String expectedLambdaMethodName = "lambda$new$0";
jlahoda@2701 72
jlahoda@2701 73 void run() throws Exception {
jlahoda@2701 74 List<JavaFileObject> sources = new ArrayList<>();
jlahoda@2701 75
jlahoda@2701 76 for (int i = 0; i < 3; i++) {
jlahoda@2701 77 sources.add(new SourceJavaFileObject("L" + i, String.format(lambdaSource, i)));
jlahoda@2701 78 }
jlahoda@2701 79
jlahoda@2701 80 JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
jlahoda@2701 81
jlahoda@2701 82 try (MemoryFileManager fm = new MemoryFileManager(compiler.getStandardFileManager(null, null, null))) {
jlahoda@2701 83 if (!compiler.getTask(null, fm, null, null, null, sources).call()) {
jlahoda@2701 84 throw new AssertionError("Compilation failed!");
jlahoda@2701 85 }
jlahoda@2701 86
jlahoda@2701 87 for (String file : fm.name2Content.keySet()) {
jlahoda@2701 88 byte[] fileBytes = fm.name2Content.get(file);
jlahoda@2701 89 try (InputStream in = new ByteArrayInputStream(fileBytes)) {
jlahoda@2701 90 boolean foundLambdaMethod = false;
jlahoda@2701 91 ClassFile cf = ClassFile.read(in);
jlahoda@2701 92 StringBuilder seenMethods = new StringBuilder();
jlahoda@2701 93 String sep = "";
jlahoda@2701 94 for (Method m : cf.methods) {
jlahoda@2701 95 String methodName = m.getName(cf.constant_pool);
jlahoda@2701 96 if (expectedLambdaMethodName.equals(methodName)) {
jlahoda@2701 97 foundLambdaMethod = true;
jlahoda@2701 98 break;
jlahoda@2701 99 }
jlahoda@2701 100 seenMethods.append(sep);
jlahoda@2701 101 seenMethods.append(methodName);
jlahoda@2701 102 sep = ", ";
jlahoda@2701 103 }
jlahoda@2701 104
jlahoda@2701 105 if (!foundLambdaMethod) {
jlahoda@2701 106 throw new AbstractMethodError("Did not find the lambda method, " +
jlahoda@2701 107 "found methods: " + seenMethods.toString());
jlahoda@2701 108 }
jlahoda@2701 109 }
jlahoda@2701 110 }
jlahoda@2701 111 }
jlahoda@2701 112 }
jlahoda@2701 113
jlahoda@2701 114 class MemoryFileManager extends ForwardingJavaFileManager<JavaFileManager> {
jlahoda@2701 115
jlahoda@2701 116 final Map<String, byte[]> name2Content = new HashMap<>();
jlahoda@2701 117
jlahoda@2701 118 public MemoryFileManager(JavaFileManager fileManager) {
jlahoda@2701 119 super(fileManager);
jlahoda@2701 120 }
jlahoda@2701 121
jlahoda@2701 122 @Override
jlahoda@2701 123 public JavaFileObject getJavaFileForOutput(Location location, String className, Kind kind, FileObject sibling) throws IOException {
jlahoda@2701 124 try {
jlahoda@2701 125 return new SimpleJavaFileObject(new URI("mem://" + className.replace('.', '/') + kind.extension), kind) {
jlahoda@2701 126 @Override public OutputStream openOutputStream() throws IOException {
jlahoda@2701 127 return new ByteArrayOutputStream() {
jlahoda@2701 128 @Override public void close() throws IOException {
jlahoda@2701 129 super.close();
jlahoda@2701 130 name2Content.put(className, toByteArray());
jlahoda@2701 131 }
jlahoda@2701 132 };
jlahoda@2701 133 }
jlahoda@2701 134 };
jlahoda@2701 135 } catch (URISyntaxException ex) {
jlahoda@2701 136 throw new AssertionError(ex);
jlahoda@2701 137 }
jlahoda@2701 138 }
jlahoda@2701 139
jlahoda@2701 140 }
jlahoda@2701 141
jlahoda@2701 142 class SourceJavaFileObject extends SimpleJavaFileObject {
jlahoda@2701 143
jlahoda@2701 144 private final String code;
jlahoda@2701 145
jlahoda@2701 146 public SourceJavaFileObject(String name, String code) throws URISyntaxException {
jlahoda@2701 147 super(new URI("mem:///" + name + ".java"), Kind.SOURCE);
jlahoda@2701 148 this.code = code;
jlahoda@2701 149 }
jlahoda@2701 150
jlahoda@2701 151 @Override
jlahoda@2701 152 public CharSequence getCharContent(boolean ignoreEncodingErrors) throws IOException {
jlahoda@2701 153 return code;
jlahoda@2701 154 }
jlahoda@2701 155
jlahoda@2701 156 }
jlahoda@2701 157 }

mercurial